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

CGOA — GitOps認定アソシエイト

設定は変わったのにプロセスはなぜそのままなのか

TT Labで続きを見る

一言でいうと

設定を保存した場所だけでなく、プロセスがその設定をいつ消費するのかまで知って初めて、復旧が完了します。

なぜ必要なのか

業務パスが500を返す設定を見つけました。Gitで200に直し、Argo CDも新しいコミットにSyncedです。 KubernetesのAPIでConfigMapを読むと、確かに新しい値があります。ところがcurlは相変わらず500を受け取ります。 このとき「GitOpsが言うことを聞かない」とPodを削除すると、一時的には問題が消えるかもしれません。しかし、どの設定が どんな過程でプロセスに伝わったのかを見落とすと、次の変更で同じ障害を繰り返します。 元のデータ・伝達されたファイル・実行中のプロセスという3つの層を、まず切り分けて見てみましょう。

どう動くのか

ConfigMapは、KubernetesのAPIに保存された設定データです。消費の方式によって、更新の動作が異なります。 環境変数として注入した値は、既存のプロセスの環境変数を自動では入れ替えません。通常のボリュームとして投影したファイルは 更新されることがありますが、伝わるまでに時間がかかることがあります。ファイルが変わっても、アプリケーションが再び読み込むかどうかは別の問題です。 特に、今回のようにsubPathでファイル1つをマウントしたコンテナは、ConfigMapのその後の更新を受け取りません。 「ConfigMapは自動で更新される」という文を、消費の方式を省略したまま暗記すると、まさにこの実験で間違えます。 公式のConfigMapの更新条件

今回のDeploymentは、nginx.confというファイル1つを/etc/nginx/nginx.confにsubPathでマウントします。 最初の設定のコミットは、ConfigMapのnginx.confだけを直します。Deploymentのspec.templateは保持します。 したがって、新しいPodが作られる理由がありません。以前のPodのUIDとコンテナが残り、コンテナの中で読んだファイルも以前の値で、 HTTPの応答も相変わらず500です。これは単に「キャッシュが遅いからだ」と推測した結果ではなく、ファイルとアイデンティティの比較で 確認した伝達の境界です。やみくもにsleepの時間を延ばしても、この消費の方式は変わりません。

2つ目のコミットは、新しい設定のバイト列のSHA-256を計算して、Podテンプレートのchecksum/configアノテーションに入れます。 このアノテーション名にKubernetesの組み込みの魔法があるわけではありません。spec.templateの値が変わることで、Deploymentが新しい ReplicaSetとPodを作るようにする約束事です。チェックサムをDeploymentの最上位のmetadataにだけ付けても、テンプレートが 変わらないので、同じ効果は得られません。新しいPodは現在のConfigMapでマウントを作り、nginxを起動します。 ConfigMapだけを変えたコミットと、テンプレートまで変えたコミットを分けておけば、この違いを目で追えます。 公式のDeploymentの更新

チェックサムは、文字列を目分量で書く値ではありません。実際の設定のバイト列を計算する必要があり、最後の改行の有無も 結果を変えます。今回のヘルパーは、保存したConfigMapの観測のnginx.confの値をそのままエンコードして計算します。 実際の運用では、設定ファイルとテンプレートの生成パイプラインが、同じルールを共有する必要があります。別のファイルのチェックサムや 任意のタイムスタンプでもロールアウトを引き起こせますが、それは私たちがどの設定をデプロイしたのかを説明する根拠にはなりません。

現場での姿

応急処置と恒久的な復旧を区別する必要があります。手動でPodを削除して新しい設定を読ませることはできても、その処置は 望ましいデプロイ状態と変更の意図をGitに残しません。selfHealが有効なリソースへの直接の修正は、Gitの状態に 再び調整されることがあります。このラボでは、プラットフォームの運用設定を変えず、受講生専用のリポジトリの2つのコミットで 復旧の過程を残します。自動同期はあらゆる誤った設定を直す機能ではなく、人によるレビューとテストが必要です。 公式の自動同期

ロールアウトの完了の確認にも、名前だけでは足りません。新しいPodのUIDは変わっている必要がありますが、ApplicationとDeploymentは 同じUIDを維持している必要があります。以前のPodを削除してから、同じ名前でリソースを丸ごと作り直したのは、同じ復旧の過程では ありません。望ましいテンプレートのチェックサム、observedGeneration、updatedReplicas、Ready、新しいPodの中のファイル、実際の応答を 一緒に確認して初めて、「新しい設定を読んだ新しいプロセスが応答した」という主張ができます。

このラボのステップごとのJSONは、レポートを書く手間を省くための学習資料です。元のデータとハッシュを保存して、うっかり以前の観測を 上書きすると失敗するようにしてありますが、同じVMのrootがすべてのファイルを変更できるという限界は残ります。ハッシュがあるからといって、 リモートの証明や、改ざんできない監査システムとは呼びません。運用の監査であれば、信頼の境界の外に送るログと アクセス制御、保存ポリシーを別に設計する必要があります。

次のラボですること

設定の変更の前後と、テンプレートの変更後を、それぞれ保存します。真ん中の観測のConfigMapは新しい値なのに、マウントされたファイルと応答は 古い値なのかを調べてください。最後に、Gitコミットの親子関係までたどって2つの変更を区別し、新しいPodの200の応答を 確認します。過去のステップの再採点は、過去の記録を読むべきで、障害を再び注入してはいけません。現在の状態の確認も一緒に 通ったときに、調査の範囲内での復旧を宣言し、外部経路と継続的な観測は、残りの作業として記録します。