コンテンツにスキップ

FluxCD Cheat Sheet

Overview

FluxCD is a set of continuous and progressive delivery solutions for Kubernetes that are open and extensible. It implements GitOps principles to automatically deploy applications and infrastructure changes from Git repositories to Kubernetes clusters, providing declarative, version-controlled, and auditable deployments.

⚠️ Note: Free and open-source. Part of the CNCF (Cloud Native Computing Foundation).

Installation

Prerequisites

# Required tools
kubectl version --client
git --version
curl --version

# Verify Kubernetes cluster access
kubectl cluster-info
kubectl get nodes

# Check cluster permissions
kubectl auth can-i create namespaces
kubectl auth can-i create customresourcedefinitions

Flux CLI Installation

# Linux/macOS
curl -s https://fluxcd.io/install.sh | sudo bash

# macOS with Homebrew
brew install fluxcd/tap/flux

# Windows with Chocolatey
choco install flux

# Windows with Scoop
scoop bucket add flux https://github.com/fluxcd/scoop-bucket
scoop install flux

# Verify installation
flux version --client

Bootstrap Flux

# GitHub bootstrap
export GITHUB_TOKEN=<your-token>
export GITHUB_USER=<your-username>

flux bootstrap github \
  --owner=$GITHUB_USER \
  --repository=fleet-infra \
  --branch=main \
  --path=./clusters/my-cluster \
  --personal

# GitLab bootstrap
export GITLAB_TOKEN=<your-token>

flux bootstrap gitlab \
  --owner=$GITLAB_USER \
  --repository=fleet-infra \
  --branch=main \
  --path=./clusters/my-cluster

# Generic Git bootstrap
flux bootstrap git \
  --url=ssh://git@example.com/my-org/my-fleet \
  --branch=main \
  --path=clusters/my-cluster

Manual Installation

# Install Flux components manually
flux install --export > flux-system.yaml
kubectl apply -f flux-system.yaml

# Verify installation
flux check
kubectl get pods -n flux-system

Core Components

Source Controller

# GitRepository source
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
  name: podinfo
  namespace: flux-system
spec:
  interval: 1m
  ref:
    branch: master
  url: https://github.com/stefanprodan/podinfo
---
# HelmRepository source
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: HelmRepository
metadata:
  name: bitnami
  namespace: flux-system
spec:
  interval: 1m
  url: https://charts.bitnami.com/bitnami
---
# Bucket source (S3, GCS, Azure Blob)
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: Bucket
metadata:
  name: artifacts
  namespace: flux-system
spec:
  interval: 1m
  provider: aws
  bucketName: my-artifacts
  endpoint: s3.amazonaws.com
  region: us-east-1

Kustomize Controller

# Kustomization
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: podinfo
  namespace: flux-system
spec:
  interval: 5m
  path: "./kustomize"
  prune: true
  sourceRef:
    kind: GitRepository
    name: podinfo
  validation: client
  healthChecks:
    - apiVersion: apps/v1
      kind: Deployment
      name: podinfo
      namespace: default
  timeout: 2m

Helm Controller

# HelmRelease
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
  name: nginx-ingress
  namespace: flux-system
spec:
  interval: 5m
  chart:
    spec:
      chart: nginx-ingress
      version: "4.0.6"
      sourceRef:
        kind: HelmRepository
        name: bitnami
        namespace: flux-system
  values:
    service:
      type: LoadBalancer
    metrics:
      enabled: true
  upgrade:
    remediation:
      retries: 3

Notification Controller

# Provider (Slack)
apiVersion: notification.toolkit.fluxcd.io/v1beta1
kind: Provider
metadata:
  name: slack
  namespace: flux-system
spec:
  type: slack
  channel: general
  secretRef:
    name: slack-webhook
---
# Alert
apiVersion: notification.toolkit.fluxcd.io/v1beta1
kind: Alert
metadata:
  name: on-call-webhook
  namespace: flux-system
spec:
  providerRef:
    name: slack
  eventSeverity: info
  eventSources:
    - kind: GitRepository
      name: '*'
    - kind: Kustomization
      name: '*'

GitOps Workflow

Repository Structure

# Recommended GitOps repository structure
fleet-infra/
├── apps/
│   ├── base/
│   │   ├── podinfo/
│   │   │   ├── kustomization.yaml
│   │   │   ├── deployment.yaml
│   │   │   └── service.yaml
│   │   └── nginx/
│   └── production/
│       ├── kustomization.yaml
│       └── podinfo-patch.yaml
├── infrastructure/
│   ├── controllers/
│   │   ├── kustomization.yaml
│   │   └── ingress-nginx.yaml
│   └── configs/
│       ├── kustomization.yaml
│       └── cluster-config.yaml
└── clusters/
    └── production/
        ├── flux-system/
        │   ├── gotk-components.yaml
        │   ├── gotk-sync.yaml
        │   └── kustomization.yaml
        ├── apps.yaml
        └── infrastructure.yaml

Multi-Environment Setup

# clusters/staging/apps.yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: apps
  namespace: flux-system
spec:
  interval: 10m
  sourceRef:
    kind: GitRepository
    name: flux-system
  path: ./apps/staging
  prune: true
  validation: client
---
# clusters/production/apps.yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: apps
  namespace: flux-system
spec:
  interval: 10m
  sourceRef:
    kind: GitRepository
    name: flux-system
  path: ./apps/production
  prune: true
  validation: client
  healthChecks:
    - apiVersion: apps/v1
      kind: Deployment
      name: podinfo
      namespace: podinfo

Progressive Delivery

# Canary deployment with Flagger
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
  name: podinfo
  namespace: test
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: podinfo
  progressDeadlineSeconds: 60
  service:
    port: 9898
    targetPort: 9898
    gateways:
    - public-gateway.istio-system.svc.cluster.local
    hosts:
    - app.example.com
  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: 30s

CLI Commands

Basic Commands

# Check Flux installation
flux check

# Get system status
flux get all

# Get sources
flux get sources all
flux get sources git
flux get sources helm

# Get Kustomizations
flux get kustomizations

# Get Helm releases
flux get helmreleases

# Suspend/resume reconciliation
flux suspend kustomization podinfo
flux resume kustomization podinfo

Source Management

# Create Git source
flux create source git podinfo \
  --url=https://github.com/stefanprodan/podinfo \
  --branch=master \
  --interval=1m \
  --export > podinfo-source.yaml

# Create Helm source
flux create source helm bitnami \
  --url=https://charts.bitnami.com/bitnami \
  --interval=1m

# Update source
flux reconcile source git podinfo

# Delete source
flux delete source git podinfo

Kustomization Management

# Create Kustomization
flux create kustomization podinfo \
  --target-namespace=default \
  --source=podinfo \
  --path="./kustomize" \
  --prune=true \
  --interval=5m

# Reconcile Kustomization
flux reconcile kustomization podinfo

# Get Kustomization status
flux get kustomization podinfo

# Suspend Kustomization
flux suspend kustomization podinfo

Helm Management

# Create Helm release
flux create helmrelease nginx-ingress \
  --source=HelmRepository/bitnami \
  --chart=nginx-ingress \
  --target-namespace=ingress-nginx \
  --create-target-namespace=true

# Upgrade Helm release
flux reconcile helmrelease nginx-ingress

# Get Helm release status
flux get helmreleases

# Delete Helm release
flux delete helmrelease nginx-ingress

Advanced Configuration

Multi-Tenancy

# Tenant namespace and RBAC
apiVersion: v1
kind: Namespace
metadata:
  name: tenant-a
  labels:
    toolkit.fluxcd.io/tenant: tenant-a
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: tenant-a-reconciler
  namespace: tenant-a
subjects:
- kind: ServiceAccount
  name: kustomize-controller
  namespace: flux-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
---
# Tenant Kustomization
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: tenant-a-apps
  namespace: flux-system
spec:
  interval: 5m
  sourceRef:
    kind: GitRepository
    name: tenant-a-repo
  path: "./apps"
  prune: true
  targetNamespace: tenant-a
  serviceAccountName: tenant-a-reconciler

Secret Management

# Sealed Secrets integration
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  name: mysecret
  namespace: default
spec:
  encryptedData:
    password: AgBy3i4OJSWK+PiTySYZZA9rO43cGDEQAx...
---
# External Secrets Operator
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: vault-backend
  namespace: default
spec:
  provider:
    vault:
      server: "https://vault.example.com"
      path: "secret"
      version: "v2"
      auth:
        kubernetes:
          mountPath: "kubernetes"
          role: "example"
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: vault-secret
  namespace: default
spec:
  refreshInterval: 15s
  secretStoreRef:
    name: vault-backend
    kind: SecretStore
  target:
    name: example-secret
    creationPolicy: Owner
  data:
  - secretKey: password
    remoteRef:
      key: secret/data/database
      property: password

Image Automation

# Image repository
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageRepository
metadata:
  name: podinfo
  namespace: flux-system
spec:
  image: ghcr.io/stefanprodan/podinfo
  interval: 1m
---
# Image policy
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImagePolicy
metadata:
  name: podinfo
  namespace: flux-system
spec:
  imageRepositoryRef:
    name: podinfo
  policy:
    semver:
      range: 5.0.x
---
# Image update automation
apiVersion: image.toolkit.fluxcd.io/v1beta1
kind: ImageUpdateAutomation
metadata:
  name: flux-system
  namespace: flux-system
spec:
  interval: 30m
  sourceRef:
    kind: GitRepository
    name: flux-system
  git:
    checkout:
      ref:
        branch: main
    commit:
      author:
        email: fluxcdbot@users.noreply.github.com
        name: fluxcdbot
      messageTemplate: |
        Automated image update

        Automation name: {{ .AutomationObject }}

        Files:
        {{ range $filename, $_ := .Updated.Files -}}
        - {{ $filename }}
        {{ end -}}

        Objects:
        {{ range $resource, $_ := .Updated.Objects -}}
        - {{ $resource.Kind }} {{ $resource.Name }}
        {{ end -}}

        Images:
        {{ range .Updated.Images -}}
        - {{.}}
        {{ end -}}
    push:
      branch: main
  update:
    path: "./clusters/my-cluster"
    strategy: Setters

Monitoring and Observability

Prometheus Metrics

# ServiceMonitor for Flux controllers
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: flux-system
  namespace: flux-system
spec:
  selector:
    matchLabels:
      app.kubernetes.io/part-of: flux
  endpoints:
  - port: http-prom
    interval: 15s
    path: /metrics
---
# Grafana dashboard ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: flux-grafana-dashboard
  namespace: monitoring
  labels:
    grafana_dashboard: "1"
data:
  flux-cluster.json: |
    {
      "dashboard": {
        "title": "Flux Cluster Stats",
        "panels": [
          {
            "title": "Reconciliation Duration",
            "type": "graph",
            "targets": [
              {
                "expr": "gotk_reconcile_duration_seconds{kind=\"Kustomization\"}"
              }
            ]
          }
        ]
      }
    }

Alerting Rules

# PrometheusRule for Flux alerts
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: flux-alerts
  namespace: flux-system
spec:
  groups:
  - name: flux
    rules:
    - alert: FluxReconciliationFailure
      expr: max(gotk_reconcile_condition{type="Ready",status="False"}) by (exported_namespace, name, kind) + on(exported_namespace, name, kind) (max(gotk_reconcile_condition{type="Ready",status="False"}) by (exported_namespace, name, kind)) > 0
      for: 10m
      labels:
        severity: critical
      annotations:
        summary: "Flux reconciliation failure"
        description: "{{ $labels.kind }}/{{ $labels.name }} in {{ $labels.exported_namespace }} has been failing for more than 10 minutes."

    - alert: FluxSuspendedResource
      expr: max(gotk_suspend_status) by (exported_namespace, name, kind) > 0
      for: 1h
      labels:
        severity: warning
      annotations:
        summary: "Flux resource suspended"
        description: "{{ $labels.kind }}/{{ $labels.name }} in {{ $labels.exported_namespace }} has been suspended for more than 1 hour."

Logging Configuration

# Fluent Bit configuration for Flux logs
apiVersion: v1
kind: ConfigMap
metadata:
  name: fluent-bit-config
  namespace: flux-system
data:
  fluent-bit.conf: |
    [SERVICE]
        Flush         1
        Log_Level     info
        Daemon        off
        Parsers_File  parsers.conf

    [INPUT]
        Name              tail
        Path              /var/log/containers/*flux*.log
        Parser            docker
        Tag               flux.*
        Refresh_Interval  5

    [OUTPUT]
        Name  es
        Match flux.*
        Host  elasticsearch.logging.svc.cluster.local
        Port  9200
        Index flux-logs

Security and RBAC

Service Account Configuration

# Custom service account for Flux
apiVersion: v1
kind: ServiceAccount
metadata:
  name: flux-custom
  namespace: flux-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: flux-custom
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: flux-custom
  namespace: flux-system
---
# Use custom service account in Kustomization
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: apps
  namespace: flux-system
spec:
  serviceAccountName: flux-custom
  interval: 10m
  sourceRef:
    kind: GitRepository
    name: flux-system
  path: ./apps

Network Policies

# Network policy for Flux system
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: flux-system
  namespace: flux-system
spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/part-of: flux
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: monitoring
    ports:
    - protocol: TCP
      port: 8080
  egress:
  - to: []
    ports:
    - protocol: TCP
      port: 443
    - protocol: TCP
      port: 80
  - to:
    - namespaceSelector: {}
    ports:
    - protocol: TCP
      port: 6443

Pod Security Standards

# Pod Security Policy for Flux
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: flux-psp
spec:
  privileged: false
  allowPrivilegeEscalation: false
  requiredDropCapabilities:
    - ALL
  volumes:
    - 'configMap'
    - 'emptyDir'
    - 'projected'
    - 'secret'
    - 'downwardAPI'
    - 'persistentVolumeClaim'
  runAsUser:
    rule: 'MustRunAsNonRoot'
  seLinux:
    rule: 'RunAsAny'
  fsGroup:
    rule: 'RunAsAny'

Troubleshooting

Common Issues

# Check Flux system status
flux check

# Get events for debugging
kubectl get events -n flux-system --sort-by='.lastTimestamp'

# Check controller logs
kubectl logs -n flux-system deployment/source-controller
kubectl logs -n flux-system deployment/kustomize-controller
kubectl logs -n flux-system deployment/helm-controller

# Debug reconciliation
flux reconcile source git flux-system --verbose
flux reconcile kustomization flux-system --verbose

# Check resource conditions
kubectl describe gitrepository flux-system -n flux-system
kubectl describe kustomization apps -n flux-system

Performance Tuning

# Tune controller resource limits
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kustomize-controller
  namespace: flux-system
spec:
  template:
    spec:
      containers:
      - name: manager
        resources:
          limits:
            cpu: 1000m
            memory: 1Gi
          requests:
            cpu: 100m
            memory: 64Mi
        args:
        - --events-addr=http://notification-controller.flux-system.svc.cluster.local./
        - --watch-all-namespaces=true
        - --log-level=info
        - --log-encoding=json
        - --enable-leader-election
        - --concurrent=10  # Increase concurrency
        - --kube-api-qps=50  # Increase API QPS
        - --kube-api-burst=100  # Increase API burst

Debugging Git Authentication

# Test Git connectivity
flux create source git test-repo \
  --url=https://github.com/your-org/your-repo \
  --branch=main \
  --interval=1m \
  --secret-ref=git-credentials

# Check secret format
kubectl get secret git-credentials -n flux-system -o yaml

# For SSH keys
kubectl create secret generic git-credentials \
  --from-file=identity=/path/to/private/key \
  --from-file=identity.pub=/path/to/public/key \
  --from-file=known_hosts=/path/to/known_hosts \
  -n flux-system

# For HTTPS with token
kubectl create secret generic git-credentials \
  --from-literal=username=git \
  --from-literal=password=your-token \
  -n flux-system

Best Practices

Repository Organization

# Separate concerns
fleet-infra/                    # Infrastructure and platform
├── clusters/                   # Cluster-specific configurations
├── infrastructure/             # Shared infrastructure components
└── tenants/                    # Tenant-specific configurations

app-manifests/                  # Application manifests
├── base/                       # Base configurations
├── overlays/                   # Environment-specific overlays
└── releases/                   # Helm releases

Security Best Practices

# 1. Use least-privilege RBAC
# 2. Enable Pod Security Standards
# 3. Use network policies
# 4. Scan images for vulnerabilities
# 5. Use sealed secrets or external secret management
# 6. Enable audit logging
# 7. Regular security updates
# 8. Monitor for drift and unauthorized changes

Performance Optimization

# 1. Tune reconciliation intervals based on needs
# 2. Use health checks for critical deployments
# 3. Implement proper resource limits
# 4. Use dependency ordering with depends-on
# 5. Monitor controller resource usage
# 6. Use horizontal pod autoscaling for controllers
# 7. Optimize Git repository structure
# 8. Use shallow clones for large repositories

Disaster Recovery

# 1. Backup Flux configuration
kubectl get gitrepository,kustomization,helmrelease -A -o yaml > flux-backup.yaml

# 2. Document bootstrap procedure
# 3. Test recovery procedures regularly
# 4. Use multiple Git repositories for redundancy
# 5. Monitor cluster state drift
# 6. Implement automated backup strategies
# 7. Document rollback procedures
# 8. Test cross-cluster migrations

Integration Examples

ArgoCD Migration

# Convert ArgoCD Application to Flux Kustomization
# ArgoCD Application:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: podinfo
spec:
  source:
    repoURL: https://github.com/stefanprodan/podinfo
    path: kustomize
    targetRevision: master
  destination:
    server: https://kubernetes.default.svc
    namespace: default

# Equivalent Flux resources:
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
  name: podinfo
spec:
  url: https://github.com/stefanprodan/podinfo
  ref:
    branch: master
  interval: 1m
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: podinfo
spec:
  sourceRef:
    kind: GitRepository
    name: podinfo
  path: ./kustomize
  targetNamespace: default
  interval: 5m

Tekton Integration

# Tekton Pipeline to update Flux
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: update-flux-image
spec:
  params:
  - name: image-tag
    type: string
  - name: git-repo
    type: string
  tasks:
  - name: update-manifest
    taskSpec:
      params:
      - name: image-tag
      - name: git-repo
      steps:
      - name: update
        image: alpine/git
        script: |
          #!/bin/sh
          git clone $(params.git-repo) /workspace
          cd /workspace
          sed -i 's|image: .*|image: myapp:$(params.image-tag)|' apps/myapp/deployment.yaml
          git add .
          git commit -m "Update image to $(params.image-tag)"
          git push

Resources

Documentation

Community

Training