GitOpsとは、アプリケーションとインフラの「望ましい状態」をGitに宣言的に書き、クラスタの中で動くエージェントがそれを取りに行って実環境と一致させ続ける運用モデルです。この記事では、OpenGitOpsが定めた4原則の原文、CIからkubectl applyするPush型との違い、Argo CDとFluxでの最小構成のYAML、リポジトリの分け方やイメージタグの更新、Secretの扱いといった導入時に決める設計を、コピーして動かせる形で示します。GitOpsを採用しない方がよい構成も条件付きで書きます。版番号は2026年10月時点の公式情報で確かめた内容です。
まとめ:GitOpsはGitの宣言を正としてクラスタ側が取りに行く運用モデル
GitOpsで新しく決まるのは「デプロイの向き」です。CIがクラスタへ押し込むのではなく、クラスタ内のエージェントがGitを読みに行きます。
- 定義はOpenGitOpsの4原則(宣言的・バージョン管理と不変性・自動で取得・継続的な調整)で、ツール名ではない
- Push型との差は、クラスタの認証情報をCIに置かないことと、手作業の変更(ドリフト)を自動で戻せること
- Kubernetesでの実装はArgo CDかFluxの2択で、画面とマルチテナントが要るならArgo CD、Gitとコマンドだけで完結させたいならFlux
- 導入時に決めるのは、リポジトリの分け方・環境の昇格方法・イメージタグの書き戻し・Secretの置き場の4つ
Kubernetesのクラスタを2つ以上持ち、週1回以上デプロイするチームなら採用します。VM中心の構成では見送ります。
GitOpsの定義:OpenGitOpsの4原則とGitを唯一の正とする考え方
GitOpsという呼び名は2017年にWeaveworksが広めたもので、当初は同社のFluxの使い方を指す言葉でした。その後、CNCFのGitOps Working Groupが運営するOpenGitOpsが、特定ツールに依存しない定義としてOpenGitOpsの原則をまとめています。
宣言的・バージョン管理・自動Pull・継続的な調整の4原則の中身
OpenGitOpsのPRINCIPLES.md(v1.0.0は2021年10月公開)は、GitOpsで管理されるシステムが満たす条件を次の4つに絞っています。
| 原則(原文) | 意味 | Kubernetesでの具体 |
|---|---|---|
| Declarative | 望ましい状態を宣言で表す | YAMLのマニフェスト |
| Versioned and Immutable | 履歴を残し書き換えない | Gitのコミット |
| Pulled Automatically | エージェントが取りに行く | クラスタ内のコントローラ |
| Continuously Reconciled | 実状態を見て差分を直し続ける | 定期的な再照合 |
原則の文面には「Git」という語が出てきません。履歴が残り不変であれば、保管先はOCIレジストリでもよいということです。実務ではGitが圧倒的に多いため、この記事もGitを前提に書きます。
IaCやCI/CDとの関係:GitOpsが新しく決めるのはデプロイの向き
構成をコードで書く点はIaC(Infrastructure as Code)と同じです。ビルドとテストを自動化する点はCI/CDの範囲に入ります。GitOpsが加えるのは、後半の2原則です。
つまり、IaCで書いたものを「誰が・いつ適用するか」をGitOpsは決めています。適用するのはクラスタ内のエージェントで、適用のきっかけはGitへのマージです。適用後も監視を続けて、ずれたら戻します。CIは引き続き必要で、担当がビルド・テスト・イメージの作成までに縮むだけです。
Push型CIOpsとPull型GitOpsの違いを認証情報とドリフトで比較
GitOpsの説明で必ず比べられるのが、CIのジョブから直接クラスタへ適用する構成です。これをCIOps(Push型)と呼びます。
CIからkubectl applyする構成とクラスタ内エージェント構成の比較表
Push型は、たとえばGitHub Actionsに次のようなステップを書く構成です。
# Push型(CIOps)の例:CIがクラスタの認証情報を持って直接適用する
- name: 本番へ適用
env:
KUBECONFIG: ${{ runner.temp }}/kubeconfig
run: |
echo "${{ secrets.PROD_KUBECONFIG }}" > "$KUBECONFIG"
kubectl apply -k overlays/prod
動きはしますが、本番クラスタの管理者権限がCIのシークレットに入ります。Pull型との違いを並べると次のとおりです。
| 観点 | Push型(CIOps) | Pull型(GitOps) |
|---|---|---|
| 適用する主体 | CIのジョブ | クラスタ内のエージェント |
| クラスタの認証情報 | CIに置く | クラスタ外に出さない |
| 手作業の変更 | 次のデプロイまで残る | 再照合で戻る |
| 閉域のクラスタ | CIから到達が必要 | 外向き通信だけで済む |
| 今の状態の確認 | CIのログを追う | Gitと同期状態を見る |
差が最も大きいのは認証情報です。CIのシークレットが漏れたときに本番が書き換えられる経路が、Pull型では消えます。
selfHealとpruneで手作業の変更とGit外のリソースを戻す仕組み
4原則の最後の「継続的な調整」は、ツールの設定で初めて有効になります。Argo CDの自動同期のドキュメントによると、Gitから消えたリソースを削除するpruneと、クラスタ上の手作業の変更を戻すselfHealは、どちらも安全のため既定で無効です。Gitを確認する間隔はargocd-cmのtimeout.reconciliationで決まり、既定は120秒に最大60秒の揺らぎを足した値(最大3分)です。
FluxはKustomizationのドキュメントにあるとおり、spec.intervalごとにマニフェストを適用し直し、その過程でドリフトを修正します。spec.pruneは必須項目で、trueにするとGitから消えたオブジェクトをクラスタからも消します。
どちらのツールでも、自動で戻す設定を入れた時点で「緊急時にkubectl editで直す」運用は数分で巻き戻されます。障害対応の手順書を、Gitのコミットで直す流れに書き換えてから有効にします。
Argo CDとFluxでGitOpsを動かす最小構成のマニフェスト例
KubernetesでGitOpsを実装する道具は、CNCFを卒業したArgo(2022年12月6日に卒業)とFlux(2022年11月30日に卒業)の2つです。最新版はArgo CDのリリース一覧で3.5系、Fluxのリリース一覧で2.9系(いずれも2026年10月時点)です。Kubernetes自体の仕組みはKubernetes(クバネティス)とはで解説しています。
Argo CDのApplicationで自動同期を有効にするYAML例
Argo CDでは、どのGitのどのパスを、どのクラスタのどの名前空間へ同期するかをApplicationリソース1つで宣言します。Declarative Setupのドキュメントの最小例に、自動同期の設定を足すと次の形になります。
# shop-api-prod.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: shop-api-prod
namespace: argocd # Argo CD本体と同じ名前空間に置く
finalizers:
- resources-finalizer.argocd.argoproj.io # Application削除時に配下も消す
spec:
project: default
source:
repoURL: https://github.com/example/platform-config.git
targetRevision: main
path: apps/shop-api/overlays/prod
destination:
server: https://kubernetes.default.svc
namespace: shop-api
syncPolicy:
automated:
prune: true # Gitから消えたリソースを削除(既定は無効)
selfHeal: true # 手作業の変更を戻す(既定は無効)
syncOptions:
- CreateNamespace=true
kubectl apply -n argocd -f shop-api-prod.yamlで登録すると、以降はmainへのマージがそのまま本番への反映になります。finalizersを付けないと、Applicationを消しても配下のDeploymentなどは残る仕組みです。Argo CD本体のインストールと画面からのSync操作はArgoCDとは?GitOpsの仕組みとインストール・Sync設定をコード付きで解説で手順を追えます。運用を始めた後に追うArgo CD本体の脆弱性と修正版は、Argo CDの脆弱性一覧と対処にまとめています。
Fluxのbootstrapとkustomize-controllerで同期させる手順
Fluxは、自分自身のマニフェストもGitで管理するところから始めます。GitHub向けbootstrapのドキュメントのとおり、実行者にはクラスタの管理者権限と、リポジトリの所有者か組織の管理者権限が要ります。
# GitHubのトークンを渡してbootstrapする(未設定なら入力を求められる)
export GITHUB_TOKEN=<GitHubのトークン>
flux bootstrap github \
--token-auth \
--owner=example \
--repository=platform-config \
--branch=main \
--path=clusters/prod
bootstrapはFluxのコントローラをクラスタに入れ、そのマニフェストをclusters/prodへpushし、以後はFlux自身もGitから更新されるように設定します。アプリを同期させるには、同じディレクトリに次の2つを置いてコミットします。
# clusters/prod/shop-api.yaml
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: platform-config-apps
namespace: flux-system
spec:
interval: 1m # Gitを確認する間隔
url: https://github.com/example/platform-config
ref:
branch: main
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: shop-api
namespace: flux-system
spec:
interval: 10m # 適用し直してドリフトを直す間隔
sourceRef:
kind: GitRepository
name: platform-config-apps
path: ./apps/shop-api/overlays/prod
prune: true # 必須項目。Gitから消えたものを削除
targetNamespace: shop-api
timeout: 2m
Fluxは取得を担うGitRepositoryと適用を担うKustomizationが別のリソースに分かれていて、Argo CDのApplication1つ分を2つで表します。flux get kustomizationsで同期したリビジョンと成否を確認できます。
Argo CDとFluxの選び分け:UIの要否とマルチテナント運用の差
選び分けの軸は2つです。1つ目は画面の要否で、開発者が自分のアプリの同期状態や差分をブラウザで見たいならArgo CDを選びます。Fluxは標準のWeb画面を持たず、CLIとkubectl、通知連携で状態を追う構成です。2つ目は複数チームの同居で、Argo CDはAppProjectでチームごとに同期先と参照できるリポジトリを絞れます。
逆に、クラスタが多数あり、すべてをGitとコマンドで揃えたい基盤チームならFluxが軽く済みます。HelmやOCIのソースを細かく組み合わせられる点もFluxの強みです。機能の細かな差はFlux CDとは?GitOps Toolkitの仕組みとArgo CDとの違いで比較しています。同じクラスタで両方を動かす構成は、同じリソースを2つのエージェントが取り合うので作りません。
リポジトリ分割・環境昇格・イメージ更新・Secret管理の設計判断
ツールを入れただけでは運用は回りません。導入の最初の1か月で決めておくべきなのが、次の4つの設計です。
アプリのソースとマニフェストを別リポジトリに分ける運用上の判断基準
アプリのソースコードと、デプロイ用のマニフェストは別のリポジトリに分けるのが基本です。同じリポジトリだと、マニフェストの変更のたびにアプリのCIが走り、CIがイメージタグを書き戻すコミットがさらにCIを起動する、というループが起きやすくなります。
分けない方がよいのは、アプリが1つでチームも1つの段階です。この場合はリポジトリ内にdeploy/ディレクトリを置き、CIのトリガーからそのパスを除外すれば足ります。マニフェストを読む人と書く人が別チームになった時点で分けます。
dev・stg・prodの環境昇格をディレクトリとPRで表す構成
環境ごとの差分は、ブランチではなくディレクトリで表します。環境ごとにブランチを切ると、共通部分の修正をブランチ間でマージする作業が増え、差分が把握できなくなるためです。Kustomizeのbaseとoverlaysを使うと次の構成になります。
platform-config/
├── apps/
│ └── shop-api/
│ ├── base/ # 全環境で共通のDeployment・Service
│ │ ├── deployment.yaml
│ │ ├── service.yaml
│ │ └── kustomization.yaml
│ └── overlays/
│ ├── stg/kustomization.yaml # レプリカ数1・stg用のイメージタグ
│ └── prod/kustomization.yaml # レプリカ数3・prod用のイメージタグ
└── clusters/
├── stg/ # stgクラスタが読むApplicationやKustomization
└── prod/
stgで確かめたイメージタグをoverlays/prodへ書き写すプルリクエストが、そのまま本番リリースの承認になります。誰が・いつ・何を本番に出したかがGitの履歴に残るので、変更管理の記録を別に作る必要がありません。カナリアのように段階的に出す仕組みは、プログレッシブデリバリーの領分として別に組みます。
CIのビルド結果をGitへ書き戻すイメージタグ更新の2方式と選び方
CIが新しいイメージを作ったあと、そのタグをマニフェストへ反映させる方法は2つあります。
- CIの最後のステップで、マニフェストのリポジトリへタグを書き換えるコミットかプルリクエストを出す方式
- クラスタ側のツールがレジストリを監視し、新しいタグをGitへ書き戻す方式(Fluxのイメージ自動更新、Argo CDでは別プロジェクトのArgo CD Image Updater)
先に試すのは前者です。CIがどのタグを出したかとマニフェストの変更が1対1で追え、本番はプルリクエストの承認を挟めます。後者はstgのように承認なしで最新を出してよい環境で使い、本番には使いません。いずれも、latestのような動くタグは使わず、コミットハッシュか版番号のタグに固定します。
平文のSecretをGitに置かないSealed SecretsとESOの使い分け
「すべてをGitに」と言っても、パスワードやAPIキーを平文でコミットしてはいけません。方法は2つです。
1つはSealed Secretsで、クラスタの公開鍵で暗号化したリソースをGitに置き、クラスタ内のコントローラだけが復号します。
# 平文のSecretを手元で作り、暗号化したものだけをコミットする
kubectl create secret generic shop-api-db \
--from-literal=password=change-me \
--dry-run=client -o yaml > secret.yaml
kubeseal --format yaml < secret.yaml > sealed-secret.yaml
rm secret.yaml
git add sealed-secret.yaml
もう1つはExternal Secrets Operator(ESO)で、Gitには「AWS Secrets Managerのこの名前を読む」という参照だけを置き、値はクラウドの金庫から取ります。すでにクラウドのシークレット管理サービスで値をローテーションしているならESO、クラウドの金庫を持たない小規模な構成ならSealed Secretsを選びます。
GitOpsを採用すべきKubernetes運用と見送るべき構成の判断基準
GitOpsは万能ではありません。採用と見送りの線を条件付きで言い切ります。
採用条件:Kubernetesクラスタ2つ以上と週1回以上のデプロイ
stgとprodのようにKubernetesクラスタを2つ以上持ち、週に1回以上デプロイするなら採用します。環境ごとの設定のずれと、手作業のkubectlによる変更が、この規模から事故の原因になるためです。監査で「本番の変更を誰が承認したか」を示す必要がある組織でも、プルリクエストの履歴がそのまま証跡になるので効果が出ます。
始め方は、まずstgだけをselfHealなしで同期させ、手作業の変更がどれだけあるかを差分表示で数えることです。差分が落ち着いてからselfHealとpruneを有効にし、最後にprodへ広げます。
導入を見送る場面:VM中心の構成とDBマイグレーションを伴う変更
Kubernetesを使っていない構成では、GitOpsのツールを新しく入れません。Argo CDもFluxもKubernetesの上で動くエージェントなので、VMやサーバーレス中心の環境で使うには、そのためだけにクラスタを1つ運用することになります。Terraformの変更をプルリクエストで回したいだけなら、AtlantisでTerraformのPR運用のようなPush型の仕組みで十分です。
DBのスキーマ変更も、GitOpsの「宣言して収束させる」モデルに乗りにくい作業です。マイグレーションは1回だけ順番どおりに流す手続きで、失敗したら止まる必要があります。アプリのマニフェストはGitOpsで同期し、マイグレーションはCIのジョブかリリース前の手順として分けたままにします。
クラスタが1つで、デプロイが月に数回の段階でも見送ります。この規模では、CIからkubectl applyする構成に、本番用の認証情報を環境保護ルールで守る設定を足す方が手間が少なく済みます。
GitOps導入で詰まりやすいCIとの責任分界と外部支援の範囲
ツールのインストールは1日で終わりますが、止まりやすいのはその先です。CIとGitOpsのどちらが何をするかの線引き、イメージタグの書き戻しの権限、Secretの移行、障害時に手で直す手順の書き換えが、関係するチームの合意待ちで止まります。止まっている箇所がパイプラインと権限の設計なら、DevOps・CI/CD導入支援のような外部の支援に、リポジトリ構成と権限の設計とレビューだけを任せる方法も選択肢です。マニフェストの中身は社内で書くと、運用を引き取るときの負担が小さくなります。
よくある質問
GitOpsを調べるときによく出る疑問に、2026年10月時点の仕様で答えます。
GitOpsはKubernetes以外でも使えますか?
原則としてはツールに依存しませんが、実装はKubernetesが前提のものがほとんどです。クラウドのリソースをGitOpsで管理したい場合は、CrossplaneでAWSなどのリソースをKubernetesのマニフェストとして表し、Argo CDやFluxで同期する構成があります。Kubernetesを持たない組織が、そのためにクラスタを立てるのは見送るのが妥当です。
GitOpsとDevOpsの違いは何ですか?
DevOpsは開発と運用の協力のしかたや文化を指す広い考え方で、GitOpsはその中のデプロイと構成管理を実現する具体的な方法の1つです。GitOpsを入れればDevOpsが完成するわけではなく、テストの自動化や成果の測り方は別に整えます。成果の測り方はDevOpsとは?DORA 5指標での成果の測り方にまとめています。
GitOpsでロールバックはどう行いますか?
基本は、問題のコミットをgit revertしてマージすることです。エージェントが元の状態へ同期し直し、戻した記録もGitに残ります。Argo CDには画面からのロールバック機能もありますが、自動同期を有効にしたアプリケーションでは使えないとドキュメントに明記されています。自動同期の環境では、Gitで戻すのが唯一の正規の手順と考えてください。
Gitless GitOpsとは何が違いますか?
Gitless GitOpsは、エージェントが読みに行く先をGitではなくOCIレジストリにする派生方式です。CIがマニフェストをOCIアーティファクトとしてレジストリへ出し、クラスタはそれを取得する構成です。4原則のうちGitに依存するものは無いので、GitOpsの範囲に含まれます。仕組みと導入手順はGitless GitOpsとはで解説しています。
GitOpsを入れたらCIツールは不要になりますか?
不要にはなりません。ソースのビルド、テスト、コンテナイメージの作成と脆弱性スキャン、レジストリへのpushは引き続きCIの担当です。変わるのはCIの最後の工程で、クラスタへ適用する代わりに、マニフェストのリポジトリへイメージタグを書き換えるプルリクエストを出す形になります。CIがクラスタの認証情報を持たなくなる点が、導入後の大きな違いです。
関連記事
- ArgoCDとは?GitOpsの仕組みとインストール・Sync設定をコード付きで解説:本記事のApplicationを実際に動かすためのインストール手順。
- Flux CDとは?GitOps Toolkitの仕組みとArgo CDとの違いを実装者目線で解説:Fluxの各コントローラの役割とArgo CDとの機能差。
- Gitless GitOpsとは?OCIレジストリ中心のGitOps新方式を仕組み・導入まで解説:Gitの代わりにOCIレジストリを正とする派生方式。
- Helmとは?チャート・リポジトリ・リリースの基本とhelm repo addなど主要コマンド解説:GitOpsで同期するマニフェストをHelmチャートで書く場合の基本。
- イミュータブルインフラとは?サーバーを更新せず作り直す運用の実装と採用判断:GitOpsの前提にある「変更せず置き換える」運用の考え方。