DevCloudLab More courses at DevCloudLab.com →
FLUX CD · SECTION 2 · LECTURE 4

DevCloudLab

Installing and bootstrapping Flux CD

Section 2, Lecture 4, from the Flux CD course by DevCloudLab.


What you’ll learn

Install the Flux CLI

Flux ships as a single Go binary, so installing it is just fetching the right build for your platform. Nothing is installed on your cluster at this step.

# macOS or Linux, with Homebrew
brew install fluxcd/tap/flux

# macOS or Linux, without Homebrew (installs to /usr/local/bin)
curl -s https://fluxcd.io/install.sh | sudo bash

# Windows, with Chocolatey
choco install flux

Confirm it installed:

flux --version

Check the cluster before you touch anything

Before creating any files, point kubectl at the target cluster and run Flux’s pre-flight check:

flux check --pre

This confirms the CLI can reach the Kubernetes API through your current kubectl context, and that the cluster is running a Kubernetes version Flux supports. Resolve anything it flags: a failing flux check --pre means the bootstrap step later will fail too.

Since this video was recorded: the video quotes a minimum of Kubernetes 1.23. Flux’s minimum supported version moves forward as older Kubernetes releases reach end of life, so treat that number as stale. The installation page lists the current minimum, and flux check --pre tells you definitively whether your own cluster qualifies.

Lay out the Git repository

Flux is entirely declarative: even Flux’s own installation is described by YAML files that live in a Git repository, the same repository that will later hold your application manifests.

Create an empty repository on GitHub or GitLab, clone it locally, then create the directory Flux will read from:

cd my-flux-repo
mkdir -p clusters/my-cluster/flux-system
cd clusters/my-cluster/flux-system
touch gotk-components.yaml gotk-sync.yaml kustomization.yaml

Note: my-cluster names the Flux configuration, not the Kubernetes cluster you’re pointing it at. The same configuration path can be bootstrapped onto several clusters, so the directory name is arbitrary. Pick something that describes the environment (production, staging) rather than a literal cluster hostname.

gotk-components.yaml and gotk-sync.yaml stay empty for now. Flux generates their contents during bootstrap. The only file you write by hand is kustomization.yaml, which tells Flux where to find the other two:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- gotk-components.yaml
- gotk-sync.yaml

Commit and push before bootstrapping:

git add -A
git commit -m "Initial commit"
git push

Create a personal access token

Bootstrap needs to push generated files back to your repository on your behalf, so it authenticates with a personal access token (PAT) rather than your own login session.

GitLab: go to your profile’s Access Tokens settings and create a token scoped to api. Copy the value immediately: GitLab shows it exactly once, and if you lose it you have to create a new one.

GitHub: create a fine-grained personal access token scoped to the target repository, with:

Permission Access needed
Contents Read and write
Administration Read-only
Metadata Read-only (granted automatically)

Note: treat the token like a password (never commit it, never share it) and set yourself a reminder before it expires. An expired token doesn’t error loudly; Flux’s reconciliation just quietly stops being able to push or pull, which makes it one of the more annoying failures to track down if you’ve forgotten you set an expiry.

Export the token so the CLI can read it:

# GitLab
export GITLAB_TOKEN=<your-token>

# GitHub
export GITHUB_TOKEN=<your-token>

Bootstrap

flux bootstrap <provider> does four things in one run: it connects to your repository, downloads the flux-system directory, generates the contents of gotk-components.yaml and gotk-sync.yaml, commits and pushes that change back to the repository using your token, then applies everything to the cluster using the kustomization.yaml you wrote.

GitLab:

flux bootstrap gitlab \
  --owner=<your-gitlab-username-or-group> \
  --repository=<your-repo-name> \
  --branch=main \
  --path=clusters/my-cluster \
  --token-auth \
  --personal

GitHub:

flux bootstrap github \
  --owner=<your-github-username-or-org> \
  --repository=<your-repo-name> \
  --branch=main \
  --path=clusters/my-cluster \
  --token-auth \
  --personal

A few flags worth knowing precisely, because getting one wrong is a common source of a bootstrap that silently targets the wrong thing:

Flag What it does
--token-auth Use the PAT you exported instead of Flux’s default SSH deploy key
--personal Tells Flux --owner is an individual account. Drop it when bootstrapping into an organization (GitHub) or group (GitLab) repository
--path Must match the directory you created earlier; this is the path Flux will keep in sync
--branch The branch Flux commits to and reconciles from

Flux also bootstraps natively against Bitbucket Server and any generic Git server over HTTPS or SSH. The provider-specific subcommands exist for the hosts that offer a token/API integration; check the installation docs for the exact command on a host not covered here.

What the bootstrap commit actually writes

Once bootstrap finishes, look at the commit it pushed to your repository:

File What bootstrap wrote into it
gotk-components.yaml The full manifest for every Flux controller and CRD. This is what actually gets applied to the cluster
gotk-sync.yaml A GitRepository and a Kustomization object that point back at this same repository, branch, and path. This is what makes Flux self-managing
kustomization.yaml Untouched: this is the file you wrote by hand

From this point on, any change you push to clusters/my-cluster/flux-system/ (or to any path a Kustomization you add later points at) gets reconciled onto the cluster automatically.

Confirm the controllers are running:

kubectl get pods -n flux-system

You’ll see four pods, one per controller (source, kustomize, helm, and notification) and, notably, none of them is named flux. Flux has no single control-plane pod; it’s a set of controllers that each reconcile a slice of Git state onto the cluster.

Bootstrapping more than one cluster

Because Flux has no central control plane, adding a second cluster to the same setup is the same flux bootstrap command run against the new cluster’s kubectl context. Point it at the same repository, branch, and path, or at a different path if you want it running a different configuration. There’s no separate registration step on a management cluster, which is the main operational difference from tools like Argo CD, where a hub cluster must be told about every cluster it manages before it can deploy to it.

Further reading


DevCloudLab

Built by DevCloudLab
Hands-on cloud-native courses: Kubernetes, GitOps, CI/CD and the cloud.
Visit DevCloudLab.com →