いつも OutOfSync なので無視したら本物のドリフトも見えなくなった
目標
argocd-cmとApplicationの2か所の無視ルールを自分で書いて、ルールが実際にどの行を比較から除くかを、CLIのdiffで確認します。広すぎる無視をしたときに何が一緒に消えるかを、目で見ます。
なぜ重要なのか
自動同期を有効にすると、すぐに「常にOutOfSync」に出会います。HPAが変えたreplicas、Webhookが差し込んだサイドカー、コントローラーが付けたアノテーションのように、リポジトリに書けないのにクラスターには必ず生まれるもののためです。無視ルールはこれを扱う道具ですが、ここには一方にだけ傾く力があります。広く無視すれば画面が静かになり、狭く無視すればずっと騒がしいままです。そのため、誰もが広いほうへ行きます。広いルールの代償は、すぐには見えません。数か月後、誰かが手でイメージを変えても誰も気づかない日になって、ようやく表に出ます。ルールを推測で書かず、「このルールが消す行」を目で確認してからコミットする習慣が、この代償を防ぎます。
ステップ
/root/ga-ignore/live.yamlにga-ignoreネームスペースのDeploymentwebを作ってください。spec.replicasは4、コンテナはapp(イメージnginx:1.25)とsidecar(イメージenvoy:1.31)の2つ、metadata.annotationsにdeployment.kubernetes.io/revision: "7"を置きます。/root/ga-ignore/argocd-cm.yamlは、data: {}の空のConfigMapです。argocd admin settings resource-overrides ignore-differences /root/ga-ignore/live.yaml --argocd-cm-path /root/ga-ignore/argocd-cm.yamlの出力を、/root/ga-ignore/none.txtに保存してください。/root/ga-ignore/argocd-cm-pointer.yamlにキーresource.customizations.ignoreDifferences.apps_Deploymentを置いて、jsonPointersで/spec/replicasだけを無視するようにしてください。/root/ga-ignore/live.yamlに対する出力を、/root/ga-ignore/pointer.txtに保存してください。/root/ga-ignore/argocd-cm-jq.yamlに、jqPathExpressions1つで、名前がsidecarのコンテナのimageだけを無視するようにしてください。出力を/root/ga-ignore/jq.txtに保存します。appコンテナのイメージは除かれてはいけません。/root/ga-ignore/argocd-cm-both.yaml1つに、jsonPointers(/spec/replicas)とjqPathExpressions(sidecarのイメージ)を一緒に置き、出力を/root/ga-ignore/both.txtに保存してください。両方が除かれ、appコンテナのイメージは残る必要があります。/root/ga-ignore/argocd-cm-wide.yamlに、jsonPointersで/specをまるごと無視させて、出力を/root/ga-ignore/wide.txtに保存してください。この出力には、コンテナのイメージの行まで入っています。つまり、誰かがイメージをこっそり変えても、比較に引っかからないという意味です。/root/ga-ignore/argocd-cm-mfm.yamlに、managedFieldsManagersにkubectlだけを置いて、出力を/root/ga-ignore/mfm-only.txtに保存してください。続けて、/root/ga-ignore/argocd-cm-mfm2.yamlに、同じmanagedFieldsManagersとjsonPointers(/metadata/annotations)を一緒に置いて、出力を/root/ga-ignore/mfm-plus.txtに保存してください。2つの出力がどう違うかを見てください。/root/ga-ignore/argocd-cm-updates.yaml1枚に、キーを2つ置いてください。resource.customizations.ignoreDifferences.apps_DeploymentはjsonPointersで/spec/replicasを、resource.customizations.ignoreResourceUpdates.apps_DeploymentはjsonPointersで/metadata/annotationsを無視します。同じファイルに対して、ignore-differencesの出力を/root/ga-ignore/updates-diff.txtに、ignore-resource-updatesの出力を/root/ga-ignore/updates-upd.txtに保存してください。/root/ga-ignore/application.yamlにApplicationga-ignore-web(ネームスペースargocd、プロジェクトdefault)を作って、kwokクラスターに適用してください。spec.ignoreDifferencesに、groupapps、kindDeploymentの項目を1つ置いて、その中に/spec/replicasのポインターと、sidecarのイメージを選ぶjq式を一緒に入れます。そして/root/ga-ignore/ignore-matrix.tsvに、<ConfigMap파일>\t<찾을 글자>\t<yes|no>を4行以上書き、/root/ga-ignore/check-ignore.shですべてを検査して、出力を/root/ga-ignore/ignore-result.txtに保存してください(プレースホルダーは、順にConfigMapのファイルと探す文字です)。スクリプトは標準出力にだけ書き、1行でも違えば0以外のコードで終了する必要があります。
参考
- キー名は
resource.customizations.ignoreDifferences.<그룹>_<종류>で、区切り文字はアンダースコアです(プレースホルダーは、順にグループと種類です)。 - 出力で
<で始まる行が、比較から除かれる行です。 - 配列の要素を条件で選ぶには、jqPathExpressionsを使います。JSONポインターは位置の番号だけを指します。
- よくあるミスは、1つの種類にルールブロックを2回書くことです。キーが重なって、あとのものだけが残ります。
- よくあるミスは、OutOfSyncをなくそうとして
/specをまるごと無視することです。 - 参考: https://argo-cd.readthedocs.io/en/stable/user-guide/diffing/
ルールがないときの出力から見る
/root/ga-ignore/live.yamlにga-ignoreネームスペースのDeploymentwebを作ってください。spec.replicasは4、コンテナはapp(イメージnginx:1.25)とsidecar(イメージenvoy:1.31)の2つ、metadata.annotationsにdeployment.kubernetes.io/revision: "7"を置きます。/root/ga-ignore/argocd-cm.yamlは、data: {}の空のConfigMapです。argocd admin settings resource-overrides ignore-differences /root/ga-ignore/live.yaml --argocd-cm-path /root/ga-ignore/argocd-cm.yamlの出力を、/root/ga-ignore/none.txtに保存してください。
ルールが1つもなければ、このコマンドは判定をでっち上げず、「設定されていない」と言います。あとのステップが、このファイル1つをずっと材料に使うので、値を正確に合わせておいてください。
フィールドを1つ指して取り除く
/root/ga-ignore/argocd-cm-pointer.yamlにキーresource.customizations.ignoreDifferences.apps_Deploymentを置いて、jsonPointersで/spec/replicasだけを無視するようにしてください。/root/ga-ignore/live.yamlに対する出力を、/root/ga-ignore/pointer.txtに保存してください。
JSONポインターは、スラッシュで降りていくパスです。出力の<で始まる行が、「比較から除かれる行」です。replicasの1行だけが除かれ、コンテナのイメージはそのまま残る必要があります。
配列から条件で選ぶのはjqだけができる
/root/ga-ignore/argocd-cm-jq.yamlに、jqPathExpressions1つで、名前がsidecarのコンテナのimageだけを無視するようにしてください。出力を/root/ga-ignore/jq.txtに保存します。appコンテナのイメージは除かれてはいけません。
JSONポインターは、配列を位置の番号でしか指せないので、順序が変わると見当違いの要素を無視してしまいます。jq式なら、select(.name == "sidecar")のように条件で選べます。式は.spec.template.spec.containers[]から始めてください。
2つの方式を1つのルールで一緒に使う
/root/ga-ignore/argocd-cm-both.yaml1つに、jsonPointers(/spec/replicas)とjqPathExpressions(sidecarのイメージ)を一緒に置き、出力を/root/ga-ignore/both.txtに保存してください。両方が除かれ、appコンテナのイメージは残る必要があります。
1つの種類に対するルールブロックは1つで、その中に2つのリストが並んで入ります。ルールを種類ごとに複数のブロックに分けようとすると、キーが重なって、あとのものだけが残ります。
広く無視しすぎると、ドリフトが永遠に見えなくなる
/root/ga-ignore/argocd-cm-wide.yamlに、jsonPointersで/specをまるごと無視させて、出力を/root/ga-ignore/wide.txtに保存してください。この出力には、コンテナのイメージの行まで入っています。つまり、誰かがイメージをこっそり変えても、比較に引っかからないという意味です。
OutOfSyncをなくす最も速い方法は広く無視することで、そのため、現場で最もよく犯すミスでもあります。ステップ4の出力と、この出力で、nginxという文字が見えるかを比べてみてください。
マネージャー名で無視するルールは、プレビューできない
/root/ga-ignore/argocd-cm-mfm.yamlに、managedFieldsManagersにkubectlだけを置いて、出力を/root/ga-ignore/mfm-only.txtに保存してください。続けて、/root/ga-ignore/argocd-cm-mfm2.yamlに、同じmanagedFieldsManagersとjsonPointers(/metadata/annotations)を一緒に置いて、出力を/root/ga-ignore/mfm-plus.txtに保存してください。2つの出力がどう違うかを見てください。
このルールは、「どのフィールド」ではなく、「誰が書いたフィールド」で、無視する対象を決めます。そのため、リソースのYAMLだけを見ても何が除かれるかを計算できず、プレビューのコマンドも、このリストだけでは何もレンダリングできません。
同期の判定と調整ループを起こすことは、別のノブ
/root/ga-ignore/argocd-cm-updates.yaml1枚に、キーを2つ置いてください。resource.customizations.ignoreDifferences.apps_DeploymentはjsonPointersで/spec/replicasを、resource.customizations.ignoreResourceUpdates.apps_DeploymentはjsonPointersで/metadata/annotationsを無視します。同じファイルに対して、ignore-differencesの出力を/root/ga-ignore/updates-diff.txtに、ignore-resource-updatesの出力を/root/ga-ignore/updates-upd.txtに保存してください。
2つのキーは、目的が違います。前のものは「この差はOutOfSyncとして数えない」、あとのものは「この変更では調整ループを起こさない」です。あとのものは、コントローラーの負荷を減らすノブなので、同期の判定を変えません。2つの出力がどう違うかを、そのまま記録してください。
アプリ1つにだけ掛かるルールと回帰チェック
/root/ga-ignore/application.yamlにApplicationga-ignore-web(ネームスペースargocd、プロジェクトdefault)を作って、kwokクラスターに適用してください。spec.ignoreDifferencesに、groupapps、kindDeploymentの項目を1つ置いて、その中に/spec/replicasのポインターと、sidecarのイメージを選ぶjq式を一緒に入れます。そして/root/ga-ignore/ignore-matrix.tsvに、<ConfigMap파일>\t<찾을 글자>\t<yes|no>を4行以上書き、/root/ga-ignore/check-ignore.shですべてを検査して、出力を/root/ga-ignore/ignore-result.txtに保存してください(プレースホルダーは、順にConfigMapのファイルと探す文字です)。スクリプトは標準出力にだけ書き、1行でも違えば0以外のコードで終了する必要があります。
グローバルなルール(argocd-cm)はすべてのアプリに掛かり、Applicationのルールはそのアプリにだけ掛かります。2つはマージされて適用されるので、グローバルに広く掛けておいて、アプリで絞ることは不可能です。絞る方向は、最初からアプリの側に置く必要があります。表には、argocd-cm-wide.yamlとnginxのように、「このルールがこの文字を消すか」を確認する行を混ぜてください。