Deployment 概要

Kubernetes
スポンサーリンク
スポンサーリンク

Deployment とは

Deployment は複数の ReplicaSet を管理するワークロード リソースです。ReplicaSet のようにスケーリングを行うだけでなく、ローリング アップデートやロールバックなどのバージョン変更を柔軟に行う機能を提供しています。

複数の ReplicaSet = 複数の Pod を管理できる機能ですが、後述するアップデートの機能などが豊富に実装されていることから、単一の Pod だけを利用する場合でも Deployment の利用が推奨されます。

ローリング アップデート

ローリング アップデートの仕組み

ローリング アップデートでは次のような流れで Pod の更新を行います。

  1. 新しい ReplicaSet を作成
  2. 新しい ReplicaSet のレプリカ数を徐々に増やす
  3. 古い ReplicaSet のレプリカ数を徐々に減らす
  4. 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 名>

コメント

タイトルとURLをコピーしました