이전 글의 마지막에서 설명한 Blue-Green 배포를 하고, 웹사이트를 통해 직접 확인해보자
: 운영중인 구버전과 동일하게 신버전의 인스턴스를 구성한 후 로드밸런서를 통해 모든 트래픽을 한번에 신버전 쪽으로 전환하는 방식이다.
구버전의 인스턴스가 그대로 남아있어, 손쉬운 롤백 가능
구버전의 환경을 다음 배포에 재사용 가능
운영환경에 영향을 주지 않고 새 버전 테스트 가능
시스템 자원이 두 배로 필요하다
새로운 환경에 대한 테스트가 전제가 되어야 한다.
: nginx1.11 (Blue)와 nginx1.12 (Green) 배포를 진행해보자.
vi nginx11.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx11
spec:
replicas: 3
selector:
matchLabels:
app: deploy-nginx11
template:
metadata:
labels:
app: deploy-nginx11
spec:
containers:
- name: deploy-nginx11
image: nginx:1.11
kubectl apply -f nginx11.yaml
vi nginx12.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx12
spec:
replicas: 3
selector:
matchLabels:
app: deploy-nginx12
template:
metadata:
labels:
app: deploy-nginx12
spec:
containers:
- name: deploy-nginx11
image: nginx:1.12
kubectl apply -f nginx12.yaml
for pod in $(kubectl get pod -l app=deploy-nginx11 |awk 'NR>1 {print $1}'); do kubectl exec $pod -- /bin/sh -c "hostname > /usr/share/nginx/html/index.html; echo 'nginx:v1.11 END' >> /usr/share/nginx/html/index.html"; done
for pod in $(kubectl get pod -l app=deploy-nginx12 |awk 'NR>1 {print $1}'); do kubectl exec $pod -- /bin/sh -c "hostname > /usr/share/nginx/html/index.html; echo 'nginx:v1.12 END' >> /usr/share/nginx/html/index.html"; done
⇒ curl을 통해 접속 시, 파드 이름과 버전, 그리고 END로 표시가 되도록 수정한다.
이제 nginx v1.11과 nginx v1.12가 제대로 생성되었는지 확인해보자.
kubectl get pod -o wide -l app=deploy-nginx11 |awk 'NR>1 {print $6}'
10.1.0.19
10.1.0.18
10.1.0.20
kubectl get pod -o wide -l app=deploy-nginx12 |awk 'NR>1 {print $6}'
10.1.0.23
10.1.0.21
10.1.0.22
minikube ssh
⇒ minkube를 사용하면 외부에서 curl을 통해 pod에 접속이 되지 않으므로, minikube의 VM에 직접 접속하여 curl을 시도해야 한다.
curl -s "위에서 nginx11 podIP 중 하나 선택"
deploy-nginx11-6489d4db8b-kbdj4
nginx:v1.11 END
curl -s "위에서 nginx12 podIP 중 하나 선택"
deploy-nginx12-b5c6679d6-dn5kc
nginx:v1.12 END
exit
vi svc-nginx.yaml
apiVersion: v1
kind: Service
metadata:
name: svc-nginx
spec:
ports:
- name: svc-nginx
port: 9000
targetPort: 80
selector:
app: deploy-nginx11
⇒ Type 지정을 하지 않을 시, 기본 Type은 ClusterIP가 된다.
kubectl apply -f svc-nginx.yaml
kubectl get service svc-nginx
kubectl get service svc-nginx -o jsonpath='{.spec.clusterIP}' ; echo
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc-nginx ClusterIP 10.108.8.47 <none> 9000/TCP 19s
10.108.8.47
⇒ 서비스 생성 확인 및 ClusterIP의 주소를 확인한다.
⇒ 어떠한 딜레이 없이 모든 엔드포인트가 바로 오른쪽 그린 배포로 옮겨져야 한다.
kubectl get endpoints svc-nginx
NAME ENDPOINTS AGE
svc-nginx 10.1.0.18:80,10.1.0.19:80,10.1.0.20:80 3m1s
⇒ 파드들의 IP와 비교한 결과 엔드포인트가 잘 연결되어있음을 알 수 있다.
kubectl get pod -o wide -l app=deploy-nginx11 |awk 'NR>1 {print $6}'
10.1.0.19
10.1.0.18
10.1.0.20
kubectl logs -l 'app in (deploy-nginx11)' -f --max-log-requests 8
kubectl logs -l 'app in (deploy-nginx12)' -f --max-log-requests 8
minikube ssh
SVC="서비스의 ClusterIP를 넣어주세요. 큰 따옴표 지워주셔야 합니다."
for i in {1..100}; do curl -s $SVC:9000 ; done | sort | uniq -c | sort -nr
while true; do curl -s --connect-timeout 1 $SVC:9000 ; echo "--------------" ; date "+%Y-%m-%d %H:%M:%S" ; sleep 1; done
2023-05-24 04:43:00
deploy-nginx11-6489d4db8b-rnmb9
nginx:v1.11 END
--------------
2023-05-24 04:43:01
deploy-nginx11-6489d4db8b-vwzj8
nginx:v1.11 END
--------------
2023-05-24 04:43:02
deploy-nginx11-6489d4db8b-vwzj8
nginx:v1.11 END
--------------
2023-05-24 04:43:03
deploy-nginx11-6489d4db8b-kbdj4
nginx:v1.11 END
--------------
2023-05-24 04:43:04
deploy-nginx11-6489d4db8b-rnmb9
nginx:v1.11 END
⇒ Blue 배포 파드의 로그는 기록되는 반면 Green 배포의 로그는 기록되지 않음을 알 수 있다.
=> Blue 배포 로그
=> Green 배포 로그
그럼 이제 Green 배포로 바꿔보자.
kubectl get svc svc-nginx -o yaml | sed -e "s/app: deploy-nginx11/app: deploy-nginx12/" | kubectl apply -f -
minikube ssh
SVC="서비스의 ClusterIP를 넣어주세요. 큰 따옴표 지워주셔야 합니다."
e
2023-05-24 04:51:25
deploy-nginx12-b5c6679d6-jf9zh
nginx:v1.12 END
--------------
2023-05-24 04:51:26
deploy-nginx12-b5c6679d6-j2qdp
nginx:v1.12 END
--------------
2023-05-24 04:51:27
deploy-nginx12-b5c6679d6-jf9zh
nginx:v1.12 END
--------------
2023-05-24 04:51:28
deploy-nginx12-b5c6679d6-dn5kc
nginx:v1.12 END
--------------
2023-05-24 04:51:29
deploy-nginx12-b5c6679d6-dn5kc
nginx:v1.12 END
⇒ 이번엔 Blue 배포의 로그는 기록되지 않고 Green 배포가 출력되고 있음을 확인할 수 있다.
kubectl get svc svc-nginx -o yaml | sed -e "s/app: deploy-nginx12/app: deploy-nginx11/" | kubectl apply -f -
더 확실하게 표시하기 위해 NodePort를 통해 외부로 노출시켜 보자.
kubectl edit svc svc-nginx
...
ports:
- name: svc-nginx
port: 9000
protocol: TCP
targetPort: 80
selector:
app: deploy-nginx11
sessionAffinity: None
type: ClusterIP # NodePort로 변경
:wq
service/svc-nginx edited
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 24h
svc-nginx NodePort 10.99.240.247 <none> 9000:30653/TCP 92s
minikube로 쿠버네티스를 실행 시, minikube 가상 머신 안에서 돌아가기 때문에 여전히 외부로 접속이 불가능하므로, minikube 자체에서 서비스를 노출시켜야 한다.
minikube service svc-nginx
|-----------|-----------|----------------|---------------------------|
| NAMESPACE | NAME | TARGET PORT | URL |
|-----------|-----------|----------------|---------------------------|
| default | svc-nginx | svc-nginx/9000 | http://192.168.49.2:30653 |
|-----------|-----------|----------------|---------------------------|
🏃 svc-nginx 서비스의 터널을 시작하는 중
|-----------|-----------|-------------|------------------------|
| NAMESPACE | NAME | TARGET PORT | URL |
|-----------|-----------|-------------|------------------------|
| default | svc-nginx | | http://127.0.0.1:53653 |
|-----------|-----------|-------------|------------------------|
🎉 Opening service default/svc-nginx in default browser...
❗ Because you are using a Docker driver on darwin, the terminal needs to be open to run it.
⇒ 터미널을 계속 열어야 하므로, 새로운 터미널 창을 열어 마저 실습한다.
kubectl get svc svc-nginx -o yaml | sed -e "s/app: deploy-nginx11/app: deploy-nginx12/" | kubectl apply -f -
kubectl get svc svc-nginx -o yaml | sed -e "s/app: deploy-nginx12/app: deploy-nginx11/" | kubectl apply -f -
다 끝난 후에는 모두 종료하자.
kubectl delete deploy --all
kubectl delete svc svc-nginx