ArgoCD の GitOps で Merge 前に manifest の差分を見たい
ArgoCD は Application リソースで source に指定した Git などの定義と実際に Kubernetes クラスタにデプロイされている manifest の差分をリッチな WebUI で確認することができる便利なツールでもありますが、auto sync を有効にした場合は WebUI で差分を確認するといったステップはなく、Git で対象の branch に push されるとそのまま apply されてしまいます。
Pull Request / Merge Request の段階で差分が確認できることが望ましい。
もちろん、auto sync が有効な状態であれば git の内容とデプロイ済みの manifest は同一であるはずなので Git の変更前後の manifest のレンダリング結果の差分を確認すれば良いわけですが、その方法は一旦置いておいて、argocd CLI でクラスタにデプロイ済みの内容と任意の git ref との差分を確認する方法を試してみます。
Login
まずは、login コマンドで token を取得します。ArgoCD の SSO は多くの IdP に対応しているのでおそらく SSO が有効になっていると思われますが、そんな場合でも --sso
オプションをつければ大丈夫。
また、Load Balancer が gRPC に対応していなくても --grpc-web
オプションをつければ大丈夫、これはログイン時に指定しておくとその情報は ~/.config/argocd/config
に書き込まれて以降のコマンドでは省略が可能になります。
argocd login argocd.example.com --grpc-web --sso
複数サーバーを使い分ける場合は argocd context
コマンドで切り替え可能です。
Diff
argocd app diff コマンドを試します。
Container image の tag 更新と HPA の上限を上げた mybranch というブランチが存在するとした場合、次のようにして現在 deploy 済みのものとの差分を表示することができます。
$ argocd app diff mynginx --revision mybranch
===== apps/Deployment nginx/mynginx ======
174c174
< - image: nginx:1.25.5
---
> - image: nginx:1.27.3
===== autoscaling/HorizontalPodAutoscaler nginx/mynginx ======
81c81
< maxReplicas: 4
---
> maxReplicas: 5
デフォルトでは差分のある当該行しか表示されませんが、KUBECTL_EXTERNAL_DIFF
変数で任意の diff コマンドを指定することが可能です。
指定したコマンドには引数で差分のあるリソースそれぞれについて live manifest と revision で指定された git ref で生成される manifest の file path が渡されます。その為、単に diff -u
を指定するだけで次のような出力に変わります。
$ KUBECTL_EXTERNAL_DIFF="diff -u" argocd app diff mynginx --revision mybranch
===== apps/Deployment nginx/mynginx ======
--- /var/folders/6_/3y9s4yg55s97xjvc8tbvgndm0000gn/T/argocd-diff1162649527/mynginx-live.yaml 2024-12-02 23:50:22
+++ /var/folders/6_/3y9s4yg55s97xjvc8tbvgndm0000gn/T/argocd-diff1162649527/mynginx 2024-12-02 23:50:22
@@ -171,7 +171,7 @@
app.kubernetes.io/name: nginx
spec:
containers:
- - image: nginx:1.25.5
+ - image: nginx:1.27.3
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
===== autoscaling/HorizontalPodAutoscaler nginx/mynginx ======
--- /var/folders/6_/3y9s4yg55s97xjvc8tbvgndm0000gn/T/argocd-diff2265450647/mynginx-live.yaml 2024-12-02 23:50:22
+++ /var/folders/6_/3y9s4yg55s97xjvc8tbvgndm0000gn/T/argocd-diff2265450647/mynginx 2024-12-02 23:50:22
@@ -78,7 +78,7 @@
resourceVersion: "226417567"
uid: 294a6291-ee43-401f-a3a2-e0522d56af3b
spec:
- maxReplicas: 4
+ maxReplicas: 5
metrics:
- resource:
name: cpu
その他の argocd コマンド
argocd コマンドはほとんどの操作が可能で意外と見やすいですし、ブラウザで開くより便利かもしれない。
ちなみに、ArgoCD のインストールには headless mode もというものもあります。
argocd
$ argocd
argocd controls a Argo CD server
Usage:
argocd [flags]
argocd [command]
Available Commands:
account Manage account settings
admin Contains a set of commands useful for Argo CD administrators and requires direct Kubernetes access
app Manage applications
appset Manage ApplicationSets
cert Manage repository certificates and SSH known hosts entries
cluster Manage cluster credentials
completion output shell completion code for the specified shell (bash or zsh)
context Switch between contexts
gpg Manage GPG keys used for signature verification
help Help about any command
login Log in to Argo CD
logout Log out from Argo CD
proj Manage projects
relogin Refresh an expired authenticate token
repo Manage repository connection parameters
repocreds Manage repository connection parameters
version Print version information
argocd app
$ argocd app
Manage applications
Usage:
argocd app [flags]
argocd app [command]
Examples:
# List all the applications.
argocd app list
# Get the details of a application
argocd app get my-app
# Set an override parameter
argocd app set my-app -p image.tag=v1.0.1
Available Commands:
actions Manage Resource actions
add-source Adds a source to the list of sources in the application
create Create an application
delete Delete an application
delete-resource Delete resource in an application
diff Perform a diff against the target and live state.
edit Edit application
get Get application details
history Show application deployment history
list List applications
logs Get logs of application pods
manifests Print manifests of an application
patch Patch application
patch-resource Patch resource in an application
remove-source Remove a source from multiple sources application. Counting starts with 1. Default value is -1.
resources List resource of application
rollback Rollback application to a previous deployed version by History ID, omitted will Rollback to the previous version
set Set application parameters
sync Sync an application to its target state
terminate-op Terminate running operation of an application
unset Unset application parameters
wait Wait for an application to reach a synced and healthy state
argocd app get
argoce app get の出力例。スッキリしてて良くないですか?
$ argocd app get mynginx
Name: argocd/mynginx
Project: myproject
Server: https://kubernetes.default.svc
Namespace: nginx
URL: https://argocd.example.com/applications/mynginx
Source:
- Repo: https://gitlab.example.com/mygroup/mycharts.git
Target: main
Path: charts/nginx
Helm Values: ../../values/mynginx.yaml
SyncWindow: Sync Allowed
Sync Policy: Automated
Sync Status: Synced to main (1c6031b)
Health Status: Healthy
GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE
ServiceAccount nginx mynginx Synced serviceaccount/mynginx unchanged
Service nginx mynginx Synced Healthy service/mynginx unchanged
apps Deployment nginx mynginx Synced Healthy deployment.apps/mynginx unchanged
autoscaling HorizontalPodAutoscaler nginx mynginx Synced Healthy horizontalpodautoscaler.autoscaling/mynginx configured
argocd app resources
argocd app resources の出力例
$ argocd app resources mynginx
GROUP KIND NAMESPACE NAME ORPHANED
Service nginx mynginx No
ServiceAccount nginx mynginx No
apps Deployment nginx mynginx No
autoscaling HorizontalPodAutoscaler nginx mynginx No
service account を使って diff を出力
SSO のユーザーアカウントでは CI の処理で使うのに向きません、専用のアカウントを作って実行することにします。
Helm で account を作成する
helm の values で次のようにして apiKey を利用可能な diff_viewer というアカウントを作成します。ここでの apiKey はそのまま apiKey
という文字列を指定します。
configs:
cm:
accounts.diff_viewer: apiKey
rbac:
create: true
policy.default: 'role:readonly'
policy.csv: |
p, diff_viewer, applications, get, */*, allow
g, admin-group, role:admin
Account の確認
Capabilities に apiKey と入っている account が作成されていることがわかります。
$ argocd account list
NAME ENABLED CAPABILITIES
admin false login
diff_viewer true apiKey
$ argocd account get --account diff_viewer
Name: diff_viewer
Enabled: true
Capabilities: apiKey
Tokens:
NONE
Token の作成
generate-token
コマンドで token を作成します。
$ argocd account generate-token --account diff_viewer
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhcmdvY2QiLCJzdWIiOiJkaWZmX3ZpZXdlcjphcGlLZXkiLCJuYmYiOjE3MzMyMjM5MDgsImlhdCI6MTczMzIyMzkwOCwianRpIjoiZTVhNmUyMjYtNmNkOC00YjY1LWJkNGEtMTRlMmRmY2RiZjRlIn0.70UKcOG5nJGpOnFVi_KeI4LsJatYCIoFerliplrp3Co
JWT を decode して中身を見てみる
Token header
------------
{
"typ": "JWT",
"alg": "HS256"
}
Token claims
------------
{
"iat": 1733223908,
"iss": "argocd",
"jti": "e5a6e226-6cd8-4b65-bd4a-14e2dfcdbf4e",
"nbf": 1733223908,
"sub": "diff_viewer:apiKey"
}
ここで再度 account get
で確認すると Tokens のところに入っていることがわかります。
$ argocd account get --account diff_viewer
Name: diff_viewer
Enabled: true
Capabilities: apiKey
Tokens:
ID ISSUED AT EXPIRING AT
e5a6e226-6cd8-4b65-bd4a-14e2dfcdbf4e 2024-12-03T20:05:08+09:00 never
Token を使って diff を取得する
SSO のアカウントではログオフしておくことで token が使われていることを確認します。
$ argocd logout argocd.example.com
Logged out from 'argocd.example.com'
app diff
コマンドを実行します。
$ argocd --server argocd.example.com --grpc-web --auth-token $TOKEN app diff mynginx --revision mybranch
===== apps/Deployment nginx/mynginx ======
174c174
< - image: nginx:1.25.5
---
> - image: nginx:1.27.3
===== autoscaling/HorizontalPodAutoscaler nginx/mynginx ======
81c81
< maxReplicas: 4
---
> maxReplicas: 5
token の削除
上記で晒してしまったので token を削除しておきます。account get
で表示されていた ID を指定します。
$ argocd account delete-token --account diff_viewer e5a6e226-6cd8-4b65-bd4a-14e2dfcdbf4e
token が消えていることを確認
$ argocd account get --account diff_viewer
Name: diff_viewer
Enabled: true
Capabilities: apiKey
Tokens:
NONE
おまけ
GitHub には良い感じに Merge Request に差分をコメントで書き込んでくれる便利な actions があるようです。
こちらはなんだか凝っていて実際の ArgoCD インスタンスへのアクセスは不要で、ローカルのクラスタに ArgoCD をセットアップしてそこで差分を出力させるようです。