TT Lab
はじめる
学ぶ 学習パス コース

CKAD — Kubernetesアプリケーション開発者

ローリングアップデート、切り戻し、ブルーグリーン、カナリア

TT Labで続きを見る

目標

Deploymentのロールアウトのパラメーターを調整し、リビジョンを積み重ねて目的の時点に戻し、ブルーグリーンとカナリアをラベル・セレクター・レプリカだけで構成できるようになります。

なぜ重要なのか

DeploymentがReplicaSetを複数管理するという事実を理解すれば、残りはすべて自然にわかります。イメージを変えると新しいReplicaSetが作られ、古いものはレプリカ0のまま残ります。rollout undoが即座に効く理由は、イメージを再取得するのではなく、すでにあるReplicaSetを再びスケールアップするからです。revisionHistoryLimitを0にすると、その安全網が失われます。

maxSurgeとmaxUnavailableは、「どれだけ速いか」と「どれだけ安全か」のトレードオフです。maxUnavailable: 0はデプロイ中も利用可能なPod数を維持しますが、新しいPodがReadyになるまで待つ必要があるので遅くなります。そして、この安全装置はReadiness Probeがあって初めて意味を持ちます。プローブがないと、コンテナが起動した直後にReadyとみなされます。

ブルーグリーンとカナリアは、別途CRDを使わずにラベルだけで作れます。違いはServiceセレクターの狭さです。セレクターにバージョンのラベルまで入れると片方だけが受け取り(ブルーグリーン)、共通のラベルだけを入れると両方が入ってきて、個数の比率どおりに分かれます(カナリア)。

ステップ

  1. ネームスペースckad-deployを作成し、Deployment webを作成してください。イメージはnginx:1.25、レプリカは4です。(コンテナ名はnginxになります。)
  2. webの戦略をRollingUpdateにして、maxSurge: 1、maxUnavailable: 0を設定してください。
  3. webのイメージをnginx:1.26に更新し、Deploymentにアノテーションkubernetes.io/change-cause=nginx 1.26 으로 업데이트を付けてください(韓国語で「nginx 1.26へ更新」を意味する文です)。
  4. webのイメージをnginx:1.27にもう一度更新し、アノテーションをkubernetes.io/change-cause=nginx 1.27 으로 업데이트で更新してください(韓国語で「nginx 1.27へ更新」を意味する文です)。この時点でReplicaSetが3つ以上存在している必要があります。
  5. webをリビジョン2に戻してください。戻すことも前に進む変更なので、リビジョン4が新しく作成され、そのリビジョンのイメージはnginx:1.26になっている必要があります。
  6. ブルーグリーンを作成してください。Deployment checkout-blue(レプリカ2、ラベルapp=checkoutとversion=blue、イメージnginx:1.26)とcheckout-green(レプリカ2、ラベルapp=checkoutとversion=green、イメージnginx:1.27)を作成し、Service checkout(ポート80、targetPort 80)のセレクターをapp=checkout + version=greenにしてください。
  7. カナリアを作成してください。Deployment pay-stable(レプリカ9、ラベルapp=payとtrack=stable、イメージnginx:1.26)とpay-canary(レプリカ1、ラベルapp=payとtrack=canary、イメージnginx:1.27)を作成し、Service pay(ポート80、targetPort 80)のセレクターはapp=payだけを指定してください。
  8. webにkubectl rollout pauseを先にかけてから、イメージをnginx:1.28に変更し、revisionHistoryLimitを3に設定してください。一時停止の状態なので、新しいReplicaSetは作成されないはずです。(再開しないでください。レプリカ4はそのままにしてください。)

参考

ネームスペースとDeploymentを作成する

ネームスペースckad-deployを作成し、Deployment webを作成してください。イメージはnginx:1.25、レプリカは4です。(コンテナ名はnginxになります。)

kubectl create deploymentに--imageと--replicasを指定します。作成されたDeploymentのラベルとセレクターが何かを確認しておいてください。あとのステップで使います。

ローリングアップデートのパラメーターを調整する

webの戦略をRollingUpdateにして、maxSurge: 1、maxUnavailable: 0を設定してください。

spec.strategy.rollingUpdateの下に2つの値があります。kubectl editで編集するか、kubectl patchにJSONを渡せば設定できます。maxUnavailable: 0は、デプロイ中も元の個数を維持するという意味です。

イメージを更新してchange-causeを記録する

webのイメージをnginx:1.26に更新し、Deploymentにアノテーションkubernetes.io/change-cause=nginx 1.26 으로 업데이트を付けてください(韓国語で「nginx 1.26へ更新」を意味する文です)。

kubectl set image deployment/이름 컨테이너=이미지の形式です(プレースホルダーはDeployment名とコンテナ名、イメージです)。コンテナ名を正確に書く必要があります。CHANGE-CAUSEは、kubernetes.io/change-causeアノテーションで直接付けます。

もう一度更新してリビジョンを積み重ねる

webのイメージをnginx:1.27にもう一度更新し、アノテーションをkubernetes.io/change-cause=nginx 1.27 으로 업데이트で更新してください(韓国語で「nginx 1.27へ更新」を意味する文です)。この時点でReplicaSetが3つ以上存在している必要があります。

リビジョンはReplicaSetとして残ります。kubectl get rs -n <ns>でいくつたまったか、kubectl rollout historyでリビジョン番号がどこまで進んだかを確認します。

特定のリビジョンに戻す

webをリビジョン2に戻してください。戻すことも前に進む変更なので、リビジョン4が新しく作成され、そのリビジョンのイメージはnginx:1.26になっている必要があります。

kubectl rollout undoに--to-revision=번호を指定します(プレースホルダーは番号です)。戻してもリビジョン番号は減らず、新しい番号が付きます。どのリビジョンがどのイメージだったかは、kubectl rollout history --revision=Nで確認します。

ブルーグリーン: Serviceセレクターの切り替え

ブルーグリーンを作成してください。Deployment checkout-blue(レプリカ2、ラベルapp=checkoutとversion=blue、イメージnginx:1.26)とcheckout-green(レプリカ2、ラベルapp=checkoutとversion=green、イメージnginx:1.27)を作成し、Service checkout(ポート80、targetPort 80)のセレクターをapp=checkout + version=greenにしてください。

2つのDeploymentは、共通のラベル1つと、互いに異なるバージョンのラベルを持ちます。Serviceのセレクターにバージョンのラベルまで入れると、そちらだけがエンドポイントに入ります。Serviceを作成したあと、セレクターだけを変えてみるのが、このパターンのすべてです。

カナリア: レプリカの比率でトラフィックを分ける

カナリアを作成してください。Deployment pay-stable(レプリカ9、ラベルapp=payとtrack=stable、イメージnginx:1.26)とpay-canary(レプリカ1、ラベルapp=payとtrack=canary、イメージnginx:1.27)を作成し、Service pay(ポート80、targetPort 80)のセレクターはapp=payだけを指定してください。

カナリアは逆に、Serviceのセレクターを共通のラベルだけに絞って、2つのDeploymentのPodがどちらも入るようにします。すると、トラフィックの比率がレプリカ数の比率になります。各Deploymentには、区別するためのラベルを別に付けます。

一時停止の状態で変更をためる(総合)

webにkubectl rollout pauseを先にかけてから、イメージをnginx:1.28に変更し、revisionHistoryLimitを3に設定してください。一時停止の状態なので、新しいReplicaSetは作成されないはずです。(再開しないでください。レプリカ4はそのままにしてください。)

kubectl rollout pauseを先にかけると、以降のテンプレートの変更はすぐには新しいReplicaSetを作らず、たまっていきます。順序が逆だと、ロールアウトがすでに始まっています。保管する以前のReplicaSetの個数を決めるフィールドも、一緒に設定します。