Kubernetes 배포 Rolling Update, Roll back

다음으로 Deployment라는 리소스를 이용하여 Pod의 Rolling Update, Rollback(무정지 갱신)을 실행한다.

Deployment에서는 Pod를 배포할 때 새 ReplicaSet을 생성하고, 이전 ReplicaSet에서 관리되는 Pod를 중지하면서 새로운 ReplicaSet에서 관리되는 Pod를 생성하는 단계를 단계별로 수행한다. 그래서 새로운(Version Up 후 등) ReplicaSet에 갱신 후의 어플리케이션을 탑재하는 것으로 무정지로의 갱신을 수행할 수 있다.

Update에 대해서뿐 아니라, Rollback(원래의 상태로 되돌리기)도 가능하여, 이 경우도 마찬가지로 정지와 기동을 단계적으로 실시하여 무정지로의 Rollback를 실시하는 것도 가능하다.

Deployment 생성

이 Deployment를 생성하려면 kubectl create deployment 명령을 사용한다.

아래의 예에서는 tag에 1.0을 지정한 helloworld에서, tag에 2.0이 지정된 helloworld로 전환하고 있다. 우선은 Pod가 하나라면 전환을 알기 어렵기 때문에, Pod를 5개에 스케일 업을 실행하겠다.

kubectl create deployment --image [이미지명] [deployment명]

tag 1.0의 helloworld Pod을 기동한다.

kubectl create deployment --image gcr.io/google-samples/hello-app:1.0 helloworld

실행 결과:

% kubectl create deployment --image gcr.io/google-samples/hello-app:1.0 helloworld
deployment.apps/helloworld created

deployment를 확인한다.

% kubectl get deployment
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
helloworld   1/1     1            1           16s

스케일 업

% kubectl scale --replicas=5 deploy/helloworld
deployment.apps/helloworld scaled

deployment를 다시 확인한다.

% kubectl get deployment
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
helloworld   5/5     5            5           34s

배포된 pod를 목록을 확인 한다.

% kubectl get pod
NAME                          READY   STATUS    RESTARTS   AGE
helloworld-7b8f9795b8-4878c   1/1     Running   0          15s
helloworld-7b8f9795b8-6rc9m   1/1     Running   0          15s
helloworld-7b8f9795b8-9k6cg   1/1     Running   0          42s
helloworld-7b8f9795b8-b55sv   1/1     Running   0          15s
helloworld-7b8f9795b8-b9qwr   1/1     Running   0          15s

Rolling Update

다음은 롤링 업데이트를 수행하려고 한다. 그럴려면 먼저 포드 그룹의 이름을 알아야 한다. (위의 방법에서는 각 Pod 이름 helloworld와는 다른 name이 붙는다. 맞추는 방법도 있지만 여기에서는 설명하지 않는다). 그래서 생성한 deployment를 구성하는 yaml 파일을 출력한다. 출력은 아래의 명령으로 수행할 수 있다.

kubectl get deployment helloworld --output yaml

실행 결과:

% kubectl get deployment helloworld --output yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  creationTimestamp: "2022-09-08T04:36:12Z"
  generation: 2
  labels:
    app: helloworld
  name: helloworld
  namespace: default
  resourceVersion: "541"
  uid: 5fe7a79c-8b4a-4961-974d-f6ebc52f00a8
spec:
  progressDeadlineSeconds: 600
  replicas: 5
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: helloworld
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: helloworld
    spec:
      containers:
      - image: gcr.io/google-samples/hello-app:1.0
        imagePullPolicy: IfNotPresent
        name: hello-app   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Pod 그룹명
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 5
  conditions:
  - lastTransitionTime: "2022-09-08T04:36:12Z"
    lastUpdateTime: "2022-09-08T04:36:17Z"
    message: ReplicaSet "helloworld-7b8f9795b8" has successfully progressed.
    reason: NewReplicaSetAvailable
    status: "True"
    type: Progressing
  - lastTransitionTime: "2022-09-08T04:36:41Z"
    lastUpdateTime: "2022-09-08T04:36:41Z"
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  observedGeneration: 2
  readyReplicas: 5
  replicas: 5
  updatedReplicas: 5

이 출력 결과에서 spec-template-spec-containers-name이 Pod 그룹명이다. 여기에서는 hello-app 그룹명이 이것을 사용한다. 롤링 업데이트는 다음 명령을 사용합니다.

kubectl set image deploy/[deployment명] [위에서 얻은 이름]=[이미지명]

tag2.0의 helloworld Pod을 올린다.

kubectl set image deploy/helloworld hello-app=gcr.io/google-samples/hello-app:2.0

실행 결과:

% kubectl set image deploy/helloworld hello-app=gcr.io/google-samples/hello-app:2.0
deployment.apps/helloworld image updated

중간 결과 출력 결과는 아래와 같다.

% kubectl get pod
NAME                          READY   STATUS              RESTARTS   AGE
helloworld-666776755c-jfsfd   0/1     ContainerCreating   0          4s
helloworld-666776755c-mgc95   1/1     Running             0          4s
helloworld-666776755c-s96qf   0/1     ContainerCreating   0          0s
helloworld-666776755c-w57b5   0/1     ContainerCreating   0          4s
helloworld-7b8f9795b8-4878c   1/1     Terminating         0          84s
helloworld-7b8f9795b8-6rc9m   1/1     Running             0          84s
helloworld-7b8f9795b8-9k6cg   1/1     Running             0          111s
helloworld-7b8f9795b8-b55sv   1/1     Running             0          84s

최종 결과 출력 결과는 아래와 같다.

$ kubectl get pod
helloworld-666776755c-jfsfd   1/1     Running   0          25s
helloworld-666776755c-mgc95   1/1     Running   0          25s
helloworld-666776755c-s96qf   1/1     Running   0          21s
helloworld-666776755c-vcmzc   1/1     Running   0          20s
helloworld-666776755c-w57b5   1/1     Running   0          25s

출력 결과를 보면, 오래된 helloworld가 점차 삭제되고 새로운 helloworld가 생성되었는지 확인할 수 있다. 이번 출력 결과에서는 Pod로서 존재하고 있는 개수가 중간 경과의 시점에서 8개가 되었다. 이는 중지 도중에 생성이 이루어지기에 존재하고 있는 Pod의 개수가 증가하고 있다. 이 최대 개수는 운영 환경의 리소스(메모리 등)에 따라 차이가 있을 수 있어, 최대 몇 개까지 존재할 수 있는지 지정할 수도 있다.

자세한 내용은 다시 설명하도록 하겠다.

Roll back

마지막으로 Roll back에 대해서는 아래의 명령으로 실행한다.

$ kubectl rollout undo deploy/helloworld
deployment.apps/helloworld rolled back

중간 결과 출력 결과는 아래와 같다.

% kubectl get pod
NAME                          READY   STATUS              RESTARTS   AGE
helloworld-666776755c-mgc95   1/1     Running             0          4m32s
helloworld-7b8f9795b8-99qsq   0/1     ContainerCreating   0          5s
helloworld-7b8f9795b8-lk8b9   0/1     ContainerCreating   0          5s
helloworld-7b8f9795b8-xnhnt   1/1     Running             0          6s
helloworld-7b8f9795b8-zbfc7   1/1     Running             0          6s
helloworld-7b8f9795b8-zn6vn   1/1     Running             0          6s

최종 결과 출력 결과는 아래와 같다.

% kubectl get pod
NAME                          READY   STATUS    RESTARTS   AGE
helloworld-7b8f9795b8-99qsq   1/1     Running   0          16s
helloworld-7b8f9795b8-lk8b9   1/1     Running   0          16s
helloworld-7b8f9795b8-xnhnt   1/1     Running   0          17s
helloworld-7b8f9795b8-zbfc7   1/1     Running   0          17s
helloworld-7b8f9795b8-zn6vn   1/1     Running   0          17s

동작은 Rolling Update와 비슷하게 서서시 교체되는 식이다.




최종 수정 : 2024-01-18