デプロイコマンドの成功と新バージョンの成功は異なる
一言でいうと
APIが新しい宣言を受け入れたという事実、コントローラーがその宣言を観測したという事実、新しいプロセスがリクエストを処理しているという事実は、それぞれ別の証拠です。
なぜ必要なのか
金曜の午後、新バージョンのデプロイコマンドが成功しました。DeploymentのAVAILABLEも2です。ところが、ユーザーは相変わらず古い画面を見ています。デプロイが成功したのだから、ブラウザーのキャッシュの問題だと断定してよいでしょうか。まだです。正常な古いPod2つがリクエストを処理している間に、準備のできていない新しいPod1つが、そばで失敗しているかもしれません。可用性が維持されたという事実は喜ばしいことですが、その事実だけで、新バージョンのデリバリーまで証明することはできません。
クラウドネイティブのデリバリーは、ソースコードをファイルとして移すことでは終わりません。何を実行するかを宣言し、その宣言を実際のプロセスに変え、リクエストを受ける準備ができたかを観察し、失敗したらどの状態に戻すかを決める流れです。CIは変更を統合してテストする過程に焦点を置き、継続的デリバリーは、デプロイ可能な状態を維持することに焦点を置きます。すべての変更を本番に自動で公開する継続的デプロイとも区別します。Gitにコミットがあるという事実は、このうちの一部の記録にすぎず、ユーザーのレスポンスの証拠ではありません。
どう動くのか
Deploymentは、望ましいPodテンプレートとレプリカ数を宣言します。Deploymentコントローラーは、ReplicaSetを作成または調整し、ReplicaSetは必要なPodを維持します。kubeletがコンテナを実行し、readinessが準備の可否を報告すると、Serviceの転送先にもその状態が反映されます。異なる構成要素が、それぞれ収束するので、1回のAPIレスポンスを、全体の作業の完了と読んではいけません。
調査するときは、名前1つよりつながりの関係を見ます。Deployment UIDと、そのオブジェクトを所有者として指すReplicaSet UID、さらにそのReplicaSetを所有者として指すPod UIDを、たどってください。名前が似ているPodを人が直接作っておいた場合を、実際のロールアウトの結果と取り違えずに済みます。新バージョンが起動したかはコンテナの状態と準備条件で、どのバージョンが提供されているかは実際のレスポンスで、別々に確認します。
Deploymentのgenerationは宣言の変化の世代を、status.observedGenerationはコントローラーが観測した世代を、比較するのに使います。両者が同じでも、新バージョンがすべて準備できたという意味ではありません。updatedReplicasは新しいテンプレートに該当するレプリカを、availableReplicasは利用可能の条件を満たしたレプリカを見るのに使います。完了したかどうかは、これらの値と条件、実際のレスポンスをあわせて調べる必要があります。特に、ロールアウト中の利用可能なレプリカには、古いバージョンが含まれることがあります。
kubectl -n kcna-delivery get deployment web -o yaml
kubectl -n kcna-delivery get replicasets
kubectl -n kcna-delivery get pods -l app=web
kubectl -n kcna-delivery get endpointslices
すべての変更が、新しいReplicaSetを作るわけではありません。Deploymentオブジェクト自体の説明用のannotationを変えるのと、spec.templateの中の環境変数を変えるのとでは、位置が違います。このラボは、まずオブジェクトのannotationだけを変えて、既存のPod・ReplicaSet・revisionが維持されるかを確認します。あとでは、テンプレートのRELEASEをv1からv2に変えて、新しいReplicaSetと新しいPodが作られるのを比較します。同じkubectlで要求したかではなく、どの宣言を変えたかが重要です。
設定も、別の境界です。ConfigMapは、秘密ではない設定データを入れるオブジェクトです。ここではcolorの値を、コンテナの環境変数として注入します。ConfigMapのblueをgreenに変えても、すでに実行中のプロセスの環境変数は、自動的には読み直されません。ConfigMap APIはgreenなのに、レスポンスはblueということがありえます。この現象をデータの喪失と断定せず、設定をいつどのような方式で消費したかを確認してください。ファイルボリュームとして投影したり、アプリがAPIを直接読んだりする方式と、環境変数の注入を、同じ更新ルールに一般化してはいけません。
現場での姿
デプロイ状態の画面の緑のランプ1つにいくつもの意味を混ぜると、対応も見当違いの方向に向かいます。GitOpsの同期は、望ましい宣言とクラスターの宣言の一致を説明できますが、新しいアプリの業務リクエストが成功したかどうかは、別の検証が必要です。イメージのタグも同じです。動くタグの文字列が同じだからといって、同じバイトが実行される保証はありません。この実験は、イメージのdigestを固定し、小さな擬似アプリのリリースの環境変数を変えます。実際に新しいイメージをビルドしたり、サプライチェーンの署名を検証したりするラボではありません。
本番では、新バージョンの識別子、エラー率、レイテンシ、必要な業務パスまで確認する必要があります。ここで6回のHTTPレスポンスを読むのは、授業の状態を比較するための標本であって、無停止やサービスレベル目標を統計的に保証する検査ではありません。正常な比較群を保存する理由も、範囲を区別するためです。実験対象の宣言の変化と、クラスター全体の障害を、同じ原因として扱いません。
あとのラボですること
v1・blueが応答するベースラインで、annotationだけを変え、ConfigMapだけをgreenに変えたあと、それぞれPodの身元を比較します。そのあと、v2テンプレートで実際にロールアウトして、新しいPodの応答がgreenになるかを確認します。続く理論は、準備ができないv3が入ってきたときに、既存の応答を守って復旧する境界を説明します。
公式の根拠: Deployment・ConfigMap