네트워킹 테스트용 데모 버전 실행을 위해
다음과 같은 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 내부 코드에서 사용 가능할까? 왠지 가능할 것 같음)
ㅇ
'Docker' 카테고리의 다른 글
[Docker] Udemy Docker & Kubernetes : 실전 가이드 필기 - Kubernetes 데이터 & 볼륨 (0) | 2024.01.15 |
---|---|
[Docker] Udemy Docker & Kubernetes : 실전 가이드 필기 - Kubernetes 핵심 개념 (1) | 2023.12.17 |
[Docker] Udemy Docker & Kubernetes : 실전 가이드 필기 - Docker Compose (0) | 2023.11.15 |
[Docker] Udemy Docker & Kubernetes : 실전 가이드 필기 - Docker (1) | 2023.10.03 |
[Docker] CentOS 7 Dockerfile (0) | 2022.07.20 |