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

CNPE — クラウドネイティブプラットフォームエンジニア

デプロイゲートとプログレッシブデリバリの設計

TT Labで続きを見る

目標

kustomizeのbaseと本番オーバーレイを作り、レンダリング結果にスキーマとポリシーのゲートをかけ、そのゲートが違反を実際に止めるかを確認します。そのあと、カナリアとブルー/グリーンをそれぞれどのServiceに付けるかを決めて、Rolloutに移します。

なぜ重要なのか

CNPEのGitOpsドメインは配点が25%で最も大きいです。そして、このドメインで実務と試験が一緒に求めるのは、ツールの使い方ではなく順序です。レンダリングが先で、検査がそのあとで、検査結果は必ず終了コードになる必要があります。この順序を守らないパイプラインは、緑ランプを出しながら何も守りません。

このラボのクラスターには、Argo CDコントローラーもArgo Rolloutsコントローラーもありません。CRDだけが登録されているので、マニフェストは本当に検証されて保存されますが、調整(reconcile)は起こりません。そのため、ここで学ぶのは「コントローラーが何をしてくれるか」ではなく、自分が何を宣言したかです。実際の試験でも、採点されるのは宣言です。

作業ディレクトリは/root/cnpe-deliveryで、本番ネームスペースはcnpe-prodです。

ステップ

  1. /root/cnpe-delivery/baseにDeploymentcheckoutとServicecheckoutを作り、kustomization.yamlでまとめます。コンテナのポートとServiceのtargetPortは8080、replicasは1です。baseにはネームスペースを入れません。
  2. /root/cnpe-delivery/overlays/prodに本番オーバーレイを作ります。ネームスペースはcnpe-prod、replicasは4、イメージはダイジェスト(@sha256:の後ろの16進数64桁)で固定し、コンテナにrequestsとlimitsをどちらも入れ、runAsNonRoot: trueを設定します。
  3. /root/cnpe-delivery/policy/require-pinned.yamlにKyverno ClusterPolicyを書きます。validationFailureActionはEnforceで、Deploymentを対象に、(ア)イメージがダイジェストで固定されているか、(イ)すべてのコンテナにresources.limits.cpuとmemoryがあるか、の2つを検査します。
  4. /root/cnpe-delivery/gate.shを作ります。prodオーバーレイをレンダリングし、その結果にポリシーを適用して、違反があれば0以外のコードで終了する必要があります。どこから呼び出しても同じように動作するよう、スクリプトが最初に自分の場所へ移動するようにしてください。
  5. /root/cnpe-delivery/rollout/checkout-canary.yamlにカナリアRolloutcheckoutを書き、cnpe-prodに適用します。setWeightは10、30、60の順で、その間ごとにpauseを置き、最初のステップはsetWeightにする必要があります。canaryServiceとstableServiceは互いに異なるものにし、progressDeadlineSecondsは600以下にします。コンテナイメージは、prodのレンダリング結果のイメージと完全に同じである必要があります。
  6. /root/cnpe-delivery/argocd/application.yamlにArgo CD Applicationを書きます。projectはdefaultではない専用プロジェクト、source.pathはoverlays/prod、targetRevisionはHEADではない固定の参照にし、syncPolicy.automatedでpruneとselfHealを有効にして、syncOptionsにCreateNamespace=trueを入れます。destination.namespaceはレンダリング結果のネームスペースと同じである必要があります。
  7. /root/cnpe-delivery/rollout/ledger-bluegreen.yamlにAnalysisTemplateledger-smokeとブルー/グリーンRolloutledgerを書き、cnpe-prodに適用します。activeServiceとpreviewServiceは互いに異なり、autoPromotionEnabledはfalse、prePromotionAnalysisはledger-smokeを参照し、scaleDownDelaySecondsは300以上です。
  8. /root/cnpe-delivery/delivery-report.txtにprod_image、prod_replicas、canary_weights、auto_promotionの4行を키=값の形式(プレースホルダーはキーと値です)で書きます。値はすべて、レンダリング結果とクラスターから直接参照したものである必要があります。

参考

baseを作ってレンダリングできることを確認する

/root/cnpe-delivery/baseにDeploymentcheckoutとServicecheckoutを作り、kustomization.yamlでまとめます。コンテナのポートとServiceのtargetPortは8080、replicasは1です。baseにはネームスペースを入れません。

baseには環境に依存しない共通部分だけを入れます。ネームスペースや環境ごとのreplicasをここに入れると、オーバーレイがそれを上書きするせめぎ合いになります。レンダリングはkustomize buildで直接実行して確認してください。

本番オーバーレイが何を加えるか

/root/cnpe-delivery/overlays/prodに本番オーバーレイを作ります。ネームスペースはcnpe-prod、replicasは4、イメージはダイジェスト(@sha256:の後ろの16進数64桁)で固定し、コンテナにrequestsとlimitsをどちらも入れ、runAsNonRoot: trueを設定します。

kustomizeのimages項目には、newTagではなくdigestを使えます。replicasはreplicas項目で、リソースとセキュリティ設定はpatchesで重ねてください。確認はファイルではなく、kustomize buildの結果で行ってください。

ポリシーで何を止めるか決める

/root/cnpe-delivery/policy/require-pinned.yamlにKyverno ClusterPolicyを書きます。validationFailureActionはEnforceで、Deploymentを対象に、(ア)イメージがダイジェストで固定されているか、(イ)すべてのコンテナにresources.limits.cpuとmemoryがあるか、の2つを検査します。

Kyvernoのvalidate.patternで、*@sha256:*は部分一致、?*は「空でない値」を意味します。ポリシーが広すぎると正常なマニフェストまで止まるため、通るべきものと止まるべきものの両方をテストしてみてください。

ゲートが実際に止めるか確認する

/root/cnpe-delivery/gate.shを作ります。prodオーバーレイをレンダリングし、その結果にポリシーを適用して、違反があれば0以外のコードで終了する必要があります。どこから呼び出しても同じように動作するよう、スクリプトが最初に自分の場所へ移動するようにしてください。

ゲートの本体は検査ではなく、検査結果を終了コードに変換することです。そして、スクリプトがどこから呼び出されても同じように動作するには、最初の行で自分のディレクトリへ移動する必要があります。作ったあとは、わざと違反を入れて赤ランプを一度見てください。

カナリアに判断の場を作る

/root/cnpe-delivery/rollout/checkout-canary.yamlにカナリアRolloutcheckoutを書き、cnpe-prodに適用します。setWeightは10、30、60の順で、その間ごとにpauseを置き、最初のステップはsetWeightにする必要があります。canaryServiceとstableServiceは互いに異なるものにし、progressDeadlineSecondsは600以下にします。コンテナイメージは、prodのレンダリング結果のイメージと完全に同じである必要があります。

重みだけを並べると、少しゆっくりな全面デプロイです。重みの間ごとにpauseを置き、カナリアだけを別に観測できるようにServiceを分けてください。イメージはレンダリング結果からコピーしてくるほうが安全です。

同期の対象と宛先を固定する

/root/cnpe-delivery/argocd/application.yamlにArgo CD Applicationを書きます。projectはdefaultではない専用プロジェクト、source.pathはoverlays/prod、targetRevisionはHEADではない固定の参照にし、syncPolicy.automatedでpruneとselfHealを有効にして、syncOptionsにCreateNamespace=trueを入れます。destination.namespaceはレンダリング結果のネームスペースと同じである必要があります。

このPodにはArgo CDコントローラーがないため、同期の結果ではなく宣言を見ます。ただし、destination.namespaceはレンダリング結果のネームスペースと必ず同じである必要があります。2つの値がずれると、同期は成功するのに、どこにも反映されません。

書き込みを分けられないサービスの戦略

/root/cnpe-delivery/rollout/ledger-bluegreen.yamlにAnalysisTemplateledger-smokeとブルー/グリーンRolloutledgerを書き、cnpe-prodに適用します。activeServiceとpreviewServiceは互いに異なり、autoPromotionEnabledはfalse、prePromotionAnalysisはledger-smokeを参照し、scaleDownDelaySecondsは300以上です。

このステップは、ブルー/グリーンの宣言と分析テンプレートの参照を検査します。プレビュー用Serviceと手動プロモーションは、データの書き込みを遮断しません。実際の元帳では、単一writerの制御・スキーマの互換性・復旧を別に検証する必要があります。ここでは、参照した分析テンプレートも一緒に作り、activeServiceとpreviewServiceを区別してください。

デプロイの記録を値として残す

/root/cnpe-delivery/delivery-report.txtにprod_image、prod_replicas、canary_weights、auto_promotionの4行を키=값の形式(プレースホルダーはキーと値です)で書きます。値はすべて、レンダリング結果とクラスターから直接参照したものである必要があります。

4つの値とも、作り出さずに参照して書いてください。イメージとレプリカはレンダリング結果から、重みと自動プロモーションの有無はクラスターのRolloutから得られます。採点ツールが同じ値を再計算して突き合わせます。