Deployment とは
Deployment は複数の ReplicaSet を管理するワークロード リソースです。ReplicaSet のようにスケーリングを行うだけでなく、ローリング アップデートやロールバックなどのバージョン変更を柔軟に行う機能を提供しています。
複数の ReplicaSet = 複数の Pod を管理できる機能ですが、後述するアップデートの機能などが豊富に実装されていることから、単一の Pod だけを利用する場合でも Deployment の利用が推奨されます。
ローリング アップデート
ローリング アップデートの仕組み
ローリング アップデートでは次のような流れで Pod の更新を行います。
- 新しい ReplicaSet を作成
- 新しい ReplicaSet のレプリカ数を徐々に増やす
- 古い ReplicaSet のレプリカ数を徐々に減らす
- 2 と 3 を古い ReplicaSet のレプリカ数が 0 になるまで繰り返す

Deployment のローリング アップデート機能はレプリカ数を徐々に変化させる単純なものですが、Pod がきちんと起動しているかヘルスチェックを自動で行いながら切り替えてくれるため、手動で更新を行うよりも格段に安全です。
なお、このローリング アップデートはレプリカ数の変更では実行されません。イメージの変更など、作成される Pod の内容が変わるような変更のタイミングで実行されます。
更新の際には次の設定で挙動を制御できます。
- spec.strategy: アップデート時の挙動
- Recreate: Pod 更新時に古い ReplicaSet のレプリカ数を 0 にし、新しい ReplicaSet を指定数作成する
- RollingUpdate: 上述のローリング アップデートを実施する
- spec.rollingUpdate:
- maxSurge: 更新時に許容する超過 Pod 数 (%)、未指定の場合は 25 %
- maxUnavailabe: 更新時に不足する超過 Pod 数 (%)、未指定の場合は 25 %
- minReadySeconds: Pod が Ready 状態になってから起動が完了したと判断する最低秒数
- revisionHistoryLimit: ロールバックするために Deployment が保持する ReplicaSet の数
- progressDeadlineSeconds: 更新処理のタイムアウト時間
ロールバックの仕組み
ロールバックもローリング アップデートと同様の流れで行われます。ローリング アップデート時にレプリカ数が 0 となった古い ReplicaSet の情報も過去の履歴として保持されるため、単純にレプリカ数を増減させるだけで指定のバージョンへ戻すことができます。
Deployment のマニフェスト
Deployment のマニフェストは次のようなものです。sample-deployment という名前で、レプリカ数が 3 の nginx コンテナを持つ Pod が作成されます。
apiVersion: apps/v1 kind: Deployment metadata: labels: app: sample-deployment name: sample-deployment spec: replicas: 3 selector: matchLabels: app: sample-deployment template: metadata: labels: app: sample-deployment spec: containers: - image: nginx name: nginx
Deployment のマニフェストは次のようなコマンドをもとにベースを出力できます。
> kubectl create deployment sample-deployment --image=nginx --dry-run=client -o yaml apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: sample-deployment name: sample-deployment spec: replicas: 1 selector: matchLabels: app: sample-deployment strategy: {} template: metadata: creationTimestamp: null labels: app: sample-deployment spec: containers: - image: nginx name: nginx resources: {} status: {}
Deployment の作成
上述のサンプルをもとに Deployment を作成すると、3 つの Pod が作成されます。
> kubectl apply -f sample-deployment.yaml -- deployment.apps/sample-deployment created > kubectl get deployment NAME READY UP-TO-DATE AVAILABLE AGE sample-deployment 3/3 3 3 17s > kubectl get rs NAME DESIRED CURRENT READY AGE sample-deployment-7dfdbd9878 3 3 3 28s > kubectl get po NAME READY STATUS RESTARTS AGE sample-deployment-7dfdbd9878-7tt2z 1/1 Running 0 33s sample-deployment-7dfdbd9878-q67bb 1/1 Running 0 33s sample-deployment-7dfdbd9878-qfmt7 1/1 Running 0 33s
Deployment によって作成された ReplicaSet には、履歴を管理するためのアノテーションが自動で付与されています。
> kubectl describe rs sample-deployment-7dfdbd9878 Name: sample-deployment-7dfdbd9878 Namespace: default Selector: app=sample-deployment,pod-template-hash=7dfdbd9878 Labels: app=sample-deployment pod-template-hash=7dfdbd9878 Annotations: deployment.kubernetes.io/desired-replicas: 3 deployment.kubernetes.io/max-replicas: 4 deployment.kubernetes.io/revision: 1 kubernetes.io/change-cause: kubectl apply --filename=./sample-deployment.yaml --record=true
Deployment の更新
ここで、Pod のイメージを別のバージョンに変えたマニフェストを使って Deployment を更新してみると、ReplicaSet がもう一つ作成され、Pod が更新されていることが伺えます。revision の番号も増加しています。
> kubectl get rs NAME DESIRED CURRENT READY AGE sample-deployment-6458dbd8b7 3 3 3 35s sample-deployment-7dfdbd9878 0 0 0 12m > kubectl get po NAME READY STATUS RESTARTS AGE sample-deployment-6458dbd8b7-8pzvz 1/1 Running 0 8m8s sample-deployment-6458dbd8b7-ddtj9 1/1 Running 0 8m25s sample-deployment-6458dbd8b7-ltccx 1/1 Running 0 8m16s > kubectl describe rs sample-deployment-6458dbd8b7 Name: sample-deployment-6458dbd8b7 Namespace: default Selector: app=sample-deployment,pod-template-hash=6458dbd8b7 Labels: app=sample-deployment pod-template-hash=6458dbd8b7 Annotations: deployment.kubernetes.io/desired-replicas: 3 deployment.kubernetes.io/max-replicas: 4 deployment.kubernetes.io/revision: 2
Deployment のスケーリング
Deployment も scale コマンドでレプリカ数をスケーリングできます。
> kubectl scale deployment sample-deployment --replicas=4 deployment.apps/sample-deployment scaled > kubectl get deployment sample-deployment NAME READY UP-TO-DATE AVAILABLE AGE sample-deployment 4/4 4 4 54m
変更履歴の確認
次のコマンドで Deployment の履歴一覧を確認できます。
kubectl rollout history deployment <Deployment 名>
一覧に表示された番号を指定することで、どのような内容の Pod が作成されるかを確認できます。
kubectl rollout history deployment <Deployment 名> --revision <履歴番号>
> kubectl rollout history deployment sample-deployment --revision 1 deployment.apps/sample-deployment with revision #1 Pod Template: Labels: app=sample-deployment pod-template-hash=7dfdbd9878 Annotations: kubernetes.io/change-cause: kubectl apply --filename=./sample-deployment.yaml --record=true Containers: nginx: Image: nginx Port: <none> Host Port: <none> Environment: <none> Mounts: <none> Volumes: <none>
ロールバックの実行
ロールバックは次のコマンドで実行できます。
kubectl rollout undo deployment <Deployment 名> --to-revision <履歴番号>
> kubectl rollout undo deployment sample-deployment --to-revision 1 deployment.apps/sample-deployment rolled back
また、更新は次のコマンドでそれぞれ一時停止と再開を行えます。
kubectl rollout pause deployment <Deployment 名> kubectl rollout resume deployment <Deployment 名>
コメント