- Published on
GitOps 実践ガイド: ArgoCD vs FluxCD アーキテクチャ比較とプロダクション デプロイ戦略
- Authors
- Name
- はじめに
- ArgoCD アーキテクチャ 深層分析
- FluxCD アーキテクチャ 深層分析
- ArgoCD vs FluxCD 比較表
- デプロイ戦略
- シークレット管理
- CI/CD統合パターン
- 障害事例と復旧手順
- プロダクションデプロイチェックリスト
- まとめ
- 参考資料

はじめに
現代のクラウドネイティブ環境において、Kubernetesデプロイを管理する方法は大きくPushベースとPullベースに分かれる。従来のCI/CDパイプラインはPush方式で、ビルド完了後にkubectl applyやhelm upgradeを実行してクラスターに変更をプッシュする。この方式はCIサーバーにクラスターアクセス権限を付与する必要があり、手動変更(kubectl edit、コンソール修正)によるドリフトの検出が困難という根本的な限界がある。
GitOpsはこの問題を解決する運用パラダイムで、Gitリポジトリを**単一の信頼できるソース(Single Source of Truth)とし、クラスター内部のエージェントがGitの望ましい状態と実際の状態を継続的に比較して自動的に同期(Reconciliation)**する。OpenGitOpsプロジェクトが定義した核心原則は以下の通りである。
- 宣言的(Declarative): システムの望ましい状態を宣言的に記述する
- バージョン管理(Versioned and Immutable): すべての変更履歴がGitに残り、監査追跡が可能
- 自動適用(Pulled Automatically): エージェントが自動的に望ましい状態をクラスターに適用する
- 継続的調整(Continuously Reconciled): ドリフトを自動的に検出して修正する
本記事では、GitOpsを実装する代表的な2つのツールであるArgoCDとFluxCDのアーキテクチャを深層比較し、実際のプロダクション環境でのデプロイ戦略、シークレット管理、CI/CD統合、障害事例と復旧、運用チェックリストまで総合的に解説する。
ArgoCD アーキテクチャ 深層分析
中核コンポーネント
ArgoCDはCNCF Graduatedプロジェクトで、Kubernetes専用のGitOps継続的デプロイツールである。デフォルトでWeb UI、CLI、gRPC/REST APIを提供する。
# ArgoCD Application リソース例
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/org/k8s-manifests.git
targetRevision: main
path: apps/my-app/overlays/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
allowEmpty: false
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground
- PruneLast=true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
ArgoCDの主要コンポーネントは以下の通りである。
- API Server: Web UI、CLI、CI/CDシステムが使用するgRPC/REST APIを提供
- Repo Server: Gitリポジトリをクローンしてマニフェストを生成。Helm、Kustomize、Jsonnetなどをサポート
- Application Controller: Applicationリソースを監視して調整ループを実行
- Redis: UIセッションとキャッシュを保存
- Dex: SSO(Single Sign-On)認証を担当
- Notifications Controller: Slack、メールなどで同期状態通知を送信
App of Apps パターン
大規模環境ではApp of Appsパターンを使用して、複数のApplicationを1つの親Applicationで管理する。
# 親Application (root-app)
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: root-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/org/k8s-manifests.git
targetRevision: main
path: apps
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
appsディレクトリ内に各サービスのApplication YAMLファイルを配置すると、root-appが自動的にこれを作成・管理する。
ApplicationSet コントローラー
ApplicationSetは1つのテンプレートから複数のApplicationを動的に生成する。マルチクラスター、マルチテナント、モノレポ環境で非常に有用である。
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: cluster-apps
namespace: argocd
spec:
generators:
- clusters:
selector:
matchLabels:
environment: production
template:
metadata:
name: 'app-{{name}}'
spec:
project: default
source:
repoURL: https://github.com/org/k8s-manifests.git
targetRevision: main
path: 'apps/{{metadata.labels.region}}/production'
destination:
server: '{{server}}'
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
このApplicationSetはenvironment: productionラベルを持つすべてのクラスターに対して自動的にApplicationを生成する。
Sync Wavesとフック
ArgoCDのSync Waveはリソースデプロイ順序を精密に制御する。
# Wave 0: NamespaceとRBACを最初に作成
apiVersion: v1
kind: Namespace
metadata:
name: production
annotations:
argocd.argoproj.io/sync-wave: '0'
---
# Wave 1: ConfigMapとSecret
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: production
annotations:
argocd.argoproj.io/sync-wave: '1'
data:
DATABASE_HOST: 'postgres.production.svc'
LOG_LEVEL: 'info'
---
# Wave 2: Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-server
namespace: production
annotations:
argocd.argoproj.io/sync-wave: '2'
spec:
replicas: 3
selector:
matchLabels:
app: api-server
template:
metadata:
labels:
app: api-server
spec:
containers:
- name: api-server
image: myregistry/api-server:v2.1.0
ports:
- containerPort: 8080
---
# PreSyncフック: DBマイグレーション
apiVersion: batch/v1
kind: Job
metadata:
name: db-migration
namespace: production
annotations:
argocd.argoproj.io/hook: PreSync
argocd.argoproj.io/hook-delete-policy: HookSucceeded
spec:
template:
spec:
containers:
- name: migrate
image: myregistry/db-migrate:v2.1.0
command: ['./migrate', 'up']
restartPolicy: Never
FluxCD アーキテクチャ 深層分析
中核コンポーネント
FluxCDはCNCF Graduatedプロジェクトで、KubernetesネイティブのGitOpsツールキットである。複数の独立したコントローラーで構成されている。
- Source Controller: Gitリポジトリ、Helmリポジトリ、OCIアーティファクト、S3バケットなどのソースを管理
- Kustomize Controller: Kustomizationリソースを監視してクラスターにマニフェストを適用
- Helm Controller: HelmReleaseリソースを監視してHelmチャートを管理
- Notification Controller: イベント通知と外部Webhook受信を処理
- Image Reflector/Automation Controllers: コンテナレジストリの新しいイメージを検知し、自動的にGitを更新
GitRepositoryとKustomization
FluxCDの基本ワークフローは、GitRepositoryでソースを定義し、Kustomizationで適用方法を記述することである。
# ソース定義
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: k8s-manifests
namespace: flux-system
spec:
interval: 1m
url: https://github.com/org/k8s-manifests.git
ref:
branch: main
secretRef:
name: git-credentials
ignore: |
# 不要なファイルを除外
docs/
README.md
---
# 適用定義
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: production-apps
namespace: flux-system
spec:
interval: 5m
retryInterval: 2m
timeout: 3m
sourceRef:
kind: GitRepository
name: k8s-manifests
path: ./apps/production
prune: true
force: false
targetNamespace: production
healthChecks:
- apiVersion: apps/v1
kind: Deployment
name: api-server
namespace: production
postBuild:
substituteFrom:
- kind: ConfigMap
name: cluster-vars
HelmReleaseコントローラー
FluxCDのHelm ControllerはHelmRelease CRDを通じてHelmチャートのライフサイクルを宣言的に管理する。
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: bitnami
namespace: flux-system
spec:
interval: 30m
url: https://charts.bitnami.com/bitnami
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: postgresql
namespace: production
spec:
interval: 10m
chart:
spec:
chart: postgresql
version: '15.x'
sourceRef:
kind: HelmRepository
name: bitnami
namespace: flux-system
values:
primary:
persistence:
size: 50Gi
resources:
requests:
memory: 512Mi
cpu: 250m
metrics:
enabled: true
upgrade:
remediation:
retries: 3
remediateLastFailure: true
rollback:
cleanupOnFail: true
timeout: 5m
FluxCD 依存関係管理
Kustomizationリソース間の依存関係を宣言してデプロイ順序を制御できる。
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: infrastructure
namespace: flux-system
spec:
interval: 10m
sourceRef:
kind: GitRepository
name: k8s-manifests
path: ./infrastructure
prune: true
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: applications
namespace: flux-system
spec:
interval: 10m
dependsOn:
- name: infrastructure
sourceRef:
kind: GitRepository
name: k8s-manifests
path: ./applications
prune: true
infrastructure Kustomizationが正常に適用された後にのみapplicationsが適用される。
ArgoCD vs FluxCD 比較表
| 項目 | ArgoCD | FluxCD |
|---|---|---|
| CNCFステータス | Graduated | Graduated |
| Web UI | O(内蔵、豊富な機能) | X(別途Weave GitOps UIを使用) |
| CLI | argocd CLI | flux CLI |
| アーキテクチャ | モノリシック(複数コンポーネントが一体) | マイクロサービス(独立コントローラー) |
| CRD | Application, ApplicationSet, AppProject | GitRepository, Kustomization, HelmReleaseなど |
| マルチクラスター | ハブ・スポークモデル | クラスターごとにFluxをインストール |
| Helmサポート | O(ソースとして直接参照) | O(HelmRelease CRD) |
| Kustomize | O | O(ネイティブ) |
| RBAC | 独自RBAC + SSO統合 | KubernetesネイティブRBAC |
| 通知 | Notification Controller | Notification Controller |
| イメージ自動更新 | Image Updater(別途インストール) | Image Automation Controller |
| ドリフト検出 | O(リアルタイムUI表示) | O(イベントベース) |
| 同期順序 | Sync Wave + フック | dependsOn依存関係 |
| SSOサポート | O(Dex内蔵) | X(Kubernetes RBACに委譲) |
| マルチテナンシー | AppProjectベース | ネームスペースベース |
| Git対応 | GitHub, GitLab, Bitbucketなど | GitHub, GitLab, Bitbucket, S3, OCIなど |
| 学習曲線 | 中程度(UIが助けになる) | 高め(CLI中心) |
| リソース使用量 | 比較的高い | 比較的低い |
デプロイ戦略
Blue-Greenデプロイ(Argo Rollouts)
ArgoCDと共にArgo Rolloutsを使用すると、Blue-Greenデプロイを宣言的に実装できる。
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: api-server
namespace: production
spec:
replicas: 5
strategy:
blueGreen:
activeService: api-server-active
previewService: api-server-preview
autoPromotionEnabled: false
prePromotionAnalysis:
templates:
- templateName: success-rate
args:
- name: service-name
value: api-server-preview
scaleDownDelaySeconds: 30
selector:
matchLabels:
app: api-server
template:
metadata:
labels:
app: api-server
spec:
containers:
- name: api-server
image: myregistry/api-server:v2.2.0
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
---
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: success-rate
namespace: production
spec:
args:
- name: service-name
metrics:
- name: success-rate
interval: 30s
count: 5
successCondition: result[0] >= 0.95
provider:
prometheus:
address: http://prometheus.monitoring:9090
query: |
sum(rate(http_requests_total{service="{{args.service-name}}",status=~"2.."}[5m])) /
sum(rate(http_requests_total{service="{{args.service-name}}"}[5m]))
Canaryデプロイ(Flagger + FluxCD)
FluxCD環境ではFlaggerを使用してCanaryデプロイを自動化する。
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: api-server
namespace: production
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: api-server
service:
port: 8080
targetPort: 8080
analysis:
interval: 1m
threshold: 5
maxWeight: 50
stepWeight: 10
metrics:
- name: request-success-rate
thresholdRange:
min: 99
interval: 1m
- name: request-duration
thresholdRange:
max: 500
interval: 1m
webhooks:
- name: load-test
type: rollout
url: http://flagger-loadtester.production/
metadata:
cmd: 'hey -z 1m -q 10 -c 2 http://api-server-canary.production:8080/'
シークレット管理
SOPS(Secrets OPerationS)
SOPSはファイルレベルでシークレットを暗号化してGitに安全に保存するツールである。FluxCDはSOPSをネイティブにサポートする。
# .sops.yaml(リポジトリルートに配置)
creation_rules:
- path_regex: .*.enc.yaml
encrypted_regex: '^(data|stringData)$'
age: age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# シークレット暗号化
sops --encrypt --in-place secrets/production/db-credentials.enc.yaml
# FluxCD KustomizationでSOPS復号化を有効化
flux create kustomization production-secrets \
--source=GitRepository/k8s-manifests \
--path="./secrets/production" \
--prune=true \
--interval=10m \
--decryption-provider=sops \
--decryption-secret=sops-age
Sealed Secrets
Sealed Secretsは非対称暗号化を使用してシークレットをGitに安全に保存する。
# SealedSecret作成
kubectl create secret generic db-credentials \
--from-literal=username=admin \
--from-literal=password=supersecret \
--dry-run=client -o yaml | \
kubeseal --controller-name=sealed-secrets \
--controller-namespace=kube-system \
--format=yaml > sealed-db-credentials.yaml
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: db-credentials
namespace: production
spec:
encryptedData:
username: AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq...
password: AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq...
template:
type: Opaque
metadata:
name: db-credentials
namespace: production
Vault統合(ArgoCD Vault Plugin)
HashiCorp VaultとArgoCDを統合してシークレットを動的に注入する。
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
namespace: production
annotations:
avp.kubernetes.io/path: 'secret/data/production/database'
type: Opaque
stringData:
username: <username>
password: <password>
上記のマニフェストで<username>と<password>は、ArgoCD Vault PluginがVaultから値を取得して実際のシークレット値に置き換えるプレースホルダーである。
CI/CD統合パターン
GitHub Actions + ArgoCD
# .github/workflows/deploy.yml
name: Build and Deploy
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build and Push Image
run: |
docker build -t myregistry/api-server:$GITHUB_SHA .
docker push myregistry/api-server:$GITHUB_SHA
- name: Update Kubernetes Manifests
run: |
git clone https://github.com/org/k8s-manifests.git
cd k8s-manifests
kustomize edit set image myregistry/api-server=myregistry/api-server:$GITHUB_SHA
git add .
git commit -m "chore: update api-server image to $GITHUB_SHA"
git push
このパターンでは、CI(GitHub Actions)はイメージビルドとマニフェストリポジトリの更新のみを担当し、実際のデプロイはArgoCDがGit変更を検知して自動的に実行する。
障害事例と復旧手順
事例1: Sync Loop(無限同期ループ)
状況: ArgoCD ApplicationがSync完了後、即座にOutOfSync状態に遷移し、無限同期ループに陥った。原因はAdmission Webhookがリソースにデフォルト値を注入し、Gitのマニフェストとの差分が発生したことだった。
症状:
- Application状態がSyncedとOutOfSyncを繰り返す
- ArgoCD API Server CPU使用量が急増
- Repo Serverメモリ使用量が増加
復旧手順:
# 1. 自動同期を一時停止
argocd app set my-app --sync-policy none
# 2. ドリフト原因を分析
argocd app diff my-app --local ./manifests/
# 3. ignoreDifferences設定でWebhook注入フィールドを無視
argocd app set my-app --ignore-differences \
'group=apps, kind=Deployment, jsonPointers=[/spec/template/metadata/annotations]'
# 4. マニフェストにWebhookが注入するデフォルト値を明示的に追加
# 5. 自動同期を再有効化
argocd app set my-app --sync-policy automated
事例2: ドリフト検出の失敗
状況: FluxCDのKustomizationが成功状態を報告しているが、実際のクラスターで手動変更されたリソースが復元されなかった。forceオプションが無効化されており、手動変更がFluxCDが管理しないフィールドで発生していた。
症状:
- Kustomization状態はReady
- 実際のリソース設定がGitと異なる
- kubectl diffで差分を確認可能
復旧手順:
# 1. FluxCD強制調整をトリガー
flux reconcile kustomization production-apps --with-source
# 2. forceオプションを有効化(server-side applyを使用)
flux create kustomization production-apps \
--source=GitRepository/k8s-manifests \
--path="./apps/production" \
--prune=true \
--force=true \
--interval=5m
# 3. 手動変更防止のためのOPAポリシーを追加
# (kubectl edit, kubectl patchなどを制限)
事例3: Helm Releaseロールバック失敗
状況: FluxCD HelmReleaseのアップグレードが失敗したが、自動ロールバックが動作しなかった。remediation設定でremediateLastFailureがfalseになっていた。
症状:
- HelmRelease状態がFailed
- 以前のバージョンのリリースも破損
- Helm historyにfailedリリースが蓄積
復旧手順:
# 1. HelmRelease状態確認
flux get helmrelease -n production
# 2. Helmリリース履歴確認
helm history postgresql -n production
# 3. 手動ロールバック
helm rollback postgresql 3 -n production
# 4. HelmRelease設定に自動復旧を追加
flux create helmrelease postgresql \
--source=HelmRepository/bitnami \
--chart=postgresql \
--chart-version="15.x" \
--target-namespace=production \
--values=values/postgresql.yaml \
--remediation-retries=3
プロダクションデプロイチェックリスト
事前準備
- Gitリポジトリ構造を設計(モノレポ vs ポリレポの決定)
- ブランチ戦略を策定(main -> staging -> production)
- RBACポリシーを設計(どのチームがどのApplication/Kustomizationを管理するか)
- シークレット管理方法を決定(SOPS、Sealed Secrets、Vaultから選択)
ArgoCD設定
- HA(高可用性)モードでデプロイ(最低3レプリカ)
- Redis SentinelまたはRedis Clusterを構成
- DexまたはOIDCによるSSO設定
- AppProjectごとにソースリポジトリとターゲットクラスターを制限
- Resource Exclusions/Inclusions設定で管理範囲を明確化
FluxCD設定
- 各クラスターに独立したFluxCDをインストール
- Source ControllerのGitポーリング間隔を最適化(デフォルト1分)
- Kustomizationのヘルスチェック対象リソースを指定
- Notification ControllerでSlack/Teams通知を構成
運用上の注意事項
- Gitリポジトリのwrite権限を最小化(PRベースの変更)
- プロダクションデプロイは必ずPRレビュー後にマージ
- 同期間隔とタイムアウトをワークロード特性に合わせて調整
- 大規模マニフェスト変更時はSync WaveやdependsOnで順序を保証
- Helmチャートバージョンは範囲ではなく固定バージョンで指定
- ロールバックのためのGit revertプロセスを文書化
モニタリング
- ArgoCD: Application同期状態メトリクスを収集(
argocd_app_info) - FluxCD: Kustomization/HelmRelease状態メトリクスを収集
- 同期失敗時の自動アラートを設定(PagerDuty、OpsGenie連携)
- 定期的なドリフト監査レポートを生成
まとめ
GitOpsはKubernetesデプロイ管理の標準として定着した。ArgoCDとFluxCDはともにCNCF Graduatedプロジェクトとして成熟したエコシステムを備えており、どちらのツールを選択してもGitOpsの核心原則を忠実に実装できる。
ArgoCDは豊富なWeb UIとApplicationSetによるマルチクラスター管理、Argo Rolloutsとの統合を強みとする。FluxCDはKubernetesネイティブなマイクロサービスアーキテクチャ、軽量なリソース使用量、SOPSのネイティブサポートを強みとする。
重要なのはツールの選択よりもGitOps文化の定着である。すべての変更がGitを通じて行われるようにプロセスを確立し、手動変更を防ぐガードレールを構築し、ドリフトを継続的に検出・修正する自動化体制を整えることが、真のGitOpsの完成である。