Install fluxcd/fluxv2
Flux is a set of continuous and progressive delivery solutions for Kubernetes that are open and extensible.
Using flux to manage deployments into the cluster means:
- All change is version-controlled (i.e. "GitOps")
- It's not necessary to expose the cluster API (i.e., which would otherwise be the case if you were using CI)
- Deployments can be paused, rolled back, examine, debugged using Kubernetes primitives and tooling
Ingredients
- Install the flux CLI tools on a host which has access to your cluster's apiserver.
- Create a GitHub personal access token that can create repositories by checking all permissions under repo.
- Create a private GitHub repository dedicated to your flux deployments
Fluxv2 components
Here's a simplified way to think about the various flux components..
- You need a source for flux to look at. This is usually a Git repository, although it can also be a helm repository, an S3 bucket. A source defines the entire repo (not a path or a folder structure).
- Within your source, you define one or more kustomizations. Each kustomization is a location on your source (i.e., myrepo/nginx) containing YAML files to be applied directly to the API server.
- The YAML files inside the kustomization include:
- HelmRepositories (think of these as the repos you'd add to helm with
helm repo
) - HelmReleases (these are charts which live in HelmRepositories)
- Any other valid Kubernetes YAML manifests (i.e., ConfigMaps, etc)
- HelmRepositories (think of these as the repos you'd add to helm with
Preparation
Install flux CLI
This section is a direct copy of the official docs, to save you having to open another tab..
With Homebrew for macOS and Linux:
brew install fluxcd/tap/flux
With Bash for macOS and Linux:
curl -s https://fluxcd.io/install.sh | sudo bash
With Chocolatey for Windows:
choco install flux
Create GitHub Token
Create a GitHub personal access token that can create repositories by checking all permissions under repo, as well as all options under admin:public_key
. (we'll use the token in the bootstrapping step below)
Tip
A personal token, not one of these new-fangled "fine grained access tokens", which don't work with Flux (yet) :)
Create GitHub Repo
Now we'll create a repo for flux - it can (and probably should!) be private. I've created a template repo to get you started, but you could simply start with a blank repo too (although you'll need at least a bootstrap
directory included or the command below will fail).1
Bootstrap Flux
Having prepared all of the above, we're now ready to deploy flux. Before we start, take a look at all the running pods in the cluster, with kubectl get pods -A
. You should see something like this...
root@shredder:~# k3s kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-7448499f4d-qfszx 1/1 Running 0 6m32s
kube-system local-path-provisioner-5ff76fc89d-rqh52 1/1 Running 0 6m32s
kube-system metrics-server-86cbb8457f-25688 1/1 Running 0 6m32s
Now, run a customized version of the following:
GITHUB_TOKEN=<your-token> \
flux bootstrap github \
--owner=my-github-username \
--repository=my-repository \
--personal \
--path bootstrap
What if SSH is blocked?
Per @jmmassou, if you're behind a restrictive firewall which may block outgoing SSH, you might see an error like this:
SSH key scan for host github.com:443 failed, error: ssh: handshake failed: EOF
A clever workaround is to use SSH over port 443 instead (apparently GitHub is configured to make this work)2, by appending the following to your bootstrap command:
--ssh-hostname ssh.github.com:443
Once the flux bootstrap is completed without errors, list the pods in the cluster again, with kubectl get pods -A
. This time, you see something like this:
root@shredder:~# k3s kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
flux-system helm-controller-f7c5b6c56-nk7rm 1/1 Running 0 5m48s
flux-system kustomize-controller-55db56f44f-4kqs2 1/1 Running 0 5m48s
flux-system notification-controller-77f68bf8f4-9zlw9 1/1 Running 0 5m48s
flux-system source-controller-8457664f8f-8qhhm 1/1 Running 0 5m48s
kube-system coredns-7448499f4d-qfszx 1/1 Running 0 15m
kube-system local-path-provisioner-5ff76fc89d-rqh52 1/1 Running 0 15m
kube-system metrics-server-86cbb8457f-25688 1/1 Running 0 15m
traefik svclb-traefik-ppvhr 2/2 Running 0 5m31s
traefik traefik-f48b94477-d476p 1/1 Running 0 5m31s
root@shredder:~#
What just happened?
Flux installed its controllers into the flux-system
namespace, and created two new objects:
- A GitRepository called
flux-system
, pointing to your GitHub repo. - A Kustomization called
flux-system
, pointing to theflux-system
directory in the above repo.
If you used my template repo, some extra things also happened..
- I'd pre-populated the
bootstrap
directory in the template repo with 3 folders:- helmrepositories, for storing repositories used for deploying helm charts
- kustomizations, for storing additional kustomizations (which in turn can reference other paths in the repo)
- namespaces, for storing namespace manifests (since these need to exist before we can deploy helmreleases into them)
- Because the
bootstrap
Kustomization includes everything recursively underbootstrap
path in the repo, all of the above were also applied to the cluster - I'd pre-prepared a Namespace, HelmRepository, and Kustomization for "podinfo", a simple example application, so these were applied to the cluster
- The kustomization we added for podinfo refers to the
/podinfo
path in the repo, so everything in this folder was also applied to the cluster - In the
/podinfo
path of the repo is a HelmRelease (an object describing how to deploy a helm chart), and a ConfigMap (which ontain thevalues.yaml
for the podinfo helm chart) - Flux recognized the podinfo HelmRelease, applied it along with the values in the ConfigMap, and consequently we have podinfo deployed from the latest helm chart, into the cluster, and managed by Flux! 💪
Wait, but why?
That's best explained on the next page, describing the design we're using...
Chef's notes 📓
-
The template repo also "bootstraps" a simple example re how to operate flux, by deploying the podinfo helm chart. ↩
-
TIL that GitHub listens for SSH on
ssh.github.com
on port 443! ↩
Tip your waiter (sponsor) 👏
Did you receive excellent service? Want to compliment the chef? (..and support development of current and future recipes!) Sponsor me on Github / Ko-Fi / Patreon, or see the contribute page for more (free or paid) ways to say thank you! 👏
Employ your chef (engage) 🤝
Is this too much of a geeky PITA? Do you just want results, stat? I do this for a living - I'm a full-time Kubernetes contractor, providing consulting and engineering expertise to businesses needing short-term, short-notice support in the cloud-native space, including AWS/Azure/GKE, Kubernetes, CI/CD and automation.
Learn more about working with me here.
Flirt with waiter (subscribe) 💌
Want to know now when this recipe gets updated, or when future recipes are added? Subscribe to the RSS feed, or leave your email address below, and we'll keep you updated.