なぜGitOpsのデプロイは密かに「破綻」してしまうのか?
GitOpsモデルにおいて、Argo CDはいわば司令塔の役割を果たします。Git上のすべてのマニフェスト変更はArgo CDによって自動的にプルされ、Kubernetesクラスタへ適用されます。しかし、実際の運用は常に順風満帆とは限りません。
アプリケーションがOutOfSyncのままスタックしたり、Degradedに陥ったりすることがあります。適切なアラートがなければ、新しいリリースが停止したままになったり、気付かないうちに本番サービスがダウンしてしまう恐れすらあります。
私たちの環境では、PrometheusとGrafanaを用いて15のサーバクラスタと80以上のマイクロサービスを管理しています。以前、チームの開発者がHelmチャートのvalues-prod.yamlでインデントを誤って設定してしまったことがありました。Gitにはコミットされたものの、Argo CDは3日間にわたって同期エラーを静かに出し続けていました。QAが新機能をテストした段階で、新しいコードが一度もロールアウトされていなかったことがようやく発覚したのです。
このような事態を防ぐための解決策は極めてシンプルです。Argo CDのSync StatusとHealth Statusに関するすべてのメトリクスをPrometheusに集約し、ダッシュボードを可視化してSlackやTelegramへアラートを通知することです。
Argo CDからPrometheus Operatorへメトリクスをスクレイピングする
argocd-server、argocd-repo-server、argocd-application-controllerといったArgo CDのコアコンポーネントは、ポート8082または8083経由でデフォルトでメトリクスをエクスポートしています。クラスタで既にkube-prometheus-stackが稼働していれば、ServiceMonitorファイルを2つ用意するだけで簡単に設定できます。
まず、argocd名前空間でメトリクス用のServiceが準備できているか確認します:
kubectl get svc -n argocd -l app.kubernetes.io/name=argocd-metrics
ポート8082をリッスンしているServiceが出力されたら、Prometheus Operatorが自動でスクレイピングできるようにargocd-servicemonitor.yamlファイルを作成します:
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: argocd-metrics
namespace: argocd
labels:
release: kube-prometheus-stack
spec:
selector:
matchLabels:
app.kubernetes.io/name: argocd-metrics
endpoints:
- port: metrics
interval: 30s
scrapeTimeout: 10s
コントローラに加えて、argocd-serverやargocd-repo-serverの監視も欠かせません。repo-serverからのメトリクスを確認することで、Gitリポジトリへのアクセスがボトルネックになっていないか、あるいはレートリミットに達していないかを把握できます:
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: argocd-server-metrics
namespace: argocd
labels:
release: kube-prometheus-stack
spec:
selector:
matchLabels:
app.kubernetes.io/name: argocd-server-metrics
endpoints:
- port: metrics
interval: 30s
両方の設定をクラスタに適用します:
kubectl apply -f argocd-servicemonitor.yaml
メトリクスの分析とPromQLクエリの構築
1. Argo CDで特に重要な4大メトリクス
Argo CDは多くのデータを提供しますが、日々の実運用においては以下の4つのメトリクスに注目すれば十分です:
argocd_app_info: 最も重要なメトリクスです。sync_status(Synced、OutOfSync)やhealth_status(Healthy、Degraded、Progressing、Suspended)などのラベルを含み、常に値1を返します。argocd_app_sync_total: 結果ごとの同期実行総数(phase="Succeeded"、phase="Failed"、phase="Error")。argocd_app_reconcile_count: Git上のマニフェストとクラスタのライブ状態との差分をコントローラが照合した頻度。argocd_git_request_total: GitHubやGitLabへのリクエスト送信数。HTTP 429 Too Many Requestsエラーのトラブルシューティングに非常に役立ちます。
2. 日常的に使用するPromQLクエリ
ヘルス異常(Degraded)が発生しているアプリケーションを一覧表示:
sum(argocd_app_info{health_status="Degraded"}) by (name, dest_server, namespace)
Gitとクラスタ間で設定に差分(OutOfSync)が生じているアプリケーションを抽出:
sum(argocd_app_info{sync_status="OutOfSync"}) by (name, dest_server, namespace)
直近15分間の同期失敗率を算出(この割合が5%を超える場合、CI/CDパイプラインに問題が発生している可能性があります):
sum(rate(argocd_app_sync_total{phase=~"Failed|Error"}[15m]))
/
sum(rate(argocd_app_sync_total[15m])) * 100
3. アラート送信用PrometheusRuleの設定
Grafanaを開いて初めて障害に気付くような事態は避けなければなりません。問題が一定時間継続した際に即座に通知が飛ぶよう、自動アラートを設定しておきましょう:
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: argocd-application-alerts
namespace: argocd
labels:
release: kube-prometheus-stack
spec:
groups:
- name: argocd.rules
rules:
- alert: ArgoAppDegraded
expr: argocd_app_info{health_status="Degraded"} == 1
for: 5m
labels:
severity: critical
annotations:
summary: "アプリケーション {{ $labels.name }} がDegraded状態です"
description: "クラスタ {{ $labels.dest_server }} 上のアプリ {{ $labels.name }} が5分以上異常状態のままスタックしています。"
- alert: ArgoAppOutOfSync
expr: argocd_app_info{sync_status="OutOfSync"} == 1
for: 15m
labels:
severity: warning
annotations:
summary: "アプリケーション {{ $labels.name }} がOutOfSync状態です"
description: "アプリ {{ $labels.name }} のクラスタとGit間で15分以上差分が発生しており、リコンサイルされていません。"
4. Grafanaへのダッシュボードのインポート
何時間もかけて各チャートを一から作成する代わりに、Argo CDコミュニティが提供している既存のダッシュボードを活用するのが効率的です。GrafanaのUIにアクセスし、Dashboards > Importを選択してID 14584(Argo CD Official Dashboard)または13038を入力します。
このダッシュボードには、Applicationの総数、Healthy/Sync率のグラフ、障害が発生しているアプリの一覧、repo-serverのレイテンシなど、主要なパネルが揃っています。Prometheusデータソースを正しく選択すれば、即座にデータが反映されます。
実環境でのテストと検証
設定が完了しても、擬似的に障害を発生させてテストするまでは完了とは言えません。
まず、PrometheusがArgo CDのターゲットを正常に認識しているか確認します:
kubectl port-forward svc/kube-prometheus-stack-prometheus -n monitoring 9090:9090
ブラウザでhttp://localhost:9090/targetsを開き、エンドポイントserviceMonitor/argocd/argocd-metrics/0が緑色の背景でUPと表示されているか確認します。
次に、ステージング環境のアプリケーションで意図的に障害を再現してみます。Git上のマニフェストファイルを編集し、イメージタグを存在しないauth-service:v999-notfoundなどに変更してプッシュします。Argo CDが新しいコミットをプルすると、直ちにPodがImagePullBackOffエラーとなり、Argo CDのヘルスステータスがDegradedに遷移します。
Grafanaを開いて確認すると、Healthy Appsパネルの数値が直ちに1減少し、Degradedパネルに対象のauth-serviceが表示されます。5分待つと、AlertmanagerからArgoAppDegradedのアラートが発火します。
最後に、Gitのコミットをリバートして正しいイメージタグに戻します。Argo CDが自動的にリコンサイルを完了し、Podが正常稼働(緑色)に戻ると、アラートも自動で解決(Resolve)されます。これで、GitOpsのデプロイフロー全体に24時間365日のセーフティネットが整備されました。