CKA를 준비해보자 14일차 - Rolling Updates and Rollbacks

0

CKA

목록 보기
14/43

Rolling Updates and Rollbacks

Deployment에서는 pod에 대한 replicas를 관리하여, 재시작, versioning 등을 제공한다고 하였다. 여기서 versioning으로 pod의 version을 올리고 내릴 수 있는데, rollout이 바로 version을 올리는 작업을 말하고, rollback이 version을 되돌리는 일을 한다.

Revision1: [Pod1-nginx:1.7.0] , [Pod2-nginx:1.7.0]
(Rollout)
Revision2: [Pod1-nginx:1.7.1] , [Pod2-nginx:1.7.1]

위의 예제와 같이 Revision이라는 것을 Deployment에서 갖게되어 version을 rollout, rollback함에 따라 pod의 version이 달라지는 것이다.

  • rollout status command
kubectl rollout status deployment/myapp-deployment

rollout status를 실행하면 지금의 rollout 현황을 볼 수 있다.

만약, 현재까지의 revision이나 version history를 보고 싶다면 아래의 명령어를 쓰면 된다.

  • rollout history
kubectl rollout history deployment/myapp-deployment

Deployment Strategy

deployment에서 rollout, rollback을 실행하는데 있어서, 두 가지 배포 전략이 있다.

  1. 이전 pod들을 모두 없애고, 새로운 version으로 대체하기 - Recreate strategy라고 한다.
Revision1: [Pod1-nginx:1.7.0] , [Pod2-nginx:1.7.0]

rollout시에 먼저 pod1, pod2를 죽이고

(Rollout)
Revision2: [Pod1-nginx:1.7.1] , [Pod2-nginx:1.7.1]

다음 새로운 version의 pod들로 새로올리는 것이다.

문제는 이러한 방식을 사용하면 잠시 동안 application이 down되는 문제가 발생한다는 것이다. 따라서 사용자에게 좋지못한 사용자 경험을 줄 수 밖에 없다.

다행이도 restart strategy는 default strategy가 아니기 때문에 문제가 되지 않는다.

  1. 두번째 방법은 모두 한 번에 다운시켰다가 올리는 것이 아니라, 하나씩 다운시킨다음 새로운 버전의 pod를 올리고를 반복하는 것이다. 이를 Rolling Update strategy라고 하며, 이 방식이 default이다.
Revision1: [Pod1-nginx:1.7.0] , [Pod2-nginx:1.7.0]

rollout시에 먼저 pod1을 죽이고 새로운 버전의 pod1을 올린다. pod2는 여전이 이전 버전이다.

Revision1: [Pod2-nginx:1.7.0]
(Rollout)
Revision2: [Pod1-nginx:1.7.1]

다음으로 pod2를 죽이고 pod2의 새로운 버전을 올린다. 이전에 이미 pod1은 새로운 버전의 pod이다.

(Rollout)
Revision2: [Pod1-nginx:1.7.1] , [Pod2-nginx:1.7.1]

방식을 사용하면 application의 다운없이 사용자에게 지속적인 경험을 시켜줄 수 있어 굉장히 좋다.

지금까지 update 전략에 대해서 알아봤는데, 그런데 어떻게 update를 할 수 있는가?? 여러 방법들이 있는데, kubectl apply를 사용하여 deployment를 업데이트하는 방법이 대표적이다.

  • deployment-definition.yaml
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

다음의 file에서 원하는 부분만 바꾸는 것이다. 이렇게 바꾸면 rollout이 발생하고 새로운 pod가 생길 것이다.

그런데, 만약 image만 바꾸고 싶은 경우는 kubectl set image를 사용해도 된다.

kubectl set image deployment/myapp-deployment nginx-container=nginx:1.9.1

사실 rollout방식은 실제로 내부적으로는 그렇게 어려울 것이 없는데, deployment내부가 ReplicaSet으로 이루어졌다는 것만 기억하면 쉽다.

현재 deployment에 해당하는 ReplicaSet1이 있다고 하자.

-----ReplicaSet 1-----
|pod1, pod2, pod3    |
----------------------

새로운 deployment로 rollout되면 새로운 ReplicaSet 2를 만드는 것이다. 단, 이 경우 순차적인 rolling update를 해야하기 때문에 다음과 같은 순서로 업데이트된다.

-----ReplicaSet 1-----  -----ReplicaSet 2-----
|pod2, pod3          |  |pod1                |
----------------------  ----------------------

먼저 ReplicaSet 1pod1이 죽고, ReplicaSet 2pod1이 생긴다.

-----ReplicaSet 1-----  -----ReplicaSet 2-----
| pod3               |  |pod1, pod2          |
----------------------  ----------------------

이 다음도 마찬가지인데, ReplicaSet 1pod2가 죽고, ReplicaSet 1pod2가 생긴다.

-----ReplicaSet 1-----  -----ReplicaSet 2-----
|                    |  |pod1, pod2, pod3    |
----------------------  ----------------------

이제 모든 pod들이 ReplicaSet 2에 의해서 생성되고 ReplicaSet 1은 텅비어지게 된다.

그러나 ReplicaSet 1이 텅비었다고 해서 사라지는 것은 아니다. kubectl get replicasets로 확인해보면 ReplicaSet 1이 있는 것을 볼 수 있을 것이다.

kubectl get replicasets
NAME        DESIRED     CURRENT     READY       AGE
replicaset1 0           0           0           22m
replicaset2 5           5           5           20m

만약 rollback을 하고 싶다면 다음의 명령어를 사용하면 된다.

kubectl rollout undo deployment/myapp-deployment

rollback시에 우리가 삭제하지 않았던 ReplicaSet 1이 힘을 발휘한다. ReplicaSet 1이 남아있으므로, 이를 사용하여 이전 old version의 pod들을 다시 올리고, 새로운 버전의 pod들은 ReplicaSet 2의 replicas 수를 0으로 만들어 rollback을 진행하는 것이다.

명령어 정리

  • create
kubectl create -f deployment-definition.yaml
  • get
kubectl get deployments
  • update
kubectl apply -f deployment-definition.yaml
kubectl set image deployment/myapp-deployment nginx=nginx:1.9.1
  • status
kubectl rollout status deployment/myapp-deployment
kubectl rollout history deployment/myapp-deployment
  • rollback
kubectl rollout undo deployment/myapp-deployment

참고로 kubectl edit으로는 rolling update 이력을 남길 수 없다. 따라서 kubectl set ... --record를 통해서 이력을 남기는 것이 좋다.

다음은 nginx-deploy deployment의 nginx container에 대해서 image를 nginx:1.17로 바꾸고, rolling update history를 남기기 위해 --record를 넣은 것이다.

kubectl set image deployment/nginx-deploy nginx=nginx:1.17 --record

0개의 댓글