네트워킹 테스트용 데모 버전 실행을 위해

다음과 같은 API 서버들을 kube 위에 띄우려고 함

Kube 는 회원제 서비스를 위한 API 를 제공하며

Client 는 새로 회원가입을 하기 위해 Users API 를 호출함

Users API 는 토큰 생성을 위해 Auth API 를 호출함

회원가입이 마무리 된 이후, Client 는 Tasks API 를 사용하여 task 를 수행함.

Client 가 직접 부를 수 있는 API 는 Users API, Tasks API 두 개이며

UsersAPI 와 Auth API 는 하나의 Pod 내부 통신을 사용함

 

 

 


 

 

 

Users API 를 생성하는 kube yaml 파일을 생성해 봄

이름은 users-deployment.yaml


< users-deployment.yaml >

apiVersion: apps/v1
kind: Deployment
metadata:
  name: users-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: users
  template:
    metadata:
      labels:
        app: users
    spec:
      containers:
        - name: users
          image: my-user-image

 

kubectl apply -f=users-deployment.yaml 명령어로 kube 위에 pod 를 띄움

그리고 kubectl get pods, kubectl get deployments 로 pods , deployments 가 잘 떴는지 확인

 

 


 

 

users API 앱이 올라온 뒤

외부 세계(즉 Client) 에서 Users API 에 접근할 수 있도록

Service 를 추가로 설정해야 함

 

Service 를 설정하여 Service 의 두 가지 기능을 사용

- Service 는 항상 변경되지 않는 안정적이고 고정된 주소를 제공

  (Pod 자체가 default IP (ClusterIP) 를 갖고 있긴 하지만, Pod 가 재실행되면 바뀌게 됨)

- Service 는 외부 세계에서 pod 내부 앱으로의 접근을 허용하도록 구성 가능케 함

 

Service 추가를 위해 Service yaml 파일을 새로 생성

이름은 users-service.yaml


< users-service.yaml >

apiVersion: v1
kind: Service
metadata:
  name: users-service
spec:
  selector: 
    app: users  #위 deployment 에서 생성한 모든 users pods 에 service 를 할당함
  type: LoadBalancer  #외부 세계에서 접근 가능한 ip 를 제공하는 유일한 type
  ports:
    - protocol: TCP
      port: 8080  # 외부 세계에서 접근 가능한 포트
      targetPort: 8080  #내부 앱에서 받는 포트

 

 

아래 명령어를 사용하여 service yaml 를 kube 에 띄움

kubectl apply -f=users-service.yaml

그 후 kubectl get services 로 제대로 떴는지 확인

 

만약 Cloud Provider 를 이용하여 Service 를 띄웠다면

Cloud Provider 에서 제공하는 Service 의 IP를 얻을 수 있지만,

강의에서는 minikube 를 사용하기 때문에

아래 명령어를 사용하여 Service 의 IP 를 확인

 

minikube service users-service

 

위 스샷에서 보이는 것처럼 192.168.99.100:32023 이 Service 가 제공하는 IP 같은데...

yaml 에 넣어준 8080은 앞에 따로 표기되어있음

32023 은 무슨 의미지(????)

게다가 실제로 IP 에 접근할 때 8080 대신 32023 을 사용하고 있음

 

8080 은 왜 넣은거야 (???)

 

 

 


 

 

가장 위의 아키텍처에서 설명했듯이,

하나의 Pod 내에 두 가지 UserAPI Container, AuthAPI Container 두 개를 각각 띄우려고 함


< users-deployment.yaml >

apiVersion: apps/v1
kind: Deployment
metadata:
  name: users-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: users
  template:
    metadata:
      labels:
        app: users
    spec:
      containers:
        - name: users
          image: my-user-image
          env:
            - name: AUTH_ADDRESS
              value: localhost
        - name: auth
          image: my-auth-image


 

 

위 yaml 로 띄운, 하나의 Pod 내 두 개의 Container 가 서로 통신하기 위해서는?

pod 내에 서로 다른 Container 는 'localhost' 라는 이름의 주소를 통해 서로 통신 가능함

my-user-image 이미지를 사용하는 users Container 에 

AUTH_ADDRESS 라는 환경변수를 설정하고 값을 localhost 로 지정함

users Container 내부에서는 AUTH_ADDRESS 환경변수(=localhost) 를 다음과 같이 이용함

 

결과적으로 localhost/token 으로 요청을 보내게 되는데

localhost/token 은 두번째 Container 인 auth Container 가 받음

즉, user Container 에서 localhost 라는 이름의 주소를 이용하여 auth Container 에 접근함(서로 통신함)

 

위와 같이 pod 내에 두 개의 Container 를 설정하고

kubectl apply -f=users-deployment.yaml 명령어로 kube 위에 pod 를 띄우고

kubectl get pods 로 확인해보면, READY 에 2/2 라고 뜨게 됨 (Container 개수)

 

 


 

 

조금 더 발전시켜 볼 테스트용 데모 버전은 다음과 같음

각 API 는 서로 다른 Pod 에 존재하고, 각 Pod 는 각 Service 를 갖고 있음

이 때 Users API 와 Tasks API 를 담는 Pod 두 개에 붙은 Service 는 Client 가 접근 가능하게 설정되어야하고

Auth API 를 담는 Pod 에 붙은 Service 는 Client 가 접근 불가능하게 설정되어야 함

하지만 Users API 와 Tasks API 는 Auth API 에 접근 가능해야 함 

 

위 데모 환경 구축을 위해 아래와 같은 yaml 파일들을 작성

auth deployment yaml 을 생성하고,

(auth pod 재시작시 IP 가 계속 바뀌는 것을 방지하기 위해) auth Service yaml 을 생성

 


< auth-deployment.yaml >

apiVersion: apps/v1
kind: Deployment
metadata:
  name: auth-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: auth
  template:
    metadata:
      labels:
        app: auth
    spec:
      containers:
        - name: auth
          image: my-auth-image

< auth-service.yaml >

apiVersion: v1
kind: Service
metadata:
  name: auth-service
spec:
  selector: 
    app: auth
  type: ClusterIP  # pod 주소 고정 및 Load Balancer 역할을 해주지만 외부 세계로 노출은 막아주는 타입. 오직 Cluster 내부 세계로부터만 auth pod 에 접근 가능하게 됨
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

 

위와 같이 ClusterIP 타입을 사용하는 auth service 를 만들고

kubectl apply 명령 진행하고 kubectl get services 로 확인하면

ClusterIP 타입 Service 가 제공하는 (Cluster 내부에서만 사용 가능한) IP 를 확인 가능

 

 

그리고 아래와 같이 users deployment 에서 auth Service 의 IP 를 사용할 수 있도록 업데이트


< users-deployment.yaml >

apiVersion: apps/v1
kind: Deployment
metadata:
  name: users-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: users
  template:
    metadata:
      labels:
        app: users
    spec:
      containers:
        - name: users
          image: my-user-image
          env:
            - name: AUTH_ADDRESS
              value: "10.99.104.252"


< users-service.yaml >

apiVersion: v1
kind: Service
metadata:
  name: users-service
spec:
  selector: 
    app: users
  type: LoadBalancer
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080

 

 

위와 같이 kubectl get services 로 일일이 IP 를 확인하고

IP 를 직접 하드코딩하는 방법은 가능하지만 불편한 방법임

더 좋은 방법은, Kube 에서 자동으로 만들어주는 Service IP 를 의미하느 환경 변수를 사용하는 것임

 

Kube 는 service 를 실행하면, 실행된 Service IP 를 의미하는 환경 변수를 생성함

"[Service_이름]_[SERVICE_HOST]" (모두 대문자이며 - 는 _ 로 변환됨)

예를 들어 위에 auth Service yaml 의 경우 이름이 "auth-service" 이기 때문에

Kube 에 의해 자동으로 만들어지는 IP 환경변수 이름은 AUTH_SERVICE_SERVICE_HOST

(물론 user service yaml 의 경우, USERS_SERVICE_SERVICE_HOST 가 됨)

이를 users Container 내부에서 다음과 같이 사용할 것임

 

(위와 같이 변경하면, users-deployment.yaml 내부에서 AUTH_ADDRESS 를 굳이 주지 않아도 됨)

 

kube 가 자동 생성하는 환경변수를 사용하는 것 외에,

(자동으로 생성되는) Service IP 의 도메인 주소를 사용할 수 있음

(kube 내에서 실행되는 Core DNS 에 의해) Service IP 의 도메인 주소를 Service name.namespace 로 설정함

[서비스명].[namespace]

즉, 아래와 같이 변경이 가능하다는 말이 됨

 


< users-deployment.yaml 변경 전 >

.....
      containers:
        - name: users
          image: my-user-image
          env:
            - name: AUTH_ADDRESS
              value: "10.99.104.252"


< users-deployment.yaml 변경 후 >

.....
      containers:
        - name: users
          image: my-user-image
          env:
            - name: AUTH_ADDRESS
              value: "auth-service.default"

 

service 이름(auth-service) 뒤에 붙은 namespace(default) 는 기본 값이 default 임 

우리가 kube 에게 특별한 namespace 를 사용하라고 명령하지 않는 한,

kube 는 default namespace 를 계속 사용함

(이 도메인네임은 Container 내부 코드에서 사용 가능할까? 왠지 가능할 것 같음)

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

+ Recent posts