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