こんにちは
株式会社クラスアクト インフラストラクチャ事業部の大塚です。
今回はGKE環境を使ってKubernetesのローリングアップデート及びロールバックを実際に試してみようと思います。
検証方法
以下が検証イメージです。
まずGKE環境上でDockerfileとindex.htmlファイルを作成し検証用のDockerイメージを作成します。
作成したイメージをGoogle Container Registry(≒docker hub的なもの)にpush。
DeploymentとLoadBalancer用のyamlを用意し、それを元にGKE環境にデプロイ。Firefoxを使ってDeploymentに接続してindex.htmlファイルの中身を確認。
その後index.htmlの内容を書き換えて再度イメージを作成しpush。
yamlを書き換えてdeploymentを更新。更新出来たらFirefoxでindex.htmlファイルの中身が更新されていることを確認。
この流れを2,3度繰り返していきます。
用語
Dockerfile
Docker は Dockerfile から命令を読み込み、自動的にイメージをビルドできます。 Dockerfile はテキストファイルであり、イメージを作り上げるために実行するコマンドライン命令を、すべてこのファイルに含められます。
docker buildコマンド
docker build を実行すると、順次コマンドライン命令を自動化した処理を行い、ビルド結果となるイメージが得られます。
GCR(Google Container Registry)
Docker コンテナ イメージを保存、管理、保護。Container Registry では、Docker イメージの一元的な管理と脆弱性分析を行えます。また、きめ細かなアクセス制御によって、どのユーザーに何へのアクセスを許可するかを決定できます。
kubectl applyコマンド
applyはKubernetesリソースを定義するファイルを通じてアプリケーションを管理します。kubectl applyを実行して、クラスター内のリソースを作成および更新します。これは、本番環境でKubernetesアプリケーションを管理する推奨方法です。
kubectl createとkubectl applyの際については以下がグラフィカルで分かりやすいと思いました。
kubectl applyで無いとkubectl diffコマンドで差分がきれいに出せないのかなと思っています。多分。
基本的にapplyを使うのが正解なのかなと思っています。
環境
GKEでautopilotでk8sクラスタを自動構築しています。
2台のノードでクラスタ化されています。
ohtsuka_honban@cloudshell:~/yaml/docker (western-antonym-●●●●●●)$ kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
gk3-my-k8s-cluster-default-pool-13c33173-fjcl Ready <none> 15m v1.25.7-gke.1000 10.128.0.6 34.31.37.35 Container-Optimized OS from Google 5.15.65+ containerd://1.6.18
gk3-my-k8s-cluster-default-pool-dda5f4e0-zrgs Ready <none> 15m v1.25.7-gke.1000 10.128.0.7 35.188.98.215 Container-Optimized OS from Google 5.15.65+ containerd://1.6.18
Dockerfileを使ってイメージを作成し、GCRにpushする(1回目)
まず以下のhtmlファイルを用意しました。
このファイルをDockerfileを使い作成するDockerイメージに組み込みますが、バージョンアップをする時に"ver1.0!"の部分を少しずつ変化させます。
<h1>Hello GKE!</h1>
<h2>This is apache2 pod ver1.0!</h2>
Dockerfileは以下を用意。
『httpdのDockerイメージを使用し、そのイメージの中にあるindex.htmlはGKE上に用意したものを使用してね!』的な事が書いていると思って頂ければいいと思います。
FROM httpd
COPY index.html /usr/local/apache2/htdocs/
イメージ化します。GCRにpushする都合上、イメージの名前の付け方に気を付けます。
"gcr.io/"のあとの部分は各個人のプロジェクトIDを確認して調整をしてください。
ohtsuka_honban@cloudshell:~/yaml/docker (western-antonym-●●●●●●)$ docker build -t gcr.io/western-antonym-●●●●●●/apache2:1.0 .
プロジェクトIDはGCPのトップ画面の赤で塗りつぶしたところに書いています。
この後GKEにGCRを認識?させます
※もしかしたら、この部分はいらないかもしれません。
ohtsuka_honban@cloudshell:~/yaml/docker (western-antonym-●●●●●●)$ gcloud auth configure-docker
WARNING: Your config file at [/home/ohtsuka_honban/.docker/config.json] contains these credential helper entries:
{
"credHelpers": {
"gcr.io": "gcloud",
"us.gcr.io": "gcloud",
"eu.gcr.io": "gcloud",
"asia.gcr.io": "gcloud",
"staging-k8s.gcr.io": "gcloud",
"marketplace.gcr.io": "gcloud"
}
}
Adding credentials for all GCR repositories.
WARNING: A long list of credential helpers may cause delays running 'docker build'. We recommend passing the registry name to configure only the registry you are using.
gcloud credential helpers already registered correctly.
GCRに作成したイメージをpushします
ohtsuka_honban@cloudshell:~/yaml/docker (western-antonym-●●●●●●)$ docker push gcr.io/western-antonym-●●●●●●/apache2:1.0
The push refers to repository [gcr.io/western-antonym-●●●●●●/apache2]
90003dd9562f: Pushed
76554aaac635: Layer already exists
12ef76c76336: Layer already exists
ce0966b9747d: Layer already exists
1f1fd2176485: Layer already exists
8553b91047da: Layer already exists
1.0: digest: sha256:e4ec01a71471dec8ebbe0dc65372b715142c5dd4b9640f0a3df0d3fbf071ac36 size: 1573
WebコンソールでGCRを開き、push出来ているかを確認します。
問題なさそうですね。
GKEにDeploymentとLoadBalancerをデプロイし、Webブラウザでindex.htmlを確認する(1回目)
Deployment用に用意したyamlファイルは以下
strategyの部分がローリングアップデートやロールバックに関連してくるものになります。
今回は"rollingUpdate"を指定していますが"Recreate"というstrategyもあるみたいです。何も指定しないと"rollingUpdate"が勝手に選択されるのですが、勉強の為入力しています。
"maxSurge: 1"というのは「宣言したPod数を超えて作れるPod数を1とする」ということを指定し、"maxUnavailable: 0"というのは「停止状態になる最大Pod数を0とする」ということを指定しています。
apiVersion: apps/v1
kind: Deployment
metadata:
name: apache2-deployment
labels:
name: apache2-deployment
spec:
replicas: 2
selector:
matchLabels:
name: apache2
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
name: apache2
spec:
containers:
- name: apache2-con
image: gcr.io/western-antonym-●●●●●●/apache2:1.0
ports:
- containerPort: 80
自分で書いていて"maxSurge: 1"と"maxUnavailable: 0"が腑に落ちなかったので、少しググってみたのですが、以下の記事が分かりやすかったです。
ざっくりですが
- "yamlで指定されたreplicasの数"+"yamlで指定されたmaxSurgeの数"="ローリングアップデート/ロールバック時の最大のpodの数"(私の場合、2 + 1 = 3)
- "yaml指定されたreplicasの数"+"yamlで指定されたmaxUnavailableの数"="ローリングアップデート/ロールバック時の最小のpodの数"(私の場合、2 - 0 = 2)
ということになるのだと思います。
「ローリングアップデート/ロールバックの際podの数は2以上3以下で維持せよ!」ということをKubernetesに指示していることになるのだと思います。
デプロイしていきます。
ohtsuka_honban@cloudshell:~/yaml (western-antonym-●●●●●●)$ kubectl apply -f apache2-deployment.yaml
Warning: Autopilot set default resource requests for Deployment default/apache2-deployment, as resource requests were not specified. See http://g.co/gke/autopilot-defaults
deployment.apps/apache2-deployment created
結果を確認します。2つpodが作成されていることが分かりますね。
また、Deploymentとそれに合わせてReplicasetも作成されています。
ohtsuka_honban@cloudshell:~/yaml (western-antonym-●●●●●●)$ kubectl get all -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/apache2-deployment-7868df7b76-d8tnd 1/1 Running 0 37s 10.109.128.138 gk3-my-k8s-cluster-pool-1-458925f9-kpcw <none> <none>
pod/apache2-deployment-7868df7b76-jbmbq 1/1 Running 0 37s 10.109.128.139 gk3-my-k8s-cluster-pool-1-458925f9-kpcw <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/kubernetes ClusterIP 10.110.0.1 <none> 443/TCP 94m <none>
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/apache2-deployment 2/2 2 2 37s apache2-con gcr.io/western-antonym-386513/apache2:1.0 name=apache2
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
replicaset.apps/apache2-deployment-7868df7b76 2 2 2 38s apache2-con gcr.io/western-antonym-386513/apache2:1.0 name=apache2,pod-template-hash=7868df7b76
LoadBalacerをデプロイします。
今回用意したyamlファイルは以下です。
apiVersion: v1
kind: Service
metadata:
name: apache2-loadbalancer
spec:
type: LoadBalancer
selector:
name: apache2
ports:
- protocol: TCP
port: 60080
targetPort: 80
デプロイします。結果も問題なさそうです。
ohtsuka_honban@cloudshell:~/yaml (western-antonym-●●●●●●)$ kubectl apply -f apache2-loadbalancer.yaml
service/apache2-loadbalancer created
ohtsuka_honban@cloudshell:~/yaml (western-antonym-●●●●●●)$ kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
apache2-loadbalancer LoadBalancer 10.110.0.162 35.238.40.41 60080:30377/TCP 43s name=apache2
kubernetes ClusterIP 10.110.0.1 <none> 443/TCP 95m <none>
この時のイメージです。
Replicasetは今後増えていくので、(私が)ごちゃごちゃしないように名前を書いておきます。
Webブラウザで確認してみます。
指定したhtmlファイルが表示されていますね。
Dockerfileを使ってイメージを作成し、GCRにpushする(2回目)
index.htmlの"ver1.0!"を"ver1.1!"にしたものをベースにdockerイメージ"apache2:1.1"を作成し、GCRにpushします。
ohtsuka_honban@cloudshell:~/yaml/docker (western-antonym-●●●●●●)$ cat index.html
<h1>Hello GKE!</h1>
<h2>This is apache2 pod ver1.1!</h2>
ohtsuka_honban@cloudshell:~/yaml/docker (western-antonym-●●●●●●)$ docker build -t gcr.io/western-antonym-●●●●●●/apache2:1.1 .
ohtsuka_honban@cloudshell:~/yaml/docker (western-antonym-●●●●●●)$ docker push gcr.io/western-antonym-●●●●●●/apache2:1.1
GKEにDeploymentとLoadBalancerをデプロイし、Webブラウザでindex.htmlを確認する(2回目)
ローリングアップデート用のyamlを用意します。
pod用のイメージを更新したのみで他は変更ありません。
ohtsuka_honban@cloudshell:~/yaml (western-antonym-●●●●●●)$ cp -p apache2-deployment.yaml apache2-deployment-1.1.yaml
ohtsuka_honban@cloudshell:~/yaml (western-antonym-●●●●●●)$ diff apache2-deployment.yaml apache2-deployment-1.1.yaml
23c23
< image: gcr.io/western-antonym-386513/apache2:1.0
---
> image: gcr.io/western-antonym-386513/apache2:1.1
kubectl applyでDeploymentに対してアップデートを行っていきます。
ohtsuka_honban@cloudshell:~/yaml (western-antonym-●●●●●●)$ kubectl apply -f apache2-deployment-1.1.yaml
deployment.apps/apache2-deployment configured
kubectl get all -o wideの出力結果をwatchコマンドでリアルタイムで追っていきます。
ローリングアップデートの途中の出力結果が以下となります。
"apache2:1.1"をイメージとしたReplicasetである"apache2-deployment-67f8d54489"が作成され、そのReplicaset内で管理されているpod"apache2-deployment-67f8d54489-dt997"が作成を開始しています。
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/apache2-deployment-67f8d54489-dt997 0/1 Pending 0 8s <none> <none> <none> <none>
pod/apache2-deployment-7868df7b76-d8tnd 1/1 Running 0 10m 10.109.128.138 gk3-my-k8s-cluster-pool-1-458925f9-kpcw <none> <none>
pod/apache2-deployment-7868df7b76-jbmbq 1/1 Running 0 10m 10.109.128.139 gk3-my-k8s-cluster-pool-1-458925f9-kpcw <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/apache2-loadbalancer LoadBalancer 10.110.0.162 35.238.40.41 60080:30377/TCP 9m32s name=apache2
service/kubernetes ClusterIP 10.110.0.1 <none> 443/TCP 104m <none>
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/apache2-deployment 2/2 1 2 10m apache2-con gcr.io/western-antonym-386513/apache2:1.1 name=apache2
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
replicaset.apps/apache2-deployment-67f8d54489 1 1 0 9s apache2-con gcr.io/western-antonym-386513/apache2:1.1 name=apache2,pod-template-hash=67f8d54489
replicaset.apps/apache2-deployment-7868df7b76 2 2 2 10m apache2-con gcr.io/western-antonym-386513/apache2:1.0 name=apache2,pod-template-hash=7868df7b76
最終的な状態は以下となります。ver1.0のpodが削除され、1.1のpodのみが稼働しています。
個人的に意外だと思ったのがver1.0のreplicasetが残るんだということです。恐らくロールバックの時に内部的に設定値を見る為とかに残しているのかなと思っているのですがどうなんでしょう。。。?
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/apache2-deployment-67f8d54489-4hzkj 1/1 Running 0 68s 10.109.128.141 gk3-my-k8s-cluster-pool-1-458925f9-kpcw <none> <none>
pod/apache2-deployment-67f8d54489-v6nnw 1/1 Running 0 68s 10.109.128.142 gk3-my-k8s-cluster-pool-1-458925f9-kpcw <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/apache2-loadbalancer LoadBalancer 10.110.0.162 35.238.40.41 60080:30377/TCP 13m name=apache2
service/kubernetes ClusterIP 10.110.0.1 <none> 443/TCP 108m <none>
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/apache2-deployment 2/2 2 2 14m apache2-con gcr.io/western-antonym-386513/apache2:1.1 name=apache2
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
replicaset.apps/apache2-deployment-67f8d54489 2 2 2 4m24s apache2-con gcr.io/western-antonym-386513/apache2:1.1 name=apache2,pod-template-hash=67f8d54489
replicaset.apps/apache2-deployment-7868df7b76 0 0 0 14m apache2-con gcr.io/western-antonym-386513/apache2:1.0 name=apache2,pod-template-hash=7868df7b76
上記のローリングアップデートをイメージに起こすと以下の様になるかと思います。
まずver1.1のpodの作成が開始されます。まだ作成完了していないので通信先は双方ver1.0のpodになります。
ver1.1のpodの作成が完了すると宛先をそちらに変更し、2つのうち1つのver1.0 podは削除。それと同時にもうひとつver1.1のpodの作成を開始します。
この時、恐らく残ったver1.0にもロードバランシングしていると思います。今後要検証かと。。。
1つ前で作成を開始したver1.1のpodの作成が完了するとver1.0に振られていた宛先をそちらに変更。
役割を終えたver1.0のpodを削除します。
kubectl rollout statusで確認してみます。問題無くローリングアップデートが出来たと書いていますね。
ohtsuka_honban@cloudshell:~/yaml (western-antonym-●●●●●●)$ kubectl rollout status deployment
deployment "apache2-deployment" successfully rolled out
kubectl rollout historyコマンドも見てみます。
過去のものはREVISIONとして管理されているようですね。
REVISION 1がver1.0のもの。2がver1.1のものになります。
ohtsuka_honban@cloudshell:~/yaml (western-antonym-●●●●●●)$ kubectl rollout history deployment
deployment.apps/apache2-deployment
REVISION CHANGE-CAUSE
1 <none>
2 <none>
kubectl diffコマンドを見てみます。
-fでyamlファイルを指定し、そのyamlファイルと現状稼動しているDeploymentの差分を出しているようですね。
現に稼働しているapache2-deployment-1.1.yamlでdiffをかけても何も出力されておりません。
ohtsuka_honban@cloudshell:~/yaml (western-antonym-●●●●●●)$ kubectl diff -f apache2-deployment.yaml
diff -u -N /tmp/LIVE-4004392298/apps.v1.Deployment.default.apache2-deployment /tmp/MERGED-3784003542/apps.v1.Deployment.default.apache2-deployment
--- /tmp/LIVE-4004392298/apps.v1.Deployment.default.apache2-deployment 2023-05-12 23:45:16.669876027 +0000
+++ /tmp/MERGED-3784003542/apps.v1.Deployment.default.apache2-deployment 2023-05-12 23:45:16.670876121 +0000
@@ -7,7 +7,7 @@
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"name":"apache2-deployment"},"name":"apache2-deployment","namespace":"default"},"spec":{"replicas":2,"selector":{"matchLabels":{"name":"apache2"}},"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0}},"template":{"metadata":{"labels":{"name":"apache2"}},"spec":{"containers":[{"image":"gcr.io/western-antonym-●●●●●●/apache2:1.1","name":"apache2-con","ports":[{"containerPort":80}]}]}}}}
creationTimestamp: "2023-05-12T23:25:59Z"
- generation: 2
+ generation: 3
labels:
name: apache2-deployment
name: apache2-deployment
@@ -33,7 +33,7 @@
name: apache2
spec:
containers:
- - image: gcr.io/western-antonym-●●●●●●/apache2:1.1
+ - image: gcr.io/western-antonym-●●●●●●/apache2:1.0
imagePullPolicy: IfNotPresent
name: apache2-con
ports:
ohtsuka_honban@cloudshell:~/yaml (western-antonym-●●●●●●)$ kubectl diff -f apache2-deployment-1.1.yaml
ohtsuka_honban@cloudshell:~/yaml (western-antonym-●●●●●●)$
Webブラウザでアクセスします。ver1.1が表示されていますね。
Dockerfileを使ってイメージを作成し、GCRにpushする(3回目)
端折りますが、htmlを1.2に変更しイメージを作成し、GCRにpushします。
ohtsuka_honban@cloudshell:~/yaml/docker$ cat index.html
<h1>Hello GKE!</h1>
<h2>This is apache2 pod ver1.2!</h2>
ohtsuka_honban@cloudshell:~/yaml/docker$ docker build -t gcr.io/western-antonym-●●●●●●/apache2:1.2 .
ohtsuka_honban@cloudshell:~/yaml/docker$ docker push gcr.io/western-antonym-●●●●●●/apache2:1.2
GKEにDeploymentとLoadBalancerをデプロイし、Webブラウザでindex.htmlを確認する(3回目)
ローリングアップデート用のyamlを用意し、更新をかけます。
ohtsuka_honban@cloudshell:~/yaml$ cp -p apache2-deployment-1.1.yaml apache2-deployment-1.2.yaml
ohtsuka_honban@cloudshell:~/yaml$ vi apache2-deployment-1.2.yaml
ohtsuka_honban@cloudshell:~/yaml$ diff apache2-deployment-1.1.yaml apache2-deployment-1.2.yaml
23c23
< image: gcr.io/western-antonym-●●●●●●/apache2:1.1
---
> image: gcr.io/western-antonym-●●●●●●/apache2:1.2
ohtsuka_honban@cloudshell:~/yaml$ kubectl apply -f apache2-deployment-1.2.yaml
deployment.apps/apache2-deployment configured
途中経過をwatchします。
ver1.2をベースとしたReplicaset"apache2-deployment-8596d9c558"が作成されており、併せてそのReplicaset配下のpod"apache2-deployment-8596d9c558-l6nqr"が作成されています。
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/apache2-deployment-67f8d54489-4hzkj 1/1 Running 0 65m 10.109.128.141 gk3-my-k8s-cluster-pool-1-458925f9-kpcw <none> <none>
pod/apache2-deployment-67f8d54489-v6nnw 1/1 Running 0 65m 10.109.128.142 gk3-my-k8s-cluster-pool-1-458925f9-kpcw <none> <none>
pod/apache2-deployment-8596d9c558-l6nqr 0/1 ContainerCreating 0 95s <none> gk3-my-k8s-cluster-pool-1-09501b89-mjg7 <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/apache2-loadbalancer LoadBalancer 10.110.0.162 35.238.40.41 60080:30377/TCP 78m name=apache2
service/kubernetes ClusterIP 10.110.0.1 <none> 443/TCP 173m <none>
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/apache2-deployment 2/2 1 2 79m apache2-con gcr.io/western-antonym-●●●●●●/apache2:1.2 name=apache2
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
replicaset.apps/apache2-deployment-67f8d54489 2 2 2 69m apache2-con gcr.io/western-antonym-●●●●●●/apache2:1.1 name=apache2,pod-template-hash=67f8d54489
replicaset.apps/apache2-deployment-7868df7b76 0 0 0 79m apache2-con gcr.io/western-antonym-●●●●●●/apache2:1.0 name=apache2,pod-template-hash=7868df7b76
replicaset.apps/apache2-deployment-8596d9c558 1 1 0 96s apache2-con gcr.io/western-antonym-●●●●●●/apache2:1.2 name=apache2,pod-template-hash=8596d9c558
最終的には以下になりました。
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/apache2-deployment-8596d9c558-6hb4b 1/1 Running 0 15s 10.109.128.197 gk3-my-k8s-cluster-pool-1-09501b89-mjg7 <none> <none>
pod/apache2-deployment-8596d9c558-l6nqr 1/1 Running 0 2m14s 10.109.128.194 gk3-my-k8s-cluster-pool-1-09501b89-mjg7 <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/apache2-loadbalancer LoadBalancer 10.110.0.162 35.238.40.41 60080:30377/TCP 79m name=apache2
service/kubernetes ClusterIP 10.110.0.1 <none> 443/TCP 173m <none>
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/apache2-deployment 2/2 2 2 80m apache2-con gcr.io/western-antonym-●●●●●●/apache2:1.2 name=apache2
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
replicaset.apps/apache2-deployment-67f8d54489 0 0 0 69m apache2-con gcr.io/western-antonym-●●●●●●/apache2:1.1 name=apache2,pod-template-hash=67f8d54489
replicaset.apps/apache2-deployment-7868df7b76 0 0 0 80m apache2-con gcr.io/western-antonym-●●●●●●/apache2:1.0 name=apache2,pod-template-hash=7868df7b76
replicaset.apps/apache2-deployment-8596d9c558 2 2 2 2m15s apache2-con gcr.io/western-antonym-●●●●●●/apache2:1.2 name=apache2,pod-template-hash=8596d9c558
遷移をイメージに起こします。
rollout historyを見てみます。REVISIONが1つ増えていますね。
ohtsuka_honban@cloudshell:~/yaml$ kubectl rollout history deployment
deployment.apps/apache2-deployment
REVISION CHANGE-CAUSE
1 <none>
2 <none>
3 <none>
Webブラウザで確認します。
ver1.2になっていますね。
ロールバックをやってみる
kubectl rollout undoコマンドでREVISIONを指定することでそのREVISIONの状態にロールバックすることが出来るようです。実際に試してみます。
今回は2世代前のREVISION 1、つまりver1.0の時に戻してみます。
ohtsuka_honban@cloudshell:~/yaml$ kubectl rollout undo deployment apache2-deployment --to-revision=1
deployment.apps/apache2-deployment rolled back
ohtsuka_honban@cloudshell:~/yaml$ kubectl rollout status deployment
Waiting for deployment "apache2-deployment" rollout to finish: 1 out of 2 new replicas have been updated...
Waiting for deployment "apache2-deployment" rollout to finish: 1 out of 2 new replicas have been updated...
Waiting for deployment "apache2-deployment" rollout to finish: 1 out of 2 new replicas have been updated...
Waiting for deployment "apache2-deployment" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "apache2-deployment" rollout to finish: 1 old replicas are pending termination...
deployment "apache2-deployment" successfully rolled out
ロールバックの結果です。
Replicasのところを見るのが分かりやすいですが、ver1.0のReplicas"apache2-deployment-7868df7b76"が2になっていますね。
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/apache2-deployment-7868df7b76-4lxc5 1/1 Running 0 40s 10.109.128.200 gk3-my-k8s-cluster-pool-1-09501b89-mjg7 <none> <none>
pod/apache2-deployment-7868df7b76-f9cnf 1/1 Running 0 40s 10.109.128.199 gk3-my-k8s-cluster-pool-1-09501b89-mjg7 <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/apache2-loadbalancer LoadBalancer 10.110.0.162 35.238.40.41 60080:30377/TCP 89m name=apache2
service/kubernetes ClusterIP 10.110.0.1 <none> 443/TCP 3h3m <none>
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/apache2-deployment 2/2 2 2 90m apache2-con gcr.io/western-antonym-●●●●●●/apache2:1.0 name=apache2
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
replicaset.apps/apache2-deployment-67f8d54489 0 0 0 79m apache2-con gcr.io/western-antonym-●●●●●●/apache2:1.1 name=apache2,pod-template-hash=67f8d54489
replicaset.apps/apache2-deployment-7868df7b76 2 2 2 90m apache2-con gcr.io/western-antonym-●●●●●●/apache2:1.0 name=apache2,pod-template-hash=7868df7b76
replicaset.apps/apache2-deployment-8596d9c558 0 0 0 12m apache2-con gcr.io/western-antonym-●●●●●●/apache2:1.2 name=apache2,pod-template-hash=8596d9c558
Webブラウザで確認するとver1.0になっていますね。ロールバック完了です。コマンド1つでrollbackできるのは凄いなと思いました。
rollout historyを見てみます。
1が消えて4が出来ましたね。恐らくGKEの設定で3世代管理迄と決まっており、今回ロールバックをしたので、一番古い世代が消えたのでしょう。設定変更もできるっぽい気がします。試してはいませんが。。。
ohtsuka_honban@cloudshell:~/yaml$ kubectl rollout history deployment
deployment.apps/apache2-deployment
REVISION CHANGE-CAUSE
2 <none>
3 <none>
4 <none>