2026年8月11日
2026年8月11日
Argo CD(GitOps)でKubernetesデプロイを自動化する方法
Argo CD を使うと、Git リポジトリに置いたマニフェストを「あるべき状態」として、Kubernetes クラスタの状態を自動で合わせ続けられます。デプロイは kubectl apply を手で叩く作業から、Git へのコミットとプルリクエストのレビューに置き換わります。この記事では、Argo CD のインストール、最初の Application の作成、自動同期の設定、イメージ更新の流れ、Secret の扱い、ロールバックの考え方までを、つまずきやすい点と確認方法を添えて説明します。
GitOps と Argo CD の役割
GitOps は「クラスタに反映される構成の正本を Git に置き、変更はすべて Git 経由で行う」という運用方法です。Argo CD はクラスタ内で動くコントローラーで、指定したリポジトリを定期的に確認し、クラスタの実際の状態との差分を検出して同期します。
従来の CI から kubectl apply する方式(プッシュ型)と比べると、次の点が変わります。
- CI にクラスタの強い権限を持たせずに済む(クラスタ側が Git を取りに行くプル型)
- 誰かが手でリソースを変えても、差分として検出できる
- 「今クラスタに何が入っているか」を Git の履歴で説明できる
一方で、Git にあるものがそのまま反映されるため、リポジトリの書き込み権限とブランチ保護が実質的な本番の権限になります。導入前に、誰がどのブランチにマージできるかを整理しておいてください。
前提と準備
- 動作する Kubernetes クラスタ(検証なら minikube や kind、k3s でも可)
kubectlがクラスタに接続できること- マニフェストを置く Git リポジトリ(アプリのソースとは別の「設定用リポジトリ」に分けるのが一般的)
マニフェストは素の YAML のほか、Kustomize や Helm チャートでも管理できます。環境ごとの差分(レプリカ数やドメイン名)があるなら、Kustomize の overlays や Helm の values ファイルで分けておくと、Argo CD 側の設定がすっきりします。
Argo CD をインストールする
公式ドキュメントの手順では、専用の Namespace を作り、配布されているマニフェストを適用します。
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
上の URL は stable を指しているため、適用されるバージョンは時期によって変わります。本番では、検証済みのバージョンのタグを指定して適用するほうが再現性があります。また、版によっては kubectl apply に追加のオプション(サーバーサイド適用など)を付けるよう案内されていることがあるため、インストール前に公式ドキュメントの Getting Started を確認してください(2026年10月現在)。
起動したかどうかは Pod の状態で確認します。
kubectl get pods -n argocd
すべての Pod が Running になれば準備完了です。Pending のままなら、ノードのリソース不足やイメージの取得失敗が考えられるので、kubectl describe pod でイベントを見てください。
管理画面にログインする
最初は外部に公開せず、ポートフォワードでアクセスします。
kubectl port-forward svc/argocd-server -n argocd 8080:443
ブラウザで https://localhost:8080 を開きます(自己署名証明書の警告が出ます)。ユーザー名は admin、初期パスワードは次のどちらかで確認できます。
# argocd CLI を入れている場合
argocd admin initial-password -n argocd
# kubectl だけで確認する場合
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -d
ログインしたらすぐにパスワードを変更し、初期パスワードの Secret は削除しておきます。運用が始まったら、admin を共有せず、SSO(OIDC など)と Argo CD の RBAC で個人ごとの権限を付けるのが望ましい形です。管理画面を外部に公開する場合も、Ingress と TLS、アクセス元の制限を合わせて設定してください。
最初の Application を作る
Argo CD では、「どのリポジトリのどのパスを、どのクラスタのどの Namespace に反映するか」を Application というリソースで定義します。画面からも作れますが、Application 自体も YAML で Git 管理しておくと、Argo CD の設定まで再現できます。
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: wordpress-prod
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/your-org/k8s-manifests.git
targetRevision: main
path: apps/wordpress/overlays/prod
destination:
server: https://kubernetes.default.svc
namespace: wordpress
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
kubectl apply -n argocd -f wordpress-prod-app.yaml
syncPolicy.automated があると、Git の変更を検出したときに自動で同期します。prune: true は Git から消したリソースをクラスタからも削除する設定、selfHeal: true は手で変更されたリソースを Git の状態に戻す設定です。最初は automated を付けずに手動同期で動きを確かめ、慣れてから自動にする進め方でも構いません。
プライベートリポジトリの場合は、事前に argocd repo add か、所定のラベルを付けた Secret でリポジトリの認証情報を登録します。読み取り専用のデプロイキーやトークンを使い、書き込み権限は与えないでください。
同期の状態を確認する
Application には大きく2つの状態があります。
- Sync Status:Git とクラスタが一致しているか(Synced / OutOfSync)
- Health Status:リソースが正常に動いているか(Healthy / Progressing / Degraded など)
Synced なのに Degraded の場合は、マニフェストどおりに反映されたが Pod が起動していない、という意味です。イメージ名の誤りやプローブの失敗が多いので、画面のリソースツリーから該当の Pod を開いてイベントとログを確認します。
Git の変更が反映されるまで数分かかるのは、Argo CD が一定間隔でリポジトリを確認しているためです。すぐに反映したい場合は、Git ホスティング側から Argo CD への Webhook を設定すると、プッシュをきっかけに確認が走るようになります。
イメージを更新するデプロイの流れ
アプリの新しいバージョンを出すときの一般的な流れは次のとおりです。
- アプリのリポジトリで CI がコンテナイメージをビルドし、バージョンやコミットIDのタグを付けてレジストリにプッシュする
- CI が設定用リポジトリのイメージタグを書き換えるプルリクエストを作る(または直接コミットする)
- レビュー後にマージされると、Argo CD が差分を検出して同期する
latest タグを使い回すと、Git 上の変更がないためArgo CD が更新を検出できず、どのバージョンが動いているかも追えなくなります。タグは毎回変わる値にしてください。タグの書き換えを自動化するツールとして Argo CD Image Updater もありますが、対応する書き戻し方式などは版によって異なるので、使う場合はドキュメントで確認してください。
Secret を Git に置かない
GitOps でまず悩むのが Secret の扱いです。Kubernetes の Secret は Base64 で符号化されているだけなので、そのまま Git にコミットすると、リポジトリを読める人に中身が見えてしまいます。代表的な方法は次のとおりです。
- Sealed Secrets:クラスタの公開鍵で暗号化した SealedSecret をコミットし、クラスタ内で復号する
- External Secrets Operator:AWS Secrets Manager などの外部の保管庫から値を取得して Secret を作る
- SOPS:ファイルを暗号化してコミットし、同期時に復号する(Argo CD 側に連携の設定が要る)
どれを選ぶにしても、平文の値がコミット履歴に残らないかをレビューで確認する体制が要ります。一度コミットした値は、履歴を消すより先に値そのものを変更してください。
WordPress などデータを持つアプリでの注意点
prune: true は便利ですが、データを持つリソースでは危険にもなります。たとえば PersistentVolumeClaim のマニフェストをリファクタリングの過程で消してしまうと、同期時に PVC が削除され、設定によってはボリュームのデータも失われます。
データを持つリソースには、自動削除の対象から外す注釈を付けておくと安全です。
metadata:
annotations:
argocd.argoproj.io/sync-options: Prune=false
データベースのマイグレーションのように順番が大事な処理は、同期フック(argocd.argoproj.io/hook: PreSync など)や同期ウェーブ(argocd.argoproj.io/sync-wave)で実行順を制御できます。いずれにしても、データベースとボリュームのバックアップは Argo CD とは別に取っておいてください。
ロールバックの考え方
GitOps でのロールバックは、Git で問題のコミットを revert し、その変更を同期させるのが基本です。Git の履歴とクラスタの状態が一致したまま戻せるため、後から経緯を追いやすくなります。
Argo CD には過去の同期履歴に戻す機能(argocd app rollback など)もありますが、自動同期が有効な Application ではこの操作が受け付けられません。仮に戻せたとしても、Git が変わっていなければ次の同期で元に戻ります。緊急時に画面から戻す場合は、自動同期を一時的に止めたうえで行い、落ち着いたら Git 側も同じ状態に直してください。
まとめ
- Argo CD は Git のマニフェストを正本として、クラスタの状態を合わせ続けるプル型のデプロイツール
- インストール後は初期パスワードを変更し、SSO と RBAC で個人ごとの権限にする
- Application で「どのリポジトリのどのパスを、どこに反映するか」を定義し、最初は手動同期で動きを確認する
- イメージタグは毎回変わる値にし、CI が設定用リポジトリのタグを書き換える流れにする
- Secret は Sealed Secrets や External Secrets Operator などで平文を Git に置かない
- データを持つリソースは
Prune=falseで保護し、ロールバックは Git の revert を基本にする