「Kubernetesへのデプロイ、kubectl apply を手動で叩いているか、CI/CDパイプラインにkubeconfigを渡しているという現場はまだまだ多い。でも、それって本当に安全で管理しやすい運用なんだろうか?」
そんな疑問を持ち始めたころに出会うのが「GitOps」という概念です。GitOpsはインフラの状態をGitリポジトリで管理し、Gitへのプッシュがクラスターへの変更を起動するアプローチです。従来のPush型CI/CDとは根本的に仕組みが異なるため、「どこが違うのか」「ArgoCDとFluxはどう使い分けるのか」で迷うエンジニアも多い。
この記事では、GitOpsとPush型CI/CDの違いを構造的に整理し、ArgoCDとFluxの実践比較、EKS・AKSへの導入パターンまでを現場目線で解説します。Kubernetesクラスターをチームで運用し始めたエンジニアに特に読んでほしい内容です。

なぜGitOpsが登場したのか?Push型CI/CDの限界から考える
KubernetesでCI/CDを構築するとき、最初に思いつく方法はシンプルです。Gitにコードをプッシュ → CIがビルド・テスト → CDパイプラインが kubectl apply でマニフェストをクラスターに適用する。いわゆる「Push型」です。
CI/CDの基本設計自体は間違っていません。しかし、Kubernetesクラスターが本番運用に入ると、Push型の弱点が徐々に見えてきます。
・kubeconfigを外部に渡す問題: CIサーバー(GitHub Actions・GitLab CI等)にクラスターの認証情報を持たせる必要があります。この認証情報が漏れると、クラスター全体が危険にさらされます。
・設定ドリフトの見えにくさ: 誰かが緊急対応で手動 kubectl apply をしてしまうと、Gitの状態とクラスターの実際の状態がずれていきます。このずれ(ドリフト)に気づかないまま運用が続くことがあります。
・変更の追跡が分断される: Gitには何を変えたかの履歴がありますが、クラスターに何が適用されているかは別途確認が必要です。GitとKubernetesの状態が「二重帳簿」になりがちです。
GitOpsはこれらの課題に対する答えとして2017年頃に提唱されたアプローチです。「Gitリポジトリをインフラの唯一の正本(Single Source of Truth)とし、クラスターは常にGitの状態に一致させる」という考え方が核心にあります。
GitOpsとPush型CI/CDの本質的な違い
Push型とGitOpsを一言で比べると、「誰がクラスターに変更を加えるか」が逆転します。
1. Push型CI/CDの仕組み
Push型では、CI/CDパイプラインがクラスターに対して能動的に変更を「押し込む」構造です。
# Push型の流れ(概念図) Gitプッシュ → CI(ビルド・テスト・Dockerイメージプッシュ) → CDパイプライン(GitHub Actionsなど) → kubectl apply -f manifest.yaml ← クラスターに「Push」
パイプラインが実行されるたびにクラスターへの認証が必要で、CI側にkubeconfigやサービスアカウントのトークンを保管する必要があります。
2. GitOps(Pull型)の仕組み
GitOpsでは、クラスター内に「オペレーター」と呼ばれるコントローラーが常駐し、Gitリポジトリを定期的に監視(Pull)して、差分があれば自動的にクラスターを同期します。
# GitOps(Pull型)の流れ(概念図) Gitプッシュ → クラスター内オペレーター(ArgoCD / Flux)が変更を検知 → Gitリポジトリからマニフェストを取得(Pull) → クラスターの状態をGitの定義に合わせる
重要な違いは、外部のCI/CDサーバーがクラスターに触る必要がない点です。認証情報がクラスターの外に出ないため、セキュリティ上のリスクが下がります。
3. Push型とGitOpsの比較表
| 観点 | Push型CI/CD | GitOps(Pull型) |
|---|---|---|
| 誰がクラスターを変更するか | 外部のCIパイプライン | クラスター内のオペレーター |
| クラスター認証情報 | CI側に保存(漏洩リスクあり) | クラスター外に出ない |
| ドリフト検知 | 手動確認が必要 | 自動検知・自動修復 |
| 変更の追跡 | GitとCD履歴が分断 | GitがSSoT、完全追跡可能 |
| ロールバック | CDパイプラインの再実行 | Gitのrevert/rollback |
| オフライン時の挙動 | CDパイプラインが止まる | オペレーターが継続稼働 |
| セットアップの複雑さ | 比較的シンプル | オペレーター導入が必要 |
GitOpsが優れているのはセキュリティと状態管理の観点です。一方でPush型は導入の敷居が低く、既存のCI/CDに近い考え方でスタートできる利点があります。
ArgoCDとFlux:2大GitOpsツールの実践比較
GitOpsを実装するツールとして実績があるのがArgoCDとFluxです。どちらもCNCF(Cloud Native Computing Foundation)のプロジェクトであり、Kubernetesへの対応は十分です。ただし設計思想が異なるため、チームや運用スタイルによって向き不向きがあります。
ArgoCD:UIで状態を「見える化」するGitOps
ArgoCDは豊富なWeb UIを持ち、Gitの状態とクラスターの状態の差分を視覚的に確認できます。
・Web UIが充実: アプリケーションの同期状態・ヘルスステータスをブラウザでリアルタイム確認できます。インフラ担当者以外(開発チーム等)にも状態を共有しやすいです。
・ApplicationSetによる大規模管理: 複数チーム・複数クラスターを一元管理できる ApplicationSet が強力で、本番・ステージングへの横展開も効率的です。
・Helm/Kustomize/jsonnet対応: マニフェスト管理ツールの選択肢が多く、既存のHelmチャートをそのまま使えます。
・RBAC・SSO連携: ArgoCDはDex等を使ったSSO、細粒度のRBAC設定をサポートしており、複数チームが同じクラスターを使う場面で役立ちます。
・デメリット: ArgoCDコンポーネント自体のリソース消費がやや大きく、小規模クラスターでは導入コストを感じることがあります。
# ArgoCDのApplicationリソース例 apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: my-app namespace: argocd spec: project: default source: repoURL: https://github.com/your-org/app-manifests targetRevision: main path: overlays/production destination: server: https://kubernetes.default.svc namespace: production syncPolicy: automated: prune: true selfHeal: true
syncPolicy.automated.selfHeal: true を設定すると、手動変更があっても自動的にGitの状態に戻す「ドリフト自動修復」が有効になります。
Flux:軽量・Kustomize統合のGitOps
Flux(v2)はGitOps Toolkitという設計に基づいており、KubernetesカスタムリソースとしてGitOps設定を宣言的に記述します。UIは標準で持ちません(別途Weave GitOps等のUIを組み合わせる)。
・軽量でリソース消費が少ない: ArgoCDより軽く、ノード数の少ない環境でも動かしやすいです。
・Kustomizeとの自然な統合: FluxはKustomizeを一等市民として扱い、オーバーレイ管理がシームレスです。
・ImageAutomation: コンテナイメージの新バージョンが来たとき、Gitのマニフェストを自動更新するImageAutomationコントローラーがあります。
・CLIによる操作: すべてflux CLIベースで管理するため、GitOps操作をスクリプト化・自動化しやすいです。
・デメリット: UIがないため、クラスターの状態確認にはCLIか kubectl が必要です。運用チーム全員がCLIに慣れていることが前提になります。
# FluxのKustomization例 apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: my-app namespace: flux-system spec: interval: 5m path: "./overlays/production" prune: true sourceRef: kind: GitRepository name: app-manifests targetNamespace: production
interval: 5m で5分ごとにGitと同期を取り、prune: true でGitに存在しないリソースは自動的に削除します。
ArgoCD vs Flux の選択基準
| チームの状況・重視点 | 推奨ツール |
|---|---|
| 開発チームにも状態を見せたい・UIを重視 | ArgoCD |
| 複数クラスター・複数チームの大規模管理 | ArgoCD(ApplicationSet) |
| 軽量に始めたい・Kustomize主体の管理 | Flux |
| CLIベースの自動化・スクリプト化が重要 | Flux |
| イメージの自動更新をGitに反映させたい | Flux(ImageAutomation) |
| Helm重視で既存チャートをそのまま使いたい | どちらも可(ArgoCDの方がUI連携が充実) |
AWS EKS・Azure AKSへのGitOps実装パターン
1. Amazon EKSにArgoCDを導入する基本構成
Amazon EKSでは、ArgoCDをHelm経由でインストールするのが一般的です。IAM Roles for Service Accounts(IRSA)を使えば、ArgoCDのPodsに対してAWS権限を適切に付与できます。
# EKSにArgoCDをHelmでインストール(kubectl) kubectl create namespace argocd helm repo add argo https://argoproj.github.io/argo-helm helm install argocd argo/argo-cd \ --namespace argocd \ --set configs.params."server\.insecure"=true # 初期adminパスワード取得 kubectl -n argocd get secret argocd-initial-admin-secret \ -o jsonpath="{.data.password}" | base64 -d
本番環境では server.insecure=true の代わりにALB Ingress ControllerとTLS終端を組み合わせることを強くすすめます。
GitHubリポジトリとの連携には、ArgoCDのSSH鍵認証またはGitHub Appを使うのが安全です。GitHub ActionsでDockerイメージをビルドしてECRにプッシュし、マニフェストリポジトリのイメージタグを更新したらArgoCDが自動同期する、というパターンが定番です。CI側のAWS認証にはAWS OIDC認証を使うと、アクセスキーをCI側に保管せずに済みます。
2. Azure AKSにFluxを導入する基本構成
Azure AKSはFlux v2をAzureの拡張機能(GitOps extension)として有効化できます。az CLIから有効にすることで、マネージドな形でFluxを使えます。
# AKS GitOps拡張機能の有効化(Azure CLI) az extension add -n k8s-configuration az extension add -n k8s-extension # GitOps設定の作成 az k8s-configuration flux create \ --resource-group myRG \ --cluster-name myAKS \ --cluster-type managedClusters \ --name my-app-config \ --namespace flux-system \ --scope cluster \ --url https://github.com/your-org/app-manifests \ --branch main \ --kustomization name=production path=./overlays/production prune=true
Azure Arc経由でオンプレクラスターやAKS以外のクラスターにも同じGitOps設定を展開できるため、マルチクラスター管理を想定している場合は特に有効なアプローチです。
GitOps導入でよくはまるポイント
1. アプリリポジトリとマニフェストリポジトリは分けるべきか?
GitOpsでよくある問いが「アプリのコードとKubernetesマニフェストを同じリポジトリに置くか、別にするか」です。
一般的なベストプラクティスは分離です。
・アプリリポジトリ: アプリのソースコード・Dockerfile・テスト。CIがここをトリガーし、イメージをビルドしてレジストリにプッシュします。
・マニフェストリポジトリ: KubernetesのYAMLやHelmの values.yaml。ArgoCDやFluxがここを監視します。
分離することで、インフラ変更(レプリカ数の変更、リソース制限の調整)のPRとアプリ変更のPRが混在せず、変更の意図と影響範囲が明確になります。
2. ドリフト自動修復は緊急対応時に要注意
selfHeal: true(ArgoCD)や prune: true(Flux)を有効にすると、手動でクラスターに加えた変更は数分以内にGitの状態に戻されます。これは設定ドリフトを防ぐ強力な機能ですが、インシデント対応中に「手でリソースを変更したのになぜ戻るんだ」という混乱を招くことがあります。
緊急対応のワークフローとして、一時的にselfHealを無効化するか同期を一時停止する手順をRunbookに明記しておくことを強くすすめます。ArgoCDであればアプリを「Suspended」状態にする操作、Fluxであれば flux suspend kustomization my-app を使います。
3. シークレット管理はGitOpsの外側で扱う
Gitにパスワードやトークンをそのままコミットするのは禁物です。GitOps環境ではSealed Secrets(Bitnami)やExternal Secrets Operatorを組み合わせて、シークレットをGitに安全に扱う仕組みが必要です。
AWS環境ならAWS Secrets ManagerをExternal Secrets OperatorでKubernetes Secretとして同期させる構成が実績あります。Azure環境ではAzure Key VaultをAKS Secrets Store CSI Driverで参照させる方法が広く使われています。
4. GitOpsはインフラ管理(Terraform)とは役割が違う
「GitOpsがあればTerraformは不要?」という誤解も現場でよく聞きます。
役割は明確に分かれます。TerraformはEKSクラスター自体・VPC・IAMロールなどのクラウドインフラを管理するツールであり、GitOps(ArgoCD/Flux)はクラスター内に何を動かすかというKubernetesリソースを管理するツールです。この2層の組み合わせが現時点では最も安定した構成です。

本記事のまとめ
GitOpsはPush型CI/CDの弱点——クラスター認証情報の外部流出リスク・ドリフトの見えにくさ・変更追跡の分断——を解消する設計アプローチです。Gitを「唯一の正本」として、クラスター内のオペレーターがPull型で状態を合わせ続ける仕組みが核心です。
・ArgoCDを選ぶ場面: Web UIで状態を共有したい・複数クラスターをApplicationSetで管理したい・Helm中心の現場
・Fluxを選ぶ場面: 軽量に始めたい・Kustomize主体・イメージの自動更新をGit連携させたい・CLIベースの自動化重視
・Push型が向く場面: Kubernetesを使わないデプロイ・小規模なチームで素早く始めたい場合
どちらのツールを選んでも、マニフェストリポジトリを分離してシークレット管理をExternal Secrets等で補完することが、安定したGitOps運用の前提条件です。まずは開発環境のKubernetesにArgoCDかFluxを入れてみて、宣言的デプロイの感覚をつかんでください。
PR
Kubernetes完全ガイド 第2版(青山真也/インプレス)
ArgoCDやFluxの前提知識となるKubernetesのアーキテクチャ・リソース設計を体系的に学べる定番書。本番運用を見据えたセキュリティ・スケーリング設計まで網羅しています。
