GitOps Flux CDプロダクション実践:Bootstrapからマルチクラスターまで6つのデプロイパターン
手動 kubectl apply が本番環境を破壊している
深夜3時、アラートが鳴り響く。踏み台サーバーにSSH接続し、kubectl apply -f deployment.yamlを実行。問題は一時的に解決したかに見えた。しかし翌日、昨夜の変更に記録がなく、設定がドリフトし、クラスターでどのバージョンが動いているのか誰も分からないことが発覚する。
これは特殊な事例ではない——従来の運用における日常的な災害だ:
- 設定ドリフト:誰かがConfigMapを直接変更し、Gitの宣言とクラスターの状態が一致しない
- 監査証跡なし:kubectl操作には痕跡が残らず、問題発生時に遡れない
- 緊急ロールバック困難:どのバージョンに戻すべきか不明で、手動で組み立てるしかない
- マルチクラスターの悪夢:3つのクラスター、5つの環境、手動で設定を同期して崩壊
- セキュリティリスク:CIシステムがクラスター管理者の認証情報を保持——漏洩すれば全てが危険に
GitOpsの核心思想:Gitが唯一の信頼できる情報源(Single Source of Truth)。Flux CDはCNCF卒業プロジェクトとして、KubernetesネイティブなGitOpsエンジンであり、プルモードでクラスターの状態を継続的に調和させる。
コア概念一覧
| 概念 | 説明 | 例え |
|---|---|---|
| GitOps | Gitリポジトリを唯一の信頼できる情報源とするインフラ管理手法 | 建築設計図 |
| Flux CD | CNCF卒業のKubernetes GitOpsエンジン | 自動施工隊 |
| Kustomize | Kubernetesネイティブな設定カスタマイズツール、テンプレート不要 | 改装プランの重ね合わせ |
| HelmRelease | Fluxカスタムリソース、宣言的なHelm Chartデプロイ管理 | パッケージマネージャー宣言 |
| Source Controller | Fluxコンポーネント、Git/Helm/OCI/Bucket等のソース管理 | 倉庫管理者 |
| Reconciliation | 期待状態と実際の状態を継続的に比較し自動修復 | 巡検・修正 |
| Progressive Delivery | カナリア/ブルーグリーン/ABテストで段階的にリリース | 段階的に扉を開く |
プロダクション環境が直面する5つの課題
課題1:マルチ環境設定管理の混乱
開発、テスト、ステージング、本番の4環境、それぞれに独立したYAMLコピーがある。1つのパラメータ変更で4ファイルを修正、1つでも見落とせばインシデント。
課題2:Helm Chartバージョンの制御不能
Chartバージョン、valuesファイル、依存関係が散在。1つのChartをアップグレードしてどのサービスに影響するか不明。
課題3:マルチクラスター連携の困難
複数のKubernetesクラスター(パブリッククラウド、プライベートクラウド、エッジノード)、設定を統一管理できず、同期は完全に手動。
課題4:Secretsの平文保存
データベースパスワード、API KeyがYAMLに直接書かれてGitにコミット——甚大なセキュリティリスク。
課題5:段階的リリース能力の欠如
一斉全量デプロイでは、新バージョンに問題があれば全ユーザーに即座に影響し、段階的な検証が不可能。
6つのプロダクションデプロイパターン
パターン1:Flux Bootstrapと初期セットアップ
Flux Bootstrapは全ての基盤——Flux自体もGitOps管理に組み込み、「自己ブートストラップ」を実現する。
# Flux CLIのインストール
curl -s https://fluxcd.io/install.sh | sudo bash
# クラスターの準備確認
flux check --pre
# Bootstrap:FluxをクラスターにインストールしGitリポジトリと連携
flux bootstrap github \
--owner=myorg \
--repository=fleet-infra \
--branch=main \
--path=clusters/production \
--personal=false \
--token-auth
# インストール確認
flux get kustomizations
kubectl get pods -n flux-system
Bootstrap完了後、FluxはGitリポジトリにclusters/production/flux-system/ディレクトリを作成し、全Fluxコンポーネントのマニフェストを含む:
# clusters/production/flux-system/gotk-components.yaml
apiVersion: v1
kind: Namespace
metadata:
name: flux-system
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: flux-system
namespace: flux-system
spec:
interval: 1m0s
ref:
branch: main
secretRef:
name: flux-system
url: ssh://git@github.com/myorg/fleet-infra.git
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: flux-system
namespace: flux-system
spec:
interval: 10m0s
path: ./clusters/production
prune: true
sourceRef:
kind: GitRepository
name: flux-system
# 調和状態の監視
flux get kustomizations --watch
# 即時調和の強制実行
flux reconcile kustomization flux-system --with-source
# ソース状態の確認
flux get sources git
パターン2:Kustomizeオーバーレイによるマルチ環境管理
Kustomizeのbase/overlayパターンを使用——1つの基本設定 + 環境差分オーバーレイで、設定の重複を完全に排除。
fleet-infra/
├── clusters/
│ ├── production/
│ │ └── flux-system/
│ ├── staging/
│ │ └── flux-system/
│ └── development/
│ └── flux-system/
├── apps/
│ ├── base/
│ │ ├── kustomization.yaml
│ │ ├── deployment.yaml
│ │ ├── service.yaml
│ │ └── hpa.yaml
│ ├── overlays/
│ │ ├── production/
│ │ │ ├── kustomization.yaml
│ │ │ ├── deployment-patch.yaml
│ │ │ └── hpa-patch.yaml
│ │ ├── staging/
│ │ │ ├── kustomization.yaml
│ │ │ └── deployment-patch.yaml
│ │ └── development/
│ │ ├── kustomization.yaml
│ │ └── deployment-patch.yaml
# apps/base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
- hpa.yaml
commonLabels:
app.kubernetes.io/managed-by: flux
# apps/base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 2
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web-app
image: myorg/web-app:latest
ports:
- containerPort: 8080
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
env:
- name: LOG_LEVEL
value: "info"
# apps/overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: production
resources:
- ../../base
patches:
- path: deployment-patch.yaml
- path: hpa-patch.yaml
# apps/overlays/production/deployment-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 5
template:
spec:
containers:
- name: web-app
env:
- name: LOG_LEVEL
value: "warn"
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: "1"
memory: 1Gi
# apps/overlays/production/hpa-patch.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-app
spec:
minReplicas: 5
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
# clusters/production/apps.yaml
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: web-app
namespace: flux-system
spec:
interval: 1m0s
ref:
branch: main
url: https://github.com/myorg/web-app-manifests.git
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: web-app-production
namespace: flux-system
spec:
interval: 5m0s
path: ./apps/overlays/production
prune: true
sourceRef:
kind: GitRepository
name: web-app
healthChecks:
- apiVersion: apps/v1
kind: Deployment
name: web-app
namespace: production
timeout: 3m0s
# Kustomizeビルドの検証
flux build kustomization web-app-production \
--path ./apps/overlays/production \
--kustomization-file ./clusters/production/apps.yaml
# 調和状態の確認
flux get kustomizations
パターン3:GitからのHelmRelease宣言型管理
FluxのHelmReleaseにより、Helmデプロイも完全に宣言型に——valuesファイルはGitに保存され、変更が自動的にアップグレードをトリガーする。
# clusters/production/nginx-ingress.yaml
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: ingress-nginx
namespace: flux-system
spec:
interval: 5m0s
url: https://kubernetes.github.io/ingress-nginx
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRelease
metadata:
name: ingress-nginx
namespace: flux-system
spec:
interval: 10m0s
chart:
spec:
chart: ingress-nginx
version: "4.11.x"
sourceRef:
kind: HelmRepository
name: ingress-nginx
interval: 1m0s
valuesFrom:
- kind: ConfigMap
name: ingress-nginx-default-values
- kind: Secret
name: ingress-nginx-sealed-values
valuesKey: values.yaml
values:
controller:
replicaCount: 3
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: "1"
memory: 512Mi
service:
type: LoadBalancer
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: nlb
config:
proxy-body-size: "50m"
proxy-read-timeout: "300"
enable-real-ip: "true"
metrics:
enabled: true
serviceMonitor:
enabled: true
additionalLabels:
release: prometheus
# clusters/production/redis-ha.yaml
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: bitnami
namespace: flux-system
spec:
interval: 5m0s
url: https://charts.bitnami.com/bitnami
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRelease
metadata:
name: redis-ha
namespace: database
spec:
interval: 15m0s
chart:
spec:
chart: redis
version: "19.x"
sourceRef:
kind: HelmRepository
name: bitnami
install:
remediation:
retries: 3
upgrade:
remediation:
retries: 3
remediateLastFailure: true
rollback:
timeout: 5m0s
cleanupOnFail: true
values:
architecture: replication
auth:
existingSecret: redis-secret
existingSecretPasswordKey: password
master:
persistence:
enabled: true
size: 8Gi
storageClass: gp3-encrypted
resources:
requests:
cpu: 250m
memory: 512Mi
replica:
replicaCount: 2
persistence:
enabled: true
size: 8Gi
storageClass: gp3-encrypted
metrics:
enabled: true
serviceMonitor:
enabled: true
# Helmリリース状態の確認
flux get helmreleases --all-namespaces
# HelmReleaseの強制調和
flux reconcile helmrelease redis-ha -n database --with-source
# HelmRelease詳細の確認
flux describe helmrelease redis-ha -n database
# 利用可能なChartバージョンの確認
flux get sources chart --all-namespaces
パターン4:Fluxによるマルチクラスター管理
Fluxはマルチクラスターをネイティブサポート——クラスターごとに1ディレクトリ、アプリケーション設定を共有し、環境変数は独立。
fleet-infra/
├── clusters/
│ ├── production/
│ │ ├── flux-system/
│ │ ├── apps.yaml
│ │ ├── infrastructure.yaml
│ │ └── monitoring.yaml
│ ├── staging/
│ │ ├── flux-system/
│ │ ├── apps.yaml
│ │ └── infrastructure.yaml
│ └── us-east-2/
│ ├── flux-system/
│ ├── apps.yaml
│ └── infrastructure.yaml
├── infrastructure/
│ ├── base/
│ └── overlays/
│ ├── production/
│ ├── staging/
│ └── us-east-2/
└── apps/
├── base/
└── overlays/
# 本番クラスターのBootstrap
flux bootstrap github \
--owner=myorg \
--repository=fleet-infra \
--branch=main \
--path=clusters/production \
--token-auth
# ステージングクラスターのBootstrap
flux bootstrap github \
--owner=myorg \
--repository=fleet-infra \
--branch=main \
--path=clusters/staging \
--token-auth
# リージョンクラスターのBootstrap(異なるコンテキストを使用)
kubectl config use-context us-east-2-admin
flux bootstrap github \
--owner=myorg \
--repository=fleet-infra \
--branch=main \
--path=clusters/us-east-2 \
--token-auth
# clusters/production/infrastructure.yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: infrastructure
namespace: flux-system
spec:
interval: 10m0s
path: ./infrastructure/overlays/production
prune: true
sourceRef:
kind: GitRepository
name: flux-system
dependsOn:
- name: flux-system
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: apps
namespace: flux-system
spec:
interval: 5m0s
path: ./apps/overlays/production
prune: true
sourceRef:
kind: GitRepository
name: flux-system
dependsOn:
- name: infrastructure
healthChecks:
- apiVersion: apps/v1
kind: Deployment
name: ingress-nginx-controller
namespace: ingress-nginx
# clusters/us-east-2/apps.yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: apps
namespace: flux-system
spec:
interval: 5m0s
path: ./apps/overlays/us-east-2
prune: true
sourceRef:
kind: GitRepository
name: flux-system
dependsOn:
- name: infrastructure
postBuildSubstitute:
CLUSTER_REGION: "us-east-2"
CLUSTER_NAME: "prod-us-east-2"
# マルチクラスター調和状態の確認(コンテキスト切替)
kubectl config use-context production-admin
flux get kustomizations
kubectl config use-context staging-admin
flux get kustomizations
# 特定クラスターの調和を一時停止(メンテナンスウィンドウ)
flux suspend kustomization apps
# 調和の再開
flux resume kustomization apps
パターン5:SOPS/sealed-secretsによるSecrets管理
SecretsをGitに平文でコミットしてはならない。FluxはSOPSとsealed-secretsの両方をネイティブに統合している。
オプションA:SOPS + Age
# age暗号化ツールのインストール
curl -sLO https://github.com/FiloSottile/age/releases/latest/download/age-v1.2.0-linux-amd64.tar.gz
tar xzf age-v1.2.0-linux-amd64.tar.gz
sudo mv age/age* /usr/local/bin/
# 鍵ペアの生成
age-keygen -o age.agekey
# 公開鍵の記録
age-keygen -y age.agekey
# 出力例:age1abc123...
# 秘密鍵をクラスターSecretに保存
kubectl create namespace flux-system || true
cat age.agekey | kubectl create secret generic sops-age \
--namespace=flux-system \
--from-file=age.agekey=/dev/stdin \
--dry-run=client -o yaml | kubectl apply -f -
# clusters/production/sops-decryption.yaml
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: flux-system
namespace: flux-system
spec:
interval: 1m0s
ref:
branch: main
secretRef:
name: flux-system
url: ssh://git@github.com/myorg/fleet-infra.git
ignore: |
/**//*.md
/**//*.txt
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: flux-system
namespace: flux-system
spec:
interval: 10m0s
path: ./clusters/production
prune: true
sourceRef:
kind: GitRepository
name: flux-system
decryption:
provider: sops
secretRef:
name: sops-age
# Secretファイルの暗号化
sops --encrypt --age=age1abc123... \
--encrypted-regex '^(data|stringData)$' \
--in-place apps/overlays/production/db-secret.yaml
# 暗号化されたSecretファイル(Gitに安全にコミット可能)
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
namespace: production
type: Opaque
data:
username: ENC[AES256_GCM,data:xxxxxxx,tag:yyyy==,type:str]
password: ENC[AES256_GCM,data:zzzzzzz,tag:wwww==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1abc123...
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
xxxxxxxxxxxxxxxxxxxxxxx
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-06-15T10:00:00Z"
mac: ENC[AES256_GCM,data:mmmmm,tag:nnnn==,type:str]
オプションB:Sealed Secrets
# kubeseal CLIのインストール
curl -sLO https://github.com/bitnami-labs/sealed-secrets/releases/latest/download/kubeseal-linux-amd64
sudo install -m 755 kubeseal-linux-amd64 /usr/local/bin/kubeseal
# クラスターから公開鍵を取得
kubeseal --fetch-cert > sealed-secrets-cert.pem
# SealedSecretの作成
kubectl create secret generic db-credentials \
--namespace=production \
--from-literal=username=admin \
--from-literal=password='S3cur3P@ss!' \
--dry-run=client -o yaml | \
kubeseal --cert sealed-secrets-cert.pem \
--format yaml > apps/overlays/production/db-sealedsecret.yaml
# apps/overlays/production/db-sealedsecret.yaml
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: db-credentials
namespace: production
spec:
encryptedData:
username: AgBfj3k2...シール済みデータ...
password: AgCg7m9x...シール済みデータ...
template:
metadata:
name: db-credentials
namespace: production
type: Opaque
パターン6:Flaggerカナリアによるプログレッシブデリバリー
FlaggerはFluxエコシステムのプログレッシブデリバリーツールで、Istio/NGINX/Skipper等と連携してカナリアデプロイを自動化する。
# Helmを使用したFlaggerのインストール
helm repo add flagger https://flagger.app
helm upgrade --install flagger flagger/flagger \
--namespace=flagger-system \
--create-namespace \
--set meshProvider=istio \
--set metricsServer=http://prometheus.istio-system:9090
# apps/base/canary.yaml
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: web-app
namespace: production
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app
service:
port: 8080
targetPort: 8080
gateways:
- istio-system/public-gateway
hosts:
- web-app.example.com
trafficPolicy:
tls:
mode: DISABLE
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.test/
timeout: 5s
metadata:
cmd: "hey -z 1m -q 10 -c 2 http://web-app.production:8080/"
- name: acceptance-test
type: pre-rollout
url: http://flagger-loadtester.test/
timeout: 30s
metadata:
type: bash
cmd: "curl -sf http://web-app.canary:8080/healthz"
# カナリアデプロイフローの可視化
# 1. 新しいイメージを検出 → Canary Deploymentを作成
# 2. 0% → 10% トラフィック → メトリクス分析
# 3. 10% → 20% トラフィック → メトリクス分析
# 4. 20% → 30% トラフィック → メトリクス分析
# 5. 30% → 40% トラフィック → メトリクス分析
# 6. 40% → 50% トラフィック → メトリクス分析
# 7. 100% トラフィック → 本番バージョンにプロモート
# いずれかの段階でメトリクスが基準を下回る → 自動ロールバック
# カナリア状態の確認
flux get kustomizations --watch
# Flaggerカナリア詳細の確認
kubectl get canary web-app -n production -o yaml
# カナリアの手動トリガー
flux reconcile kustomization apps --with-source
# カナリアイベントの確認
kubectl describe canary web-app -n production
# 強制ロールバック
kubectl patch canary web-app -n production \
-p '{"status":{"phase":"Rollback"}}' --type=merge
5つのよくある落とし穴と正しいアプローチ
落とし穴1:調和間隔設定の無視
❌ 誤った方法:
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: apps
namespace: flux-system
spec:
interval: 1h
sourceRef:
kind: GitRepository
name: flux-system
✅ 正しい方法:
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: apps
namespace: flux-system
spec:
interval: 5m0s
retryInterval: 1m0s
timeout: 3m0s
sourceRef:
kind: GitRepository
name: flux-system
ポイント:
retryIntervalで調和失敗後の迅速なリトライを確保し、timeoutで調和のスタックを防止。
落とし穴2:HelmReleaseのロールバック設定の欠落
❌ 誤った方法:
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRelease
metadata:
name: redis
spec:
chart:
spec:
chart: redis
sourceRef:
kind: HelmRepository
name: bitnami
values:
architecture: replication
✅ 正しい方法:
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRelease
metadata:
name: redis
spec:
install:
remediation:
retries: 3
upgrade:
remediation:
retries: 3
remediateLastFailure: true
rollback:
timeout: 5m0s
cleanupOnFail: true
disableWait: false
uninstall:
keepHistory: true
chart:
spec:
chart: redis
sourceRef:
kind: HelmRepository
name: bitnami
values:
architecture: replication
落とし穴3:Secretの平文Gitコミット
❌ 誤った方法:
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
type: Opaque
stringData:
username: admin
password: S3cur3P@ss!
✅ 正しい方法:
# SOPSで暗号化してからコミット
sops --encrypt --age=age1abc123... \
--encrypted-regex '^(data|stringData)$' \
--in-place secret.yaml
# 暗号化後は安全にコミット可能
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
type: Opaque
data:
username: ENC[AES256_GCM,data:xxx,tag:yyy==,type:str]
password: ENC[AES256_GCM,data:zzz,tag:www==,type:str]
sops:
age:
- recipient: age1abc123...
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
-----END AGE ENCRYPTED FILE-----
落とし穴4:ヘルスチェックの欠落
❌ 誤った方法:
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: apps
namespace: flux-system
spec:
interval: 5m0s
path: ./apps/overlays/production
prune: true
sourceRef:
kind: GitRepository
name: flux-system
✅ 正しい方法:
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: apps
namespace: flux-system
spec:
interval: 5m0s
path: ./apps/overlays/production
prune: true
sourceRef:
kind: GitRepository
name: flux-system
healthChecks:
- apiVersion: apps/v1
kind: Deployment
name: web-app
namespace: production
- apiVersion: apps/v1
kind: Deployment
name: api-server
namespace: production
timeout: 5m0s
落とし穴5:GitRepositoryでHTTPSの代わりにSSHを使用しない
❌ 誤った方法:
flux bootstrap github \
--owner=myorg \
--repository=fleet-infra \
--branch=main \
--path=clusters/production
✅ 正しい方法:
# トークン認証を使用(GitHub推奨)
flux bootstrap github \
--owner=myorg \
--repository=fleet-infra \
--branch=main \
--path=clusters/production \
--token-auth
# またはSSH鍵を使用
ssh-keygen -t ed25519 -C "flux@production" -f flux-ssh-key
flux bootstrap github \
--owner=myorg \
--repository=fleet-infra \
--branch=main \
--path=clusters/production \
--ssh-key-algorithm=ed25519
エラートラブルシューティング早見表
| エラーメッセージ | 原因 | 解決策 |
|---|---|---|
unable to clone repository |
Git認証情報が無効またはネットワーク不通 | Secret内のSSH key/tokenを確認、リポジトリアクセス権を検証 |
artifact fetch failed |
Source Controllerがアーティファクトを取得できない | ネットワークポリシー、プロキシ設定、Source状態を確認 |
dry-run failed, error: resource exists |
リソースの競合、同名リソースが既存 | prune: trueを使用するか、競合リソースを手動でクリーンアップ |
health check failed |
ヘルスチェックタイムアウト、Podが準備未完了 | Podイベントとログを確認、イメージプルと起動を検証 |
chart pull failed |
Helm Chartのプル失敗 | HelmRepositoryのURLと認証情報を確認 |
Helm install failed: timed out |
Helmインストールのタイムアウト | timeoutを増やし、Readiness Probe設定を確認 |
decryption failed |
SOPS復号の失敗 | sops-age Secretの存在と秘密鍵の正確性を確認 |
Kustomization dependency not ready |
依存するKustomizationが準備未完了 | dependsOn設定を確認、依存関係の状態を検証 |
drift detected |
クラスター状態がGit宣言と不一致 | クラスターリソースが手動で変更されていないか確認 |
no matches for kind "HelmRelease" |
CRDがインストールされていない | Helm ControllerのインストールとCRDの登録を確認 |
# 一般的なトラブルシューティングコマンド
flux check # Fluxコンポーネント状態の確認
flux get sources all # 全ソースの確認
flux get kustomizations # Kustomization状態の確認
flux get helmreleases --all-namespaces # HelmRelease状態の確認
flux logs --level=error # Fluxエラーログの確認
flux logs --kind=kustomization --name=apps # 特定リソースのログ確認
# 詳細なトラブルシューティング
kubectl describe gitrepository flux-system -n flux-system
kubectl describe kustomization apps -n flux-system
kubectl logs -n flux-system deploy/kustomize-controller --tail=100
kubectl logs -n flux-system deploy/source-controller --tail=100
kubectl logs -n flux-system deploy/helm-controller --tail=100
高度な最適化
依存関係オーケストレーションとデプロイ順序
FluxのdependsOnは宣言的なデプロイ順序制御を実現し、インフラの準備完了後にアプリケーションをデプロイすることを保証する。
# clusters/production/dependencies.yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: crds
namespace: flux-system
spec:
interval: 10m0s
path: ./infrastructure/crds
prune: true
sourceRef:
kind: GitRepository
name: flux-system
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: infrastructure
namespace: flux-system
spec:
interval: 10m0s
path: ./infrastructure/overlays/production
prune: true
sourceRef:
kind: GitRepository
name: flux-system
dependsOn:
- name: crds
healthChecks:
- apiVersion: apps/v1
kind: Deployment
name: cert-manager
namespace: cert-manager
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: apps
namespace: flux-system
spec:
interval: 5m0s
path: ./apps/overlays/production
prune: true
sourceRef:
kind: GitRepository
name: flux-system
dependsOn:
- name: infrastructure
通知とアラートの統合
Flux Notification Controllerは、調和イベントをSlack、Teams、Discord等にプッシュできる。
# clusters/production/notifications.yaml
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: slack
namespace: flux-system
spec:
type: slack
channel: flux-deployments
secretRef:
name: slack-webhook-url
---
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Alert
metadata:
name: slack-alert
namespace: flux-system
spec:
providerRef:
name: slack
eventSeverity: error
eventSources:
- kind: Kustomization
name: "*"
- kind: HelmRelease
name: "*"
- kind: GitRepository
name: "*"
exclusionList:
- "waiting.*"
- "reconcilation.*in_progress"
---
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Alert
metadata:
name: slack-info
namespace: flux-system
spec:
providerRef:
name: slack
eventSeverity: info
eventSources:
- kind: Kustomization
name: "apps"
summary: "アプリケーションデプロイ通知"
# Slack Webhook Secretの作成
kubectl create secret generic slack-webhook-url \
--namespace=flux-system \
--from-literal=address=https://hooks.slack.com/services/T00/B00/xxx
イメージ自動更新
Flux Image Automationは「コードコミット → イメージビルド → 自動デプロイ」のフルパイプラインを実現する。
# clusters/production/image-automation.yaml
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageRepository
metadata:
name: web-app
namespace: flux-system
spec:
image: myorg/web-app
interval: 1m0s
secretRef:
name: registry-credentials
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImagePolicy
metadata:
name: web-app
namespace: flux-system
spec:
imageRepositoryRef:
name: web-app
policy:
semver:
range: ">=1.0.0 <2.0.0"
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageUpdateAutomation
metadata:
name: web-app
namespace: flux-system
spec:
interval: 1m0s
sourceRef:
kind: GitRepository
name: flux-system
git:
commit:
author:
email: flux@myorg.com
name: Flux Bot
messageTemplate: |
auto: update {{ .AutomationObject }} image
{{ range .Updated.Images -}}
- {{ . }}
{{ end -}}
update:
path: ./apps/overlays/production
strategy: Setters
# apps/overlays/production/deployment-patch.yaml
# setterマーカー — ImageUpdateAutomationが自動的に置換
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
annotations:
# image.fluxcd.io/setters: web-app
spec:
template:
spec:
containers:
- name: web-app
image: myorg/web-app:1.0.0 # {"$imagepolicy": "flux-system:web-app"}
# イメージポリシーの確認
flux get image policies
# イメージリポジトリの確認
flux get image repositories
# 自動更新の確認
flux get image update-auto
# イメージスキャンの手動トリガー
flux reconcile image repository web-app
GitOpsツール比較
| 特徴 | Flux CD | ArgoCD | Jenkins X | Spinnaker |
|---|---|---|---|---|
| コアモデル | Pull | Pull | Push + Pull | Push |
| CNCFステータス | 卒業プロジェクト | 卒業プロジェクト | インキュベーティング | アーカイブ済み |
| マルチクラスター | ネイティブ対応 | ネイティブ対応 | 限定対応 | ネイティブ対応 |
| UIダッシュボード | なし(Weaveworksオプション) | 豊富な内蔵UI | 内蔵 | 豊富な内蔵UI |
| Helmサポート | HelmRelease CRD | Helm + Helmfile | Pipeline | Helm + Bake |
| Kustomize | ネイティブ対応 | ネイティブ対応 | 限定 | なし |
| プログレッシブデリバリー | Flagger(カナリア) | Argo Rollouts | なし | 内蔵ストラテジー |
| Secrets管理 | SOPSネイティブ統合 | Vault/Sealed | Vault | Vault |
| イメージ自動更新 | Image Automation | Image Updater | Pipeline | なし |
| 通知 | Notification Controller | 内蔵 | Pipeline | 内蔵 |
| 学習曲線 | 中 | 低 | 高 | 高 |
| リソース使用量 | 低(~200MB) | 中(~500MB) | 高 | 高 |
| 適用シナリオ | 宣言的ピュアGitOps | ビジュアルGitOps | CI/CDオールインワン | 複雑なリリース戦略 |
| コミュニティ活動 | 高 | 非常に高い | 低 | 低 |
まとめ:Flux CDの設計哲学は「Gitが指示すれば、クラスターが実行する」——UIの干渉も、手動操作の余地もない。宣言的APIと継続的調和により、クラスターの状態が常にGitリポジトリと一致することを保証する。Bootstrapからマルチクラスター、KustomizeからHelmRelease、SOPSからFlaggerまで、6つのパターンがプロダクションGitOpsのあらゆるシナリオをカバーする。Fluxを選ぶことは、純粋で監査可能、自動化されたGitOpsの道を選ぶことだ。
おすすめツール
- JSONフォーマッター — Flux YAML出力をフォーマットし、設定エラーを素早く特定
- Base64エンコード — Kubernetes Secretデータのエンコード
- ハッシュ計算 — 設定ファイルのハッシュを計算し、変更の一貫性を検証
ブラウザローカルツールを無料で試す →