Flux
Flux is a set of continuous delivery tools for Kubernetes that keeps your cluster in sync with Git repositories. It implements GitOps principles — using Git as the single source of truth for declarative infrastructure and application configuration.
Installation
Install Flux CLI
# Linux/macOS via shell script
curl -s https://fluxcd.io/install.sh | sudo bash
# macOS via Homebrew
brew install fluxcd/tap/flux
# Windows via Chocolatey
choco install flux
# Verify installation
flux --version
# Check cluster prerequisites
flux check --pre
Bootstrap with GitHub
# Export GitHub token
export GITHUB_TOKEN=<your-token>
export GITHUB_USER=<your-username>
# Bootstrap — creates a Fleet repository and installs Flux components
flux bootstrap github \
--token-auth \
--owner=${GITHUB_USER} \
--repository=fleet-infra \
--branch=main \
--path=clusters/my-cluster \
--personal
# Bootstrap with an existing repository
flux bootstrap github \
--token-auth \
--owner=my-org \
--repository=fleet-infra \
--branch=main \
--path=clusters/production
Bootstrap with GitLab
export GITLAB_TOKEN=<your-token>
flux bootstrap gitlab \
--token-auth \
--owner=my-group \
--repository=fleet-infra \
--branch=main \
--path=clusters/production
Bootstrap with Generic Git
flux bootstrap git \
--url=ssh://git@github.com/my-org/fleet-infra \
--branch=main \
--path=clusters/production \
--private-key-file=${HOME}/.ssh/id_rsa
Configuration
GitRepository Source
# Watch a Git repository for changes
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: podinfo
namespace: flux-system
spec:
interval: 1m
url: https://github.com/stefanprodan/podinfo
ref:
branch: master
secretRef:
name: podinfo-auth # Optional: for private repos
HelmRepository Source
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: HelmRepository
metadata:
name: bitnami
namespace: flux-system
spec:
interval: 1h
url: https://charts.bitnami.com/bitnami
Kustomization Resource
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: apps
namespace: flux-system
spec:
interval: 10m
path: ./apps/production
prune: true # Delete resources removed from Git
sourceRef:
kind: GitRepository
name: fleet-infra
healthChecks:
- apiVersion: apps/v1
kind: Deployment
name: backend
namespace: production
timeout: 5m
retryInterval: 2m
HelmRelease Resource
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: podinfo
namespace: default
spec:
interval: 5m
chart:
spec:
chart: podinfo
version: ">=6.0.0"
sourceRef:
kind: HelmRepository
name: podinfo
namespace: flux-system
values:
replicaCount: 2
resources:
requests:
cpu: 100m
memory: 64Mi
valuesFrom:
- kind: ConfigMap
name: podinfo-values
- kind: Secret
name: podinfo-secret-values
optional: true
Core Commands
| Command | Description |
|---|---|
flux check | Validate cluster prerequisites |
flux check --pre | Pre-installation checks |
flux get all | List all Flux resources and their status |
flux get sources git | List GitRepository sources |
flux get sources helm | List HelmRepository sources |
flux get kustomizations | List Kustomization objects |
flux get helmreleases | List HelmRelease objects |
flux reconcile source git <name> | Force reconcile a GitRepository |
flux reconcile kustomization <name> | Force reconcile a Kustomization |
flux reconcile helmrelease <name> | Force reconcile a HelmRelease |
flux suspend kustomization <name> | Pause reconciliation |
flux resume kustomization <name> | Resume reconciliation |
flux logs | Show Flux controller logs |
flux logs --follow | Stream logs continuously |
flux events | Show Flux Kubernetes events |
flux diff kustomization <name> | Dry-run diff against live cluster |
flux push artifact | Push OCI artifact to registry |
flux pull artifact | Pull OCI artifact from registry |
flux create secret git | Create a Git authentication secret |
flux create secret helm | Create a Helm authentication secret |
flux uninstall | Remove all Flux components |
flux export | Export Flux resources as YAML |
Advanced Usage
Image Automation
# Track and update container image tags automatically
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageRepository
metadata:
name: podinfo
namespace: flux-system
spec:
image: ghcr.io/stefanprodan/podinfo
interval: 5m
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImagePolicy
metadata:
name: podinfo
namespace: flux-system
spec:
imageRepositoryRef:
name: podinfo
policy:
semver:
range: ">=6.0.0" # SemVer range
# OR use tag filter:
# filterTags:
# pattern: '^main-[a-fA-F0-9]+-(?P<ts>.*)$'
# extract: '$ts'
# numerical:
# order: asc
---
apiVersion: image.toolkit.fluxcd.io/v1beta1
kind: ImageUpdateAutomation
metadata:
name: flux-system
namespace: flux-system
spec:
interval: 30m
sourceRef:
kind: GitRepository
name: fleet-infra
git:
checkout:
ref:
branch: main
commit:
author:
email: fluxcdbot@users.noreply.github.com
name: fluxcdbot
messageTemplate: |
Auto-update images
{{range .Updated.Images -}}
- {{.}}
{{end -}}
push:
branch: main
update:
path: ./clusters/production
strategy: Setters
Marker annotation in deployment YAML
# In your deployment, mark the image field for automation:
containers:
- name: podinfo
image: ghcr.io/stefanprodan/podinfo:6.0.0 # {"$imagepolicy": "flux-system:podinfo"}
Multi-Tenancy
# Create tenant namespace and RBAC
flux create tenant dev-team \
--with-namespace=dev-team \
--label=environment=staging \
--export > tenants/dev-team/rbac.yaml
# Tenant-scoped GitRepository (service account limits access)
kubectl create serviceaccount -n dev-team flux-reconciler
# Tenant Kustomization scoped to team namespace
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: dev-team-apps
namespace: flux-system
spec:
serviceAccountName: flux-reconciler # Tenant service account
targetNamespace: dev-team
sourceRef:
kind: GitRepository
name: dev-team-infra
path: ./
prune: true
interval: 5m
Notifications and Alerts
# Send Slack alerts on Flux events
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: slack
namespace: flux-system
spec:
type: slack
channel: flux-alerts
secretRef:
name: slack-webhook-url
---
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Alert
metadata:
name: on-call-webapp
namespace: flux-system
spec:
providerRef:
name: slack
eventSeverity: info
eventSources:
- kind: GitRepository
name: "*"
- kind: Kustomization
name: "*"
- kind: HelmRelease
name: "*"
OCI Artifacts
# Push Kustomization bundle as OCI artifact
flux push artifact oci://ghcr.io/my-org/fleet-infra:$(git rev-parse --short HEAD) \
--path="./clusters/production" \
--source="$(git config --get remote.origin.url)" \
--revision="$(git branch --show-current)/$(git rev-parse HEAD)"
# Reference OCI artifact as source
flux create source oci podinfo \
--url=oci://ghcr.io/my-org/fleet-infra \
--tag=latest \
--namespace=flux-system
Common Workflows
Deploy a New Application
# 1. Create namespace and source
flux create source git podinfo \
--url=https://github.com/stefanprodan/podinfo \
--branch=master \
--interval=1m \
--namespace=flux-system
# 2. Create Kustomization
flux create kustomization podinfo \
--target-namespace=default \
--source=podinfo \
--path="./kustomize" \
--prune=true \
--interval=5m
# 3. Watch reconciliation
flux get kustomizations --watch
Rollback a HelmRelease
# Suspend the release
flux suspend hr podinfo -n default
# Rollback via Helm
helm rollback podinfo -n default
# Resume Flux management
flux resume hr podinfo -n default
Debug a Failed Reconciliation
# Check overall status
flux get all -A
# Get detailed error messages
flux logs --level=error --all-namespaces
# Describe the failing resource
kubectl describe kustomization apps -n flux-system
# Force a reconcile after fixing the issue
flux reconcile kustomization apps --with-source
Promote from Staging to Production
# 1. Tag tested image
docker tag my-app:latest my-app:v1.2.3
docker push my-app:v1.2.3
# 2. Update production overlay in Git
cd clusters/production
kustomize edit set image my-app=my-app:v1.2.3
git commit -am "Promote my-app v1.2.3 to production"
git push
# 3. Flux auto-reconciles within the configured interval
# Force immediate reconcile
flux reconcile kustomization production --with-source
Tips and Best Practices
- Use
prune: trueon Kustomizations — it ensures that resources removed from Git are deleted from the cluster, preventing drift. - Set
healthCheckson Kustomizations — Flux will wait for Deployments and StatefulSets to be ready before marking the reconciliation successful. - Pin Helm chart versions with SemVer ranges —
>=1.0.0 <2.0.0gives automatic patch updates while preventing breaking changes. - Use
flux diff kustomizationbefore merging PRs — it shows exactly what will change in the cluster, functioning as a dry-run. - Separate cluster infrastructure from app configs — bootstrap Flux controllers and CRDs in one repo/path; manage application Kustomizations in another.
- Use Sealed Secrets or External Secrets alongside Flux — never commit plaintext secrets to Git; reference encrypted or externally managed secrets instead.
- Enable notifications early — Slack or Teams alerts on reconciliation failures catch drift before it becomes an incident.
- Use
flux suspend/resumeduring maintenance windows — prevents Flux from reverting manual changes while you work. - Audit with
flux events -A— events provide a chronological history of every reconciliation action across all controllers. - Multi-tenancy: scope Kustomizations to service accounts with limited RBAC — prevents one team’s config from affecting another’s namespace.