*유데미에서 진행하는 Kubernetes for the Absolute Beginners - Hands-on 강의를 바탕으로 제작되었습니다.
마이크로서비스 어플리케이션 실습을 위해 개와 고양이를 선택하는 투표앱과 그 결과를 알려주는 결과앱을 연동하는 서비스를 만들어보겠습니다.
마이크로서비스는 각 서비스가 독립적으로 동작하고 느슨하게 연결되어 있는 특징이 있습니다. 이러한 독립적인 서비스를 쿠버네티스 배포와 서비스를 이용해 만들어보겠습니다.
1. 마이크로서비스 구성
pod는 5개로 voting-app, redis, worker, postgres, result-app가 있고 각 파드들을 이어주기 위한 쿠버네티스 서비스가 필요합니다. 서비스는 voting-app, redis, postgres, result-app에 각 1개씩 총 4개가 존재하고 worker에는 서비스가 붙어있지 않습니다.
어떤 응용 프로그램이 어떤 서비스에 액세스를 요구하는지 확실히 알아야 합니다. 위의 그림에서 redis는 voting-app과 worker에 액세스되고, postgresDB는 worker앱과 result-app에 액세스 됩니다.
voting-app은 외부의 투표하는 사용자와 액세스 되고, result-app은 외부의 결과를 확인하기 위해 액세스 됩니다.
각각의 구성요소는 다른 구성요소의 연결을 허용하지만 worker앱은 아무도 접속하지 않습니다. 즉, 다른 구성요소나 외부 사용자가 worker앱에는 접속할 수 없습니다.
2. 정의 파일 생성 및 실행
각 파드를 생성하는 yaml 파일들은 다음과 같습니다.
voting-app-deploy.yaml, voting-app-service.yaml
redis-deploy.yaml, redis-service.yaml
worker-deploy.yaml
postgres-deploy.yaml, postgres-service.yaml
result-app-deploy.yaml, result-app-service.yaml
# voting-app-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: voting-app-deploy
labels:
name: voting-app-deploy
app: demo-voting-app
spec:
replicas: 1
selector:
matchLabels:
name: voting-app-pod
app: demo-voting-app
template:
metadata:
name: voting-app-pod
labels:
name: voting-app-pod
app: demo-voting-app
spec:
containers:
- name: voting-app
image: kodekloud/examplevotingapp_vote:v1
ports:
- containerPort: 80
spec.containers.ports에 containerPort가 있습니다. containerPort란 컨테이너가 수신 대기하고 있는 포트를 의미합니다.
쿠버네티스 서비스에서 spec.ports.targetPort랑은 다른데 targetPort는 서비스나 다른 파드가 해당 컨테이너로 연결할 때 사용되는 포트이고, containerPort는 파드 내부의 컨테이너가 수신 대기하고 있는 포트. 즉, 파드 내부에서 해당 컨테이너의 어플리케이션이나 서비스와 통신하기 위해 사용되는 포트입니다.
targetPort는 외부용, containerPort는 파드 내부용입니다
# voting-app-service.yaml
apiVersion: v1
kind: Service
metadata:
name: voting-service
labels:
name: voting-service
app: demo-voting-app
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
# voting-app은 클러스터 외부와 통신해야 하므로 nodePort 필요
nodePort: 30004
selector:
# redis-pod.yaml의 labels 부분을 가져온다
name: voting-app-pod
app: demo-voting-app
voting-app은 외부 사용자와 통신해야 하므로 노드포트가 필요합니다. 그래서 type도 NodePort입니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-deploy
labels:
name: redis-pod
app: demo-voting-app
spec:
replicas: 1
selector:
matchLabels:
name: redis-pod
app: demo-voting-app
template:
metadata:
name: redis-pod
labels:
name: redis-pod
app: demo-voting-app
spec:
containers:
- name: redis
image: redis
ports:
- containerPort: 6379
# redis-service.yaml
apiVersion: v1
kind: Service
metadata:
name: redis
labels:
name: redis-service
app: demo-voting-app
spec:
# type: ClusterIP 지정하지 않으면 클러스터ip가 기본값이 된다
ports:
- port: 6379
targetPort: 6379
# 내부 서비스가 될 예정이라 nodePort는 필요없다
selector:
# redis-pod.yaml의 labels 부분을 가져온다
name: redis-pod
app: demo-voting-app
redis의 서비스는 type이 ClusterIP이지만 spec속성에 따로 지정하지 않으면 자동으로 할당됩니다. 또한 redis는 클러스터 내부에서만 통신하기 때문에 노드포트가 필요없습니다.
# worker-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: worker-deploy
labels:
name: worker-app-pod
app: demo-voting-app
spec:
replicas: 1
selector:
matchLabels:
name: worker-app-pod
app: demo-voting-app
template:
metadata:
name: worker-app-pod
labels:
name: worker-app-pod
app: demo-voting-app
spec:
containers:
- name: worker-app
image: kodekloud/examplevotingapp_worker:v1
# postgres-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres-deploy
labels:
name: postgres-deploy
app: demo-voting-app
spec:
replicas: 1
selector:
matchLabels:
name: postgres-pod
app: demo-voting-app
template:
metadata:
name: postgres-pod
labels:
name: postgres-pod
app: demo-voting-app
spec:
containers:
- name: postgres
image: postgres
ports:
- containerPort: 5432
env:
- name: POSTGRES_USER
value: "postgres"
- name: POSTGRES_PASSWORD
value: "postgres"
- name: POSTGRES_HOST_AUTH_METHOD # 추가사항
value: trust
- name: POSTGRES_HOST_AUTH_METHOD # 추가사항
value: trust
이 부분은 강의대로 진행하면 오류가 발생해 문의사항에 질문을 올린 후 피드백을 받아서 추가한 내용입니다.
# postgres-service.yaml
apiVersion: v1
kind: Service
metadata:
name: db
labels:
name: postgres-service
app: demo-voting-app
spec:
ports:
- port: 5432
targetPort: 5432
selector:
name: postgres-pod
app: demo-voting-app
postgres의 서비스도 클러스터 내부에서만 통신하기 때문에 노드포트가 필요하지 않습니다 또한 type은 클러스터ip로 자동 할당됩니다.
또한 데이터베이스의 역할을 하기 때문에 name도 db라 지정했습니다.
# result-app-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: result-app-deploy
labels:
name: result-app-pod
app: demo-voting-app
spec:
replicas: 1
selector:
matchLabels:
name: result-app-pod
app: demo-voting-app
template:
metadata:
name: result-app-pod
labels:
name: result-app-pod
app: demo-voting-app
spec:
containers:
- name: result-app
image: kodekloud/examplevotingapp_result:v1
ports:
- containerPort: 80
# result-app-service.yaml
apiVersion: v1
kind: Service
metadata:
name: result-service
labels:
name: result-service
app: demo-voting-app
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
# result-app-service는 클러스터 외부와 통신해야 하므로 노드포트 필요
nodePort: 30005
selector:
# redis-pod.yaml의 labels 부분을 가져온다
name: result-app-pod
app: demo-voting-app
result-app은 외부 사용자와 통신해야 하므로 노드포트가 필요합니다.
이제 kubectl create -f 명령어를 사용해서 각 deployment와 service를 생성하고 생성 내용을 확인해 보겠습니다.
kubectl get pods,deployment
>>>
NAME READY STATUS RESTARTS AGE
pod/postgres-deploy-776f4bdfcb-b54qz 1/1 Running 0 22m
pod/redis-deploy-54b67b7b4-wqwjj 1/1 Running 0 22m
pod/result-app-deploy-7cc95854b6-krqr6 1/1 Running 0 21m
pod/voting-app-deploy-96f58547f-t8ktw 1/1 Running 0 21m
pod/worker-deploy-54575bd48c-2qbzn 1/1 Running 0 20m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/postgres-deploy 1/1 1 1 22m
deployment.apps/redis-deploy 1/1 1 1 22m
deployment.apps/result-app-deploy 1/1 1 1 21m
deployment.apps/voting-app-deploy 1/1 1 1 21m
deployment.apps/worker-deploy 1/1 1 1 20m
------------------------------------------------------------------------
kubectl get service
>>>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
db ClusterIP 10.100.248.147 <none> 5432/TCP 20m
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 9h
redis ClusterIP 10.98.104.33 <none> 6379/TCP 20m
result-service NodePort 10.103.9.230 <none> 80:30005/TCP 20m
voting-service NodePort 10.107.25.136 <none> 80:30004/TCP 5s
디플로이먼트 5개 replicas=1로 지정했기 때문에 pods도 5개가 생성되었습니다. 그리고 서비스의 type도 노드포트2개, 클러스터ip 3개로 총 5개가 정상적으로 작동되는 것을 확인할 수 있습니다.
3. 실행
이제 voting-app과 result-app이 잘 실행되는지 확인하기 위해 새로운 터미널 2개를 생성합니다.
각 터미널에 다음과 같은 명령어를 입력합니다.
minikube service voting-service --url
>>>
http://127.0.0.1:54697
❗ darwin 에서 Docker 드라이버를 사용하고 있기 때문에, 터미널을 열어야 실행할 수 있습니다
minikube service result-service --url
>>>
http://127.0.0.1:54758
❗ darwin 에서 Docker 드라이버를 사용하고 있기 때문에, 터미널을 열어야 실행할 수 있습니다
voting-service와 result-service에 지정한 노드포트인 30004, 30005가 아닌 다른 포트번호가 출력되는 것은 minikube에서 자동으로 다른 포트로 매핑하는 것이기 때문에 신경쓰지 않아도 됩니다. ctrl+c를 눌러 취소를 한 뒤 저 명령어를 다시 실행하면 포트 번호는 다른 번호로 변경됩니다.
voting-app 화면에서 고양이가 아닌 강아지를 선택하면 result-app의 모습도 변경됩니다.
'[Cloud] > [Kubernetes]' 카테고리의 다른 글
[Kubernetes] HPA, VPC, CA (0) | 2024.09.03 |
---|---|
[Kubernetes] 쿠버네티스 서비스 - 3. 로드밸런서(LoadBalancer) (0) | 2024.05.29 |
[Kubernetes] 쿠버네티스 서비스 - 2. 클러스터ip(ClusterIP) (0) | 2024.05.28 |
[Kubernetes] 쿠버네티스 서비스 - 1. 노드포트(NodePort) (0) | 2024.05.27 |
[Kubenetes] 쿠버네티스 업데이트 & 롤백 2 (0) | 2024.05.25 |