--- title: Install fluxcd/fluxv2 with custom layout for future flexibility description: Installing fluxcd/fluxv2 is a trivial operation, but sometimes the defaults are not conducive to future flexibility. This pages details a few tricks to ensure Flux can be easily managed / extended over time. --- # Install fluxcd/fluxv2 [Flux](https://fluxcd.io/) 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: 1. All change is version-controlled (*i.e. "GitOps"*) 2. It's not necessary to expose the cluster API (*i.e., which would otherwise be the case if you were using CI*) 3. Deployments can be paused, rolled back, examine, debugged using Kubernetes primitives and tooling !!! summary "Ingredients" * [x] [Install the flux CLI tools](https://fluxcd.io/docs/installation/#install-the-flux-cli) on a host which has access to your cluster's apiserver. * [x] Create a GitHub [personal access token](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line) that can create repositories by checking all permissions under repo. * [x] Create a private GitHub repository dedicated to your flux deployments ## Fluxv2 components Here's a simplified way to think about the various flux components.. 1. 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*). 2. 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. 3. The YAML files inside the kustomization include: 1. HelmRepositories (*think of these as the repos you'd add to helm with `helm repo`*) 2. HelmReleases (*these are charts which live in HelmRepositories*) 3. Any other valid Kubernetes YAML manifests (*i.e., ConfigMaps, etc)* ## Preparation ### Install flux CLI This section is a [direct copy of the official docs](https://fluxcd.io/docs/installation/#install-the-flux-cli), to save you having to open another tab.. === "HomeBrew (MacOS/Linux)" With [Homebrew](https://brew.sh/) for macOS and Linux: ```bash brew install fluxcd/tap/flux ``` === "Bash (MacOS/Linux)" With Bash for macOS and Linux: ```bash curl -s https://fluxcd.io/install.sh | sudo bash ``` === "Chocolatey" With [Chocolatey](https://chocolatey.org/) for Windows: ```bash choco install flux ``` ### Create GitHub Token Create a GitHub [personal access token](https://github.com/settings/tokens) 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](https://github.com/geek-cookbook/template-flux/generate), 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... ```bash 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: ```bash GITHUB_TOKEN= flux bootstrap github \ --owner=my-github-username \ --repository=my-repository \ --personal \ --path bootstrap ``` !!! tip "What if SSH is blocked?" Per [@jmmassou](https://forum.funkypenguin.co.nz/t/install/1541/2?u=funkypenguin), 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: ```bash 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: 1. A **GitRepository** called `flux-system`, pointing to your GitHub repo. 2. A **Kustomization** called `flux-system`, pointing to the `flux-system` directory in the above repo. If you used my template repo, some extra things also happened.. 1. I'd pre-populated the `bootstrap` directory in the template repo with 3 folders: 1. [helmrepositories](https://github.com/geek-cookbook/template-flux/tree/main/bootstrap/helmrepositories), for storing repositories used for deploying helm charts 2. [kustomizations](https://github.com/geek-cookbook/template-flux/tree/main/bootstrap/kustomizations), for storing additional kustomizations *(which in turn can reference other paths in the repo*) 3. [namespaces](https://github.com/geek-cookbook/template-flux/tree/main/bootstrap/namespaces), for storing namespace manifests (*since these need to exist before we can deploy helmreleases into them*) 2. Because the `bootstrap` Kustomization includes everything **recursively** under `bootstrap` path in the repo, all of the above were **also** applied to the cluster 3. I'd pre-prepared a [Namespace](https://github.com/geek-cookbook/template-flux/blob/main/bootstrap/namespaces/namespace-podinfo.yaml), [HelmRepository](https://github.com/geek-cookbook/template-flux/blob/main/bootstrap/helmrepositories/helmrepository-podinfo.yaml), and [Kustomization](https://github.com/geek-cookbook/template-flux/blob/main/bootstrap/kustomizations/kustomization-podinfo.yaml) for "podinfo", a simple example application, so these were applied to the cluster 4. 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 5. In the `/podinfo` path of the repo is a [HelmRelease](https://github.com/geek-cookbook/template-flux/blob/main/podinfo/helmrelease-podinfo.yaml) (*an object describing how to deploy a helm chart*), and a [ConfigMap](https://github.com/geek-cookbook/template-flux/blob/main/podinfo/configmap-podinfo-helm-chart-value-overrides.yaml) (*which ontain the `values.yaml` for the podinfo helm chart*) 6. 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](/kubernetes/deployment/flux/design/), describing the design we're using... --8<-- "recipe-footer.md" [^1]: The [template repo](https://github.com/geek-cookbook/template-flux/) also "bootstraps" a simple example re how to [operate flux](/kubernetes/deployment/flux/operate/), by deploying the podinfo helm chart. [^2]: TIL that GitHub listens for SSH on `ssh.github.com` on port 443!