argocd app diff の仕組みを理解する
はじめに
Argo CD でアプリケーションの差分 (diff) を確認する場合は、以下のいくつかの方法があります:
-
argocd app diff <アプリ名>
- Git リポジトリなどの「
spec.source
」を参照し、リポジトリサーバーでマニフェストを生成 - 実行中のリソース(live state)と比較して差分を出力
- Git リポジトリなどの「
-
argocd app diff --local /path/to/local
- ユーザーのローカルマシンに存在するファイルを使って、差分を確認 (client side)
- ただし、この場合はローカル環境に Helm/Kustomize などが必要で、CMP (Config Management Plugin) は標準的には動作しにくい
- Deprecated
-
argocd app diff --local /path/to/local --server-side-generate
- ローカルファイルを tar 化してリポジトリサーバー (あるいは Argo CD API サーバー) に送信し、サーバーサイドでマニフェストを生成
- ユーザーのローカル環境に特定バージョンの Helm/Kustomize は不要、さらに CMP (Config Management Plugin) も動作可能
Argo CD v2.7 以降では --server-side-generate
がデフォルトになるとドキュメントに記載されています。
https://argo-cd.readthedocs.io/en/stable/operator-manual/upgrading/2.4-2.5/#deprecated-client-side-manifest-diffs
argocd app diff <アプリ名>
がやっていること
argocd app diff <アプリ名>
を実行すると、以下のような流れになります:
- 指定した Application リソース (<アプリ名>) の
spec.source
(GitリポジトリURL, Helm, Kustomize, Plugin名など) を読み取る - Argo CD リポジトリサーバーで desired state のマニフェストを生成
- Kubernetes クラスターから live state を取得
- 両者の差分を CLI で表示
--local
オプションを指定した場合
client side (--local
のみ)
argocd app diff --local /path/to/dir
を指定すると、Argo CD はユーザーのローカルファイルを直接読み込み、マニフェストを生成し、ライブリソースとの diff を行います。
- 利点: ネットワーク越しにファイルを送らずに済む
- 欠点: ユーザーのローカル環境に Helm/Kustomize が必要、CMP (プラグイン) は動作しづらい.
server side (--local
+ --server-side-generate
)
argocd app diff --local /path/to/dir --server-side-generate
を指定すると、下記のフローでサーバーサイド生成が走ります:
- CLI が Argo CD API サーバー (アプリケーションサービス) に対して gRPC メソッド
GetManifestsWithFiles(...)
を開始 - CLI 側で
SendApplicationManifestQueryWithFiles(...)
が呼ばれ、/path/to/dir
以下のファイルを tar 化してストリーミング送信 - Argo CD API サーバーがリポジトリサーバーへ「このファイルを用いてマニフェストを生成して」と依頼
- リポジトリサーバーでヘルムやカスタマイズ、CMP サイドカーなどを使ってマニフェストを生成し、API サーバーへ返却
- API サーバーが最終的なマニフェストを CLI に返す
- 受け取ったマニフェストを CLI がライブリソースと突き合わせ、diff を表示
この方法ならユーザーのローカルマシンはargocd cli
の管理と、argocd
へアクセスできる状況を維持するだけで済み、Helm/Kustomize のバージョン整合性や CMP の有無を管理しなくて済みます。
マーメイド図 (サーバーサイド生成時のシーケンス)
spec.source
とローカル転送の関係
「ローカルからファイルを送るなら、そもそも spec.source
は読まなくていいかもしれない」と疑問に思う方もいるかもしれません。しかし、以下のような理由で実際には部分的に参照されるケースがあります:
- アプリケーション名や Plugin 名、Project 情報などを取得するため:
- どのプラグインを使うのか, あるいは Helm の設定や Kustomize の設定があるのか、といった メタ情報 を確認する際に
spec.source
を利用する
- どのプラグインを使うのか, あるいは Helm の設定や Kustomize の設定があるのか、といった メタ情報 を確認する際に
- Revision やデフォルトブランチの参照:
- 実際にはローカルファイルで差分を取る場合でも、revision の扱いをどうするか (現在の revision と比較する等) のために
spec.source
のTargetRevision
やRepoURL
を参照することがある
- 実際にはローカルファイルで差分を取る場合でも、revision の扱いをどうするか (現在の revision と比較する等) のために
- ただし、Git リポジトリから実際に checkout しにいくわけではない:
-
--server-side-generate
を使ってローカルファイルが転送される場合は、リポジトリサーバーで Git をダウンロードしてくる処理がスキップされ、tar 化されたローカルファイルが直接使われる -
spec.source
はあくまで他の設定 (ネームスペースや Plugin 名判定など) に利用されるに留まる
-
結果として、Application リソースの spec.source
は 完全に無視されているわけではない が、マニフェスト取得本体としては ローカルでアップロードしたファイル が優先されます。
まとめ
-
argocd app diff <アプリ名>
は、Application CR のspec.source
からリポジトリ情報やプラグイン設定を読み取り、サーバーサイド (repo server) でマニフェストを生成 → ライブリソースと差分表示する -
argocd app diff --local /path
は、ローカルファイルをベースに差分を算出するやり方で、Helm/Kustomize/CMP をローカルにインストールしておく必要がある (client side) -
argocd app diff --local /path --server-side-generate
は、ローカルファイルをサーバーに送信してサーバーサイドでマニフェスト生成を行うため、ローカルへの事前インストール不要かつ CMP などの高度な機能も利用可能 -
spec.source
はローカル転送でも設定情報 (Revision、Plugin種別など) を確認するために一部参照されるが、Git リポジトリダウンロードは行われない