GitOps Flux CDプロダクション実践:Bootstrapからマルチクラスターまで6つのデプロイパターン

DevOps

手動 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の道を選ぶことだ。


おすすめツール

ブラウザローカルツールを無料で試す →

#GitOps#Flux CD#Kubernetes#CI/CD#持续交付#2026#ArgoCD