Rollout
사용자는 Application의 revision 업데이트를 rollout을 통해 수행할 수 있다. Deployment로 배치된 Application의 rollout예시는 다음과 같다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
labels:
app: myapp
type: front-end
spec:
template:
metadata:
name: myapp-pod
labels:
app: myapp
type: front-end
spec:
containers:
- name: nginx-container
image: nginx
replicas: 3
selector:
matchLabels:
type: front-end
Rollout Strategy
새로운 Revision 배포방법들은 다양하다
Recrease
현재 버전의 Pod instance를 모두 삭제하고 새로운 Revision application으로 구성한다. 이 경우 이전 버전의 Pod instance들이 모두 삭제되고 새로운 Revision application이 배치될 때 까지 서비스 장애가 발생한다.
Rolling Update
구 버전 Pod를 하나 삭제하고 Revision Pod를 새롭게 생성한다. 이 과정을 Pod의 개수만큼 수행하면 Pod가 없어 서비스를 제공하지 못하는 장애는 발생하지 않는다. Rollout의 default strategy 이기도 하다.
Rolling update 방법(kubectl apply)
Deployment의 container revision을 한다면 해당 deployment의 container 버전 tag를 명시해서 업데이트 할 수 있다.
기존
...
...
spec:
template:
metadata:
name: myapp-pod
labels:
app: myapp
type: front-end
spec:
containers:
- name: nginx-container
image: nginx
...
Revision
...
...
spec:
template:
metadata:
name: myapp-pod
labels:
app: myapp
type: front-end
spec:
containers:
- name: nginx-container
image: nginx:1.7. # <-- 변경
...
변경된 Deployment를 kubectl apply 명령어로 업데이트 한다.
hugh@master:~/yaml/rolling-update $ k apply -f deploy-revision.yaml
deployment.apps/myapp-deployment configured
hugh@master:~/yaml/rolling-update $
hugh@master:~/yaml/rolling-update $ k get po
NAME READY STATUS RESTARTS AGE
myapp-deployment-56b4f77799-2nvgz 0/1 ContainerCreating 0 6s # <-- Rolling update
myapp-deployment-84ccc5558-mj7pf 1/1 Running 0 5m19s
myapp-deployment-84ccc5558-nrqbf 1/1 Running 0 5m19s
myapp-deployment-84ccc5558-r2smc 1/1 Running 0 5m19s
hugh@master:~/yaml/rolling-update $
Pod의 container 이미지를 확인해 보면 tag가 변경되었음을 확인할 수 있다.
hugh@master:~/yaml/rolling-update $ k describe po myapp-deployment-56b4f77799-2nvgz | grep "Image:"
Image: nginx:1.7.1
hugh@master:~/yaml/rolling-update $ k describe po myapp-deployment-84ccc5558-mj7pf | grep "Image:"
Image: nginx
hugh@master:~/yaml/rolling-update $
Rolling update 방법(kubectl set)
kubectl apply 외에도 set
명령어를 이용해 업데이트할 수 있다.
hugh@master:~/yaml/rolling-update $ k set image deploy/myapp-deployment \
> nginx-container=nginx:1.9.1
deployment.apps/myapp-deployment image updated
hugh@master:~/yaml/rolling-update $ k get po
NAME READY STATUS RESTARTS AGE
myapp-deployment-67b5d598df-24tr8 0/1 ContainerCreating 0 15s
myapp-deployment-84ccc5558-l94xj 1/1 Running 0 56s
myapp-deployment-84ccc5558-lld5m 1/1 Running 0 52s
myapp-deployment-84ccc5558-nrqbf 1/1 Running 0 9m53s
hugh@master:~/yaml/rolling-update $ k describe po myapp-deployment-67b5d598df-24tr8
Name: myapp-deployment-67b5d598df-24tr8
Namespace: default
...
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 22s default-scheduler Successfully assigned default/myapp-deployment-67b5d598df-24tr8 to worker2
Normal Pulling 21s kubelet Pulling image "nginx:1.9.1"
Rolling update 로그
Rolling update로 revision 한다면 다음처럼 Deployment의 로그들을 확인할 수 있다.
hugh@master:~/yaml/rolling-update $ k describe deploy myapp-deployment
Name: myapp-deployment
...
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 2m36s deployment-controller Scaled up replica set myapp-deployment-84ccc5558 to 3
Normal ScalingReplicaSet 2m21s deployment-controller Scaled up replica set myapp-deployment-59f8f48cc to 1
Normal ScalingReplicaSet 2m3s deployment-controller Scaled down replica set myapp-deployment-84ccc5558 to 2 from 3
Normal ScalingReplicaSet 2m3s deployment-controller Scaled up replica set myapp-deployment-59f8f48cc to 2 from 1
Normal ScalingReplicaSet 105s deployment-controller Scaled down replica set myapp-deployment-84ccc5558 to 1 from 2
Normal ScalingReplicaSet 105s deployment-controller Scaled up replica set myapp-deployment-59f8f48cc to 3 from 2
Normal ScalingReplicaSet 85s deployment-controller Scaled down replica set myapp-deployment-84ccc5558 to 0 from 1
위 로그들을 보면 Rolling update로 scale up/down을 반복하며 Pod들의 개수를 유지해 서비스 장애를 발생시키지 않고 업데이트함을 확인할 수 있다.
Upgrade
Deployment의 rolling upgrade 전략은 하나의 Replica-set을 업그레이드 할 때 새로운 Replica-set을 만들어 개수를 조절해 가며 Revision한다.

hugh@master:~/yaml/rolling-update $ k get rs
NAME DESIRED CURRENT READY AGE
myapp-deployment-59f8f48cc 3 3 3 5m52s # 이전 Replicaset
myapp-deployment-84ccc5558 0 0 0 6m7s # 신규 ReplicaSet
Rollback
만약 새로운 Application을 배포했는데 치명적인 문제가 있다고 가정해보자. 생각하기는 싫지만 이 경우 문제분석과 해결, 새롭게 배포하기 전 까지 서비스를 유지해야하므로 이전 버전의 Application을 사용해야 할 것이다. k8s는 이러한 상황에서 사용할 수 있는 rollback을 제공한다.
hugh@master:~/yaml/rolling-update $ k rollout undo deploy/myapp-deployment
deployment.apps/myapp-deployment rolled back
hugh@master:~/yaml/rolling-update $
이렇게 rollback을 하게되면 새로운 Replica-set을 생성하는 것이 아니라 이전의 Replica-set을 재사용 한다.
hugh@master:~/yaml/rolling-update $ k get rs
NAME DESIRED CURRENT READY AGE
myapp-deployment-59f8f48cc 0 0 0 9m11s # 이전 Replicaset
myapp-deployment-84ccc5558 3 3 3 9m26s # 신규 ReplicaSet