Kubernetesデプロイ Rolling Update、Rollback

次に、Deploymentというリソースを利用して、PodのRolling Update、Rollback、つまり無停止更新を実行する。

Deploymentでは、Podをデプロイするときに新しいReplicaSetを作成し、以前のReplicaSetで管理されるPodを停止しながら、新しいReplicaSetで管理されるPodを作成する手順を段階的に実行する。そのため、新しいReplicaSetに更新後のアプリケーション、たとえばVersion Up後のアプリケーションを載せることで、無停止で更新を実行できる。

Updateだけでなく、Rollback、つまり元の状態に戻すことも可能であり、この場合も同様に停止と起動を段階的に行うことで、無停止のRollbackを実行できる。

Deploymentの作成

このDeploymentを作成するには、kubectl create deploymentコマンドを使用する。

以下の例では、tagに1.0を指定したhelloworldから、tagに2.0を指定したhelloworldへ切り替えている。まずはPodが1つだけだと切り替えがわかりにくいため、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グループの名前を知る必要がある。上の方法では各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名] [上で取得した名前]=[イメージ名]

tag 2.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数が増えている。この最大数は運用環境のリソース、たとえばメモリなどによって差があり、最大で何個まで存在できるかを指定することもできる。

詳細は改めて説明する。

Rollback

最後にRollbackについては、以下のコマンドで実行する。

$ 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と同じように、徐々に置き換えられる形である。