서버를 실제로 서비스할 때 서비스적인 장애와 배포에 있어서 부담감을 최소화하고, 서비스가 중단되지 않도록 배포하는 기술이다.
구 버전을 하나 제거하고 새 버전을 하나 추가하는 과정을 반복하는 방식이다.(V1에서 V2로 점진적으로 전환)
이전버전(v1)과 새버전(v2)의 인스턴스가 동시에 존재할 수 있다는 단점이 있다.
이전버전과 새버전을 동시에 나란히 구성 후 트래픽을 일제히 전환한다.
롤링에서 존재하는 버전차이에 대한 문제를 해결할 수 있다.
문제 발생시 빠른 롤백(Roll-Back)이 가능하다.
단점으로는 시스템 자원이 두배로 필요하다.
서버의 트래픽 일부를 새로운 버전으로 분산해서 조금씩 테스트해본 후, 오류가 없으면 정상적으로 전체를 배포하는 방식이다.
트래픽 일부를 분산하는 방식으로 신버전에서의 오류여부를 확인 할 수 있다.
문제 발생시 트래픽만 조정하면 되므로, 빠른 롤백이 가능하다.
# deployment-exam1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deploy
spec:
selector:
matchLabels:
app: webui
replicas: 3
template:
metadata:
labels:
app: webui
spec:
containers:
- image: nginx:1.14
name: web
ports:
- containerPort: 80
위는 RollingUpdate를 위한 yaml 파일이다.
# pod 배포 (--record옵션은 업데이트 과정을 history로 기록하는 옵션)
$ kubectl apply -f deployment-exam1.yaml --record
# pod 확인
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
app-deploy-86c8cbb88-hsmmb 1/1 Running 0 16m 172.16.103.138 w2-k8s <none> <none>
app-deploy-86c8cbb88-hwvll 1/1 Running 0 16m 172.16.221.137 w1-k8s <none> <none>
app-deploy-86c8cbb88-k5vn6 1/1 Running 0 16m 172.16.132.14 w3-k8s <none> <none>
# describe를 통한 pod Image정보 확인
$ kubectl describe pod app-deploy-86c8cbb88-hsmmb | grep Image
Image: nginx:1.14
Image ID: docker.io/library/nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d
# nginx:1.15 버전으로 업데이트
$ kubectl set image deployment app-deploy web=nginx:1.15 --record
# pod 확인
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
app-deploy-cf8c7477c-6vnfb 1/1 Running 0 119s 172.16.103.140 w2-k8s <none> <none>
app-deploy-cf8c7477c-f8c6c 1/1 Running 0 2m10s 172.16.221.139 w1-k8s <none> <none>
app-deploy-cf8c7477c-lzgwg 1/1 Running 0 109s 172.16.132.16 w3-k8s <none> <none>
# describe를 통한 pod Image정보 확인
$ kubectl describe pod app-deploy-cf8c7477c-6vnfb | grep Image
Image: nginx:1.15
Image ID: docker.io/library/nginx@sha256:23b4dcdf0d34d4a129755fc6f52e1c6e23bb34ea011b315d87e193033bcd1b68
# history 확인
$ kubectl rollout history deployment app-deploy
deployment.apps/app-deploy
REVISION CHANGE-CAUSE
1 kubectl apply --filename=deployment-exam1.yaml --record=true
2 kubectl set image deployment app-deploy web=nginx:1.15 --record=true
위 예시와 같이 v1은 nginx:1.14버전에서 RollingUpdate를 통해 v2의 nginx:1.15버전으로 점진적으로 바뀌는 것을 확인할 수 있다.
# history 확인
$ kubectl rollout history deployment app-deploy
deployment.apps/app-deploy
REVISION CHANGE-CAUSE
1 kubectl apply --filename=deployment-exam1.yaml --record=true
2 kubectl set image deployment app-deploy web=nginx:1.15 --record=true
# 1버전으로 rollout
$ kubectl rollout undo deployment app-deploy --to-revision=1
deployment.apps/app-deploy rolled back
# history 확인
$ kubectl rollout history deployment app-deploy
deployment.apps/app-deploy
REVISION CHANGE-CAUSE
2 kubectl set image deployment app-deploy web=nginx:1.15 --record=true
3 kubectl apply --filename=deployment-exam1.yaml --record=true
# pod 확인
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
app-deploy-86c8cbb88-kts7r 1/1 Running 0 3m45s 172.16.103.141 w2-k8s <none> <none>
app-deploy-86c8cbb88-v6q9d 1/1 Running 0 3m43s 172.16.221.140 w1-k8s <none> <none>
app-deploy-86c8cbb88-w2msh 1/1 Running 0 3m43s 172.16.132.17 w3-k8s <none> <none>
# Image 확인
$ kubectl describe pod app-deploy-86c8cbb88-kts7r | grep Image
Image: nginx:1.14
Image ID: docker.io/library/nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d
1버전으로 rollout하였고, history를 확인한다면 1버전이 3버전으로 바뀌는 것을 확인할 수 있다. 만약, kubectl rollout undo deployment <디플로이먼트>
으로 명령을 실행한다면 2버전의 nginx:1.15의 Pod가 rollout이 될 것이다.
$ kubectl set image deployment <디플로이먼트> <컨테이너>=<이미지>:<버전>
$ kubectl rollout status deployment <디플로이먼트>
$ kubectl describe deployments.apps <디플로이먼트>
$ kubectl rollout undo deployment <디플로이먼트>
$ kubectl rollout undo deployment <디플로이먼트> --to-revision=<버전>
$ kubectl rollout history deployment <디플로이먼트>
$ kubectl rollout history deployment <디플로이먼트> --revision=<버전>
# deployment-exam2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
annotations:
kubernetes.io/change-cause: version 1.15
spec:
progressDeadlineSeconds: 600
revisionHistoryLimit: 10
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
replicas: 3
selector:
matchLabels:
app: webui
template:
metadata:
labels:
app: webui
spec:
containers:
- name: web
image: nginx:1.15
ports:
- containerPort: 80
위는 yaml을 통한 RollingUpdate를 위한 yaml 파일이다.
# pod 배포
$ kubectl apply -f deployment-exam2.yaml --record
# pod 확인
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
deploy-nginx-cf8c7477c-ln6xr 1/1 Running 0 15s 172.16.221.141 w1-k8s <none> <none>
deploy-nginx-cf8c7477c-tfvmc 1/1 Running 0 15s 172.16.132.18 w3-k8s <none> <none>
deploy-nginx-cf8c7477c-zd646 1/1 Running 0 15s 172.16.103.142 w2-k8s <none> <none>
# describe를 통한 pod Image정보 확인
$ kubectl describe pod deploy-nginx-cf8c7477c-tfvmc | grep Image
Image: nginx:1.15
Image ID: docker.io/library/nginx@sha256:23b4dcdf0d34d4a129755fc6f52e1c6e23bb34ea011b315d87e193033bcd1b68
# yaml 파일 수정
$ vi deployment-exam2.yaml
kubernetes.io/change-cause: version 1.15 -> kubernetes.io/change-cause: version 1.18
image:1.15 -> image:1.18
# pod 배포
$ kubectl apply -f deployment-exam2.yaml
deployment.apps/deploy-nginx configured
# pod 확인
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
deploy-nginx-55cdc7c796-7pvd7 1/1 Running 0 63s 172.16.132.19 w3-k8s <none> <none>
deploy-nginx-55cdc7c796-cg7h2 1/1 Running 0 75s 172.16.221.142 w1-k8s <none> <none>
deploy-nginx-55cdc7c796-d4cvb 1/1 Running 0 86s 172.16.103.143 w2-k8s <none> <none>
# describe를 통한 pod Image정보 확인
kubectl describe pod deploy-nginx-55cdc7c796-7pvd7 | grep Image
Image: nginx:1.18
Image ID: docker.io/library/nginx@sha256:e90ac5331fe095cea01b121a3627174b2e33e06e83720e9a934c7b8ccc9c55a0
# history 확인
$ kubectl rollout history deployment deploy-nginx
deployment.apps/deploy-nginx
REVISION CHANGE-CAUSE
1 version 1.15
2 version 1.18
yaml 수정을 통해 업데이트 시 훨씬 더 간결하게 history 정보를 확인할 수 있다. 마지막으로 업데이트한 내역을 yaml 로 업데이트하기에 어느 버전인지 더 빠르게 확인할 수 있다는 장점이 있다.