Get Started with Flux

Get Started with Flux and the GitOps Toolkit.

In this tutorial, you will deploy an application to a kubernetes cluster with Flux and manage the cluster in a complete GitOps manner. You’ll be using a dedicated Git repository e.g. fleet-infra to manage your Kubernetes clusters.


In order to follow the guide, you will need a Kubernetes cluster version 1.16 or newer and kubectl version 1.18. For a quick local test, you can use Kubernetes kind. Any other Kubernetes setup will work as well though.

Flux is installed in a GitOps way and its manifest will be pushed to the repository, so you will also need a GitHub account and a personal access token that can create repositories (check all permissions under repo) to enable Flux do this.

Export your GitHub personal access token and username:

export GITHUB_TOKEN=<your-token>
export GITHUB_USER=<your-username>

Install the Flux CLI

To install the latest flux release on MacOS and Linux using Homebrew run:

brew install fluxcd/tap/flux

Or install flux by downloading precompiled binaries using a Bash script:

curl -s | sudo bash

The install script downloads the flux binary to /usr/local/bin.

If using Arch Linux, install the latest stable version from AUR using either flux-bin (pre-built binary) or flux-go (locally built binary).

Binaries for macOS, Windows and Linux AMD64/ARM are available for download on the release page.

To configure your shell to load flux bash completions add to your profile:

# ~/.bashrc or ~/.bash_profile
. <(flux completion bash)

zsh, fish, and powershell are also supported with their own sub-commands.

Install Flux components

Create the cluster using Kubernetes kind or set the kubectl context to an existing cluster:

kind create cluster
kubectl cluster-info

Verify that your staging cluster satisfies the prerequisites with:

$ flux check --pre
► checking prerequisites
✔ kubectl 1.18.3 >=1.18.0
✔ kubernetes 1.18.2 >=1.16.0
✔ prerequisites checks passed

Run the bootstrap command:

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

The bootstrap command creates a repository if one doesn’t exist, commits the manifests for the Flux components to the default branch at the specified path, and installs the Flux components. Then it configures the target cluster to synchronize with the specified path inside the repository.

If you wish to create the repository under a GitHub organization:

flux bootstrap github \
  --owner=<organization> \
  --repository=<repo-name> \
  --branch=<organization default branch> \
  --team=<team1-slug> \
  --team=<team2-slug> \

Example output:

$ flux bootstrap github --owner=gitopsrun --team=devs --repository=fleet-infra --path=./clusters/my-cluster 
► connecting to
✔ repository created
✔ devs team access granted
✔ repository cloned
✚ generating manifests
✔ components manifests pushed
► installing components in flux-system namespace
deployment "source-controller" successfully rolled out
deployment "kustomize-controller" successfully rolled out
deployment "helm-controller" successfully rolled out
deployment "notification-controller" successfully rolled out
✔ install completed
► configuring deploy key
✔ deploy key configured
► generating sync manifests
✔ sync manifests pushed
► applying sync manifests
◎ waiting for cluster sync
✔ bootstrap finished

If you prefer GitLab, export GITLAB_TOKEN env var and use the command flux bootstrap gitlab.

Clone the git repository

We are going to drive app deployments in a GitOps manner, using the Git repository as the desired state for our cluster. Instead of applying the manifests directly to the cluster, Flux will apply it for us instead.

Therefore, we need to clone the repository to our local machine:

git clone$GITHUB_USER/fleet-infra
cd fleet-infra

Add podinfo repository to Flux

We will be using a public repository, podinfo is a tiny web application made with Go.

Create a GitRepository manifest pointing to podinfo repository’s master branch:

flux create source git podinfo \
  --url= \
  --branch=master \
  --interval=30s \
  --export > ./clusters/my-cluster/podinfo-source.yaml

The above command generates the following manifest:

kind: GitRepository
  name: podinfo
  namespace: flux-system
  interval: 30s
    branch: master

Commit and push it to the fleet-infra repository:

git add -A && git commit -m "Add podinfo GitRepository"
git push

Deploy podinfo application

We will create a Flux Kustomization manifest for podinfo. This configures Flux to build and apply the kustomize directory located in the podinfo repository.

flux create kustomization podinfo \
  --source=podinfo \
  --path="./kustomize" \
  --prune=true \
  --validation=client \
  --interval=5m \
  --export > ./clusters/my-cluster/podinfo-kustomization.yaml

The above command generates the following manifest:

kind: Kustomization
  name: podinfo
  namespace: flux-system
  interval: 5m0s
  path: ./kustomize
  prune: true
    kind: GitRepository
    name: podinfo
  validation: client

Commit and push the Kustomization manifest to the repository:

git add -A && git commit -m "Add podinfo Kustomization"
git push

The structure of your repository should look like this:

└── clusters/
    └── my-cluster/
        ├── flux-system/                        
        │   ├── gotk-components.yaml
        │   ├── gotk-sync.yaml
        │   └── kustomization.yaml
        ├── podinfo-kustomization.yaml
        └── podinfo-source.yaml

Watch Flux sync the application

In about 30s the synchronization should start:

$ watch flux get kustomizations
flux-system     True    Applied revision: main/fc07af652d3168be329539b30a4c3943a7d12dd8
podinfo         True    Applied revision: master/855f7724be13f6146f61a893851522837ad5b634

When the synchronization finishes you can check that podinfo has been deployed on your cluster:

$ kubectl -n default get deployments,services
NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/podinfo   2/2     2            2           108s

NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE
service/podinfo      ClusterIP   <none>        9898/TCP,9999/TCP   108s

If a Kubernetes manifest is removed from the podinfo repository, Flux will remove it from your cluster. If you delete a Kustomization from the fleet-infra repository, Flux will remove all Kubernetes objects that were previously applied from that Kustomization.

If you alter the podinfo deployment using kubectl edit, the changes will be reverted to match the state described in Git. When dealing with an incident, you can pause the reconciliation of a kustomization with flux suspend kustomization <name>. Once the debugging session is over, you can re-enable the reconciliation with flux resume kustomization <name>.

Multi-cluster Setup

To use Flux to manage more than one cluster or promote deployments from staging to production, take a look at the two approaches in the repositories listed below.

Last modified 2021-05-25 : Remove "Flux v2" mentions (ebff99e)