KubernetesWritten by GLWS18 min readUbuntu 24.04 LTS / AlmaLinux 9
Commands run on your server unless a section says otherwise. Replace example usernames, addresses and paths with your own values. Keep a working session open when changing remote access.

What Flux does

Flux is a GitOps tool. It runs inside your cluster and keeps the cluster matching a Git repository: you commit YAML, and Flux applies it, continuously, and corrects drift if someone changes the cluster by hand. Rollback is a Git revert, and the repository is the record of what runs.

You need a working K3s cluster (see the K3s guide), a GitHub account, and kubectl access. The cluster should have about 2 GB of memory free for Kubernetes plus Flux's controllers.

Install the Flux command-line tool

The flux command talks to your cluster and to Git. Install it with the project's script, which you should read first, then check the version. The pre-flight check confirms the cluster is compatible.

Both systems
curl -s https://fluxcd.io/install.sh -o flux-install.sh
less flux-install.sh
sudo bash flux-install.sh
flux --version
export KUBECONFIG=$HOME/.kube/config
flux check --pre

Create a token with the least access

Bootstrap needs a GitHub token. Create a fine-grained personal access token limited to the one repository, with Administration read-only (read and write if you use deploy keys instead of token authentication), Contents read and write, and Metadata read-only. Set an expiry date. Keep the token in your shell for the bootstrap only. Flux stores it in the cluster as a secret named flux-system, which is why the narrow scope matters.

Both systems
read -rsp "GitHub token: " GITHUB_TOKEN; echo
export GITHUB_TOKEN
To avoid a token stored in the cluster, the documentation describes SSH deploy keys with the token-auth flag set to false. Read that section if you want the stricter setup.

Bootstrap Flux

Bootstrap creates the repository if it does not exist, installs Flux's controllers in the flux-system namespace, commits their manifests to your repository and sets Flux to watch it. The path is the folder in the repository that holds this cluster's configuration. The personal flag is for a repository under your own account. Omit it for an organisation.

Both systems (replace the owner and repository)
flux bootstrap github \
  --token-auth \
  --owner=YOUR_GITHUB_USER \
  --repository=fleet-infra \
  --branch=main \
  --path=clusters/my-cluster \
  --personal
kubectl -n flux-system get pods
flux get all
Clone the repository and look at it
unset GITHUB_TOKEN
git clone https://github.com/YOUR_GITHUB_USER/fleet-infra.git
cd fleet-infra
find . -type f | head -n 20

Add an application from a public repository

Tell Flux where to find source and how to apply it. A GitRepository resource points to a repository, and a Kustomization applies a path in it. The generator commands write the YAML for you. This example deploys the public podinfo demo into the cluster. You commit the files, and Flux applies them.

Inside the fleet-infra folder
flux create source git podinfo \
  --url=https://github.com/stefanprodan/podinfo \
  --branch=master \
  --interval=1m \
  --export > ./clusters/my-cluster/podinfo-source.yaml
flux create kustomization podinfo \
  --target-namespace=demo \
  --source=podinfo \
  --path="./kustomize" \
  --prune=true \
  --wait=true \
  --interval=30m \
  --retry-interval=2m \
  --health-check-timeout=3m \
  --export > ./clusters/my-cluster/podinfo-kustomization.yaml
kubectl create namespace demo --dry-run=client -o yaml > ./clusters/my-cluster/demo-namespace.yaml
git add -A && git commit -m "Add podinfo" && git push
Watch it arrive
flux get sources git
flux get kustomizations
kubectl -n demo get pods

Deploy your own application from Git

For your own project, keep Kubernetes manifests in a folder such as apps/myapp in the repository, then add a Kustomization that points at it. Structure the repository with a clusters folder for Flux's own configuration and an apps folder for applications, so that each cluster can pick the apps it runs. The manifests are the same YAML you wrote in the deployment guide.

Example Kustomization for a folder in the same repository
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: myapp
  namespace: flux-system
spec:
  interval: 10m
  path: ./apps/myapp
  prune: true
  sourceRef:
    kind: GitRepository
    name: flux-system
  targetNamespace: demo

Private repositories and secrets

For an application repository that is private, create a read-only deploy key and give Flux the secret. Never commit plain Kubernetes Secrets to Git, even in a private repository. Use SOPS encryption with a key held in the cluster, which Flux supports, or create secrets outside Git. Keep this rule from the start, because a secret in Git history is hard to remove.

Both systems
flux create secret git app-repo-auth --url=ssh://[email protected]/YOUR_USER/YOUR_APP_REPO --ssh-key-algorithm=ed25519
# add the printed public key as a read-only deploy key on the repository

Update and roll back with Git

To change an application, edit the manifest, commit and push. Flux notices within its interval, or immediately if you ask it to reconcile. To roll back, revert the commit and push. Because Flux prunes what is no longer in Git, deleting a file removes the resource, so review deletions carefully.

Both systems
git commit -am "Scale myapp to 2 replicas" && git push
flux reconcile kustomization flux-system --with-source
flux reconcile kustomization myapp --with-source
git revert HEAD --no-edit && git push

When something does not apply

Flux reports problems clearly. List resources that are not ready, read the controller logs and read the Kustomization's status message, which usually names the invalid manifest. You can pause reconciliation while you fix something by hand, then resume it.

Both systems
flux get all -A
flux logs --level=error --since=30m
kubectl -n flux-system describe kustomization myapp | tail -n 20
flux suspend kustomization myapp
flux resume kustomization myapp

Official documentation

These upstream references provide more detail on the commands and workflows in this guide.