緑ランプなのに根拠を誰も知らない — ヘルス判定を自分で書く
目標
argocd-cmのresource.customizations.health.<그룹>_<종류>にLuaのルールを書いて、CRDのヘルスをHealthy・Progressing・Degraded・Suspendedの4つの欄に分け、サンプルと期待値を表にまとめて回帰チェックします(プレースホルダーは、順にグループと種類です)。
なぜ重要なのか
Argo CDの画面で人が実際に見ているのは、同期ではなくヘルスです。Deployment・Service・Jobのような組み込みの種類は、コントローラーが自動で判定しますが、CRDには組み込みのルールがありません。Operatorが作るリソースが画面でいつも同じ色に見えるなら、それはうまくいっているという意味ではなく、判定する根拠がないという意味です。ルールを自分で書くことが重要な理由は2つです。1つ目は、まだ作られている途中のものと、すでに壊れているものを分けて初めて、アラートを設定できることです。2つ目は、ルールは一度書くと忘れられるコードなので、サンプルと期待値を一緒にリポジトリに置いておかないと、あとでstatusフィールドが変わったときに、静かに間違うことです。
ステップ
/root/ga-health/argocd-cm.yamlをdata: {}の空のargocd-cm ConfigMapとして作り、/root/ga-health/deploy.yamlにga-healthネームスペースのDeploymentwebを置いてください。spec.replicasは3で、statusにはobservedGeneration: 1、replicas: 3、updatedReplicas: 2、readyReplicas: 1、availableReplicas: 1を書きます。argocd admin settings resource-overrides health /root/ga-health/deploy.yaml --argocd-cm-path /root/ga-health/argocd-cm.yamlの出力を、/root/ga-health/builtin.txtに保存してください。/root/ga-health/w-ready.yamlにexample.com/v1のWidgetを作ってください。名前はw-ready、ネームスペースはga-health、spec.sizeは3、status.phaseはReadyです。ステップ1の空のargocd-cmで、このファイルのヘルスを尋ねて、出力を/root/ga-health/nocustom.txtに保存してください。/root/ga-health/argocd-cm-healthy.yamlにキーresource.customizations.health.example.com_Widgetを置いて、status.phaseがReadyならHealthyを、それ以外はProgressingを返すLuaを書いてください。どちらの場合もhs.messageを埋めます。/root/ga-health/w-ready.yamlをこのConfigMapで判定した出力を、/root/ga-health/healthy.txtに保存してください。/root/ga-health/w-failed.yamlを作ってください。名前はw-failed、status.phaseはFailed、status.reasonはDiskFullです。/root/ga-health/argocd-cm-degraded.yamlは、ステップ3のルールにFailedの分岐を加えて、Degradedを返すようにしてください。ただし、hs.messageの中に、そのリソースのstatus.reasonの値が入る必要があります。判定の出力を/root/ga-health/degraded.txtに保存してください。/root/ga-health/w-building.yaml(status.phaseがBuilding、名前w-building)と、/root/ga-health/w-nostatus.yaml(status自体がない、名前w-nostatus)を作ってください。ステップ4のConfigMapで、2つを順に判定して、出力を/root/ga-health/progressing.txtに追記してください。どちらもProgressingである必要があります。/root/ga-health/w-paused.yamlを作ってください。名前はw-paused、spec.pausedはtrue、status.phaseはReadyです。/root/ga-health/argocd-cm-full.yamlは、前のルールに分岐を1つ加えて、spec.pausedが真ならほかの条件より先にSuspendedを返す必要があります。判定の出力を/root/ga-health/suspended.txtに保存してください。/root/ga-health/argocd-cm-typo.yamlを作ってください。ステップ6と内容は同じですが、キー名だけをresource.customizations.health.example.com_Widgets(種類を複数形に)にします。このConfigMapで/root/ga-health/w-ready.yamlを判定した出力を、/root/ga-health/typo.txtに保存してください。/root/ga-health/health-matrix.tsvに<샘플파일이름>\t<기대 STATUS>を4行以上書いてください。Healthy・Degraded・Progressing・Suspendedが、すべて1回以上出る必要があります。/root/ga-health/check-health.shは、この表を読んで/root/ga-health/argocd-cm-full.yamlで各サンプルを判定し、合っていればOK …、違っていればMISMATCH …を標準出力にだけ出力して、1行でも違えば0以外のコードで終了する必要があります。その出力を/root/ga-health/health-result.txtに保存してください(プレースホルダーは、順にサンプルファイル名と期待するSTATUSです)。
参考
- Luaの断片は、
objでリソースを受け取り、hs.status・hs.messageを埋めたテーブルをreturnします。 - ヘルス状態の名前は、Healthy、Progressing、Degraded、Suspended、Missing、Unknownです。
- キー名の区切り文字は、ドットではなくアンダースコアです。
resource.customizations.health.<그룹>_<종류>です(プレースホルダーは、順にグループと種類です)。 - よくあるミスは、statusがない瞬間を抜かして、新しく作ったリソースが毎回赤信号で始まることです。
- よくあるミスは、種類の名前を複数形で書くことです。エラーが出ず、ルールがないかのように動作します。
- 参考: https://argo-cd.readthedocs.io/en/stable/operator-manual/health/
まず組み込みの判定を見る
/root/ga-health/argocd-cm.yamlをdata: {}の空のargocd-cm ConfigMapとして作り、/root/ga-health/deploy.yamlにga-healthネームスペースのDeploymentwebを置いてください。spec.replicasは3で、statusにはobservedGeneration: 1、replicas: 3、updatedReplicas: 2、readyReplicas: 1、availableReplicas: 1を書きます。argocd admin settings resource-overrides health /root/ga-health/deploy.yaml --argocd-cm-path /root/ga-health/argocd-cm.yamlの出力を、/root/ga-health/builtin.txtに保存してください。
Deploymentには組み込みのヘルスルールがあるので、argocd-cmが空でも判定が出ます。3つを望んでいるのに、1つしか準備できていないので、どんな状態で出るか予想してみてください。出力の最初の行がSTATUSです。
CRDにはルールがそもそもない
/root/ga-health/w-ready.yamlにexample.com/v1のWidgetを作ってください。名前はw-ready、ネームスペースはga-health、spec.sizeは3、status.phaseはReadyです。ステップ1の空のargocd-cmで、このファイルのヘルスを尋ねて、出力を/root/ga-health/nocustom.txtに保存してください。
Argo CDは、自分が知らない種類について、判定をでっち上げません。画面では、こうしたリソースはたいてい緑に見えますが、実際には「判定する根拠がない」という意味です。出力の文をそのまま読んでみてください。
緑の条件をLuaで書く
/root/ga-health/argocd-cm-healthy.yamlにキーresource.customizations.health.example.com_Widgetを置いて、status.phaseがReadyならHealthyを、それ以外はProgressingを返すLuaを書いてください。どちらの場合もhs.messageを埋めます。/root/ga-health/w-ready.yamlをこのConfigMapで判定した出力を、/root/ga-health/healthy.txtに保存してください。
Luaの断片は、objというグローバル変数でリソースを受け取り、hs.statusとhs.messageを埋めたテーブルをreturnします。statusがまったくないリソースも入ってくるので、obj.status ~= nilを先に確認してください。キー名の区切り文字は、ドットではなくアンダースコアです。<그룹>_<종류>です(プレースホルダーは、順にグループと種類です)。
赤信号には理由も一緒に出る必要がある
/root/ga-health/w-failed.yamlを作ってください。名前はw-failed、status.phaseはFailed、status.reasonはDiskFullです。/root/ga-health/argocd-cm-degraded.yamlは、ステップ3のルールにFailedの分岐を加えて、Degradedを返すようにしてください。ただし、hs.messageの中に、そのリソースのstatus.reasonの値が入る必要があります。判定の出力を/root/ga-health/degraded.txtに保存してください。
メッセージを固定文字列で書くと、どのリソースがなぜ落ちたのか、画面でわかりません。Luaの文字列の連結は..で、値がない場合もあるので、(obj.status.reason or "unknown")のようにデフォルト値を置きます。
知らない状態と状態がないものは、同じ欄に送る
/root/ga-health/w-building.yaml(status.phaseがBuilding、名前w-building)と、/root/ga-health/w-nostatus.yaml(status自体がない、名前w-nostatus)を作ってください。ステップ4のConfigMapで、2つを順に判定して、出力を/root/ga-health/progressing.txtに追記してください。どちらもProgressingである必要があります。
ルールを書くときに抜かしやすいのが、「まだコントローラーがstatusを書いていない瞬間」です。このときDegradedを出すと、新しく作ったリソースが毎回赤信号で始まります。デフォルトの分岐をProgressingにしておく理由です。
わざと止めておいたものは故障ではない
/root/ga-health/w-paused.yamlを作ってください。名前はw-paused、spec.pausedはtrue、status.phaseはReadyです。/root/ga-health/argocd-cm-full.yamlは、前のルールに分岐を1つ加えて、spec.pausedが真ならほかの条件より先にSuspendedを返す必要があります。判定の出力を/root/ga-health/suspended.txtに保存してください。
Suspendedは、Argo CDが知っている4番目のヘルス状態です。人がわざと止めておいたものなので、アラートを鳴らしてはいけない場所です。分岐の順序を入れ替えてみれば、なぜ一番前でなければならないかがすぐにわかります(phaseがReadyなので、緑のほうが先に当てはまります)。
キー名を1文字間違えると、ルールがまるごと消える
/root/ga-health/argocd-cm-typo.yamlを作ってください。ステップ6と内容は同じですが、キー名だけをresource.customizations.health.example.com_Widgets(種類を複数形に)にします。このConfigMapで/root/ga-health/w-ready.yamlを判定した出力を、/root/ga-health/typo.txtに保存してください。
キー名の種類は、マニフェストのkindと文字どおり同じである必要があります。間違えるとエラーは出ず、単にルールがないかのように動作します。このようなミスは、画面を見て初めてわかります。ステップ2の出力と比べてみてください。
サンプルと期待値を表にまとめて、ルールを回帰チェックする
/root/ga-health/health-matrix.tsvに<샘플파일이름>\t<기대 STATUS>を4行以上書いてください。Healthy・Degraded・Progressing・Suspendedが、すべて1回以上出る必要があります。/root/ga-health/check-health.shは、この表を読んで/root/ga-health/argocd-cm-full.yamlで各サンプルを判定し、合っていればOK …、違っていればMISMATCH …を標準出力にだけ出力して、1行でも違えば0以外のコードで終了する必要があります。その出力を/root/ga-health/health-result.txtに保存してください(プレースホルダーは、順にサンプルファイル名と期待するSTATUSです)。
サンプルファイルの名前だけを書いて、パスはスクリプトが付ければ、表が短くなります。STATUSの1行だけを取り出すなら、sed -n 's/^STATUS: //p'が楽です。スクリプトがファイルを直接書くと、採点ツールが再実行するときに学習者の成果物を上書きするので、標準出力にだけ出してください。