11 KiB
FluxCD
-
We're going to implement a basic GitOps workflow with Flux
-
Pushing to
mainwill automatically deploy to the clusters -
There will be two clusters (
devandprod) -
The two clusters will have similar (but slightly different) workloads
Repository structure
This is (approximately) what we're going to do:
@@INCLUDE[slides/k8s/gitopstree.txt]
Getting ready
-
Let's make sure we have two clusters
-
It's OK to use local clusters (kind, minikube...)
-
We might run into resource limits, though
(pay attention to
Pendingpods!) -
Highly recommended: set up CLI completion!
-
Of course we'll need a Git service, too
(we're going to use GitHub here)
GitHub setup
-
Generate a GitHub token:
-
Give it "repo" access
-
This token will be used by the
flux bootstrap githubcommand later -
It will create a repository and configure it (SSH key...)
-
The token can be revoked afterwards
Flux bootstrap
.lab[
- Let's set a few variables for convenience, and create our repository:
export GITHUB_TOKEN=... export GITHUB_USER=changeme export GITHUB_REPO=alsochangeme export FLUX_CLUSTER=dev flux bootstrap github \ --owner=$GITHUB_USER \ --repository=$GITHUB_REPO \ --branch=main \ --path=./clusters/$FLUX_CLUSTER \ --personal --public
]
Problems? check next slide!
What could go wrong?
-
flux bootstrapwill create or update the repository on GitHub -
Then it will install Flux controllers to our cluster
-
Then it waits for these controllers to be up and running and ready
-
Check pod status in
flux-system -
If pods are
Pending, check that you have enough resources on your cluster -
For testing purposes, it should be fine to lower or remove Flux
requests!(but don't do that in production!)
-
If anything goes wrong, don't worry, we can just re-run the bootstrap
class: extra-details
Idempotence
-
It's OK to run that same
flux bootstrapcommand multiple times! -
If the repository already exists, it will re-use it
(it won't destroy or empty it)
-
If the path
./clusters/$FLUX_CLUSTERalready exists, it will update it -
It's totally fine to re-run
flux bootstrapif something fails -
It's totally fine to run it multiple times on different clusters
-
Or even to run it multiple times for the same cluster
(to reinstall Flux on that cluster after a cluster wipe / reinstall)
What do we get?
- Let's look at what
flux bootstrapinstalled on the cluster
.lab[
-
Look inside the
flux-systemnamespace:kubectl get all --namespace flux-system -
Look at
kustomizationscustom resources:kubectl get kustomizations --all-namespaces -
See what the
fluxCLI tells us:flux get all
]
Deploying with GitOps
-
We'll need to add/edit files on the repository
-
We can do it by using
git clone, local edits,git commit,git push -
Or by editing online on the GitHub website
.lab[
-
Create a manifest; for instance
clusters/dev/flux-system/blue.yaml -
Add that manifest to
clusters/dev/kustomization.yaml -
Commit and push both changes to the repository
]
Waiting for reconciliation
-
Compare the git hash that we pushed and the one shown with
kubectl get -
Option 1: wait for Flux to pick up the changes in the repository
(the default interval for git repositories is 1 minute, so that's fast)
-
Option 2: use
flux reconcile source git flux-system(this puts an annotation on the appropriate resource, triggering an immediate check)
-
Option 3: set up receiver webhooks
(so that git updates trigger immediate reconciliation)
Checking progress
-
flux logs -
kubectl get gitrepositories --all-namespaces -
kubectl get kustomizations --all-namespaces
Did it work?
--
- No!
--
- Why?
--
-
We need to indicate the namespace where the app should be deployed
-
Either in the YAML manifests
-
Or in the
kustomizationcustom resource(using field
spec.targetNamespace) -
Add the namespace to the manifest and try again!
Adding an app in a reusable way
-
Let's see a technique to add a whole app
(with multiple resource manifets)
-
We want to minimize code repetition
(i.e. easy to add on multiple clusters with minimal changes)
The plan
-
Add the app manifests in a directory
(e.g.:
apps/myappname/manifests) -
Create a kustomization manifest for the app and its namespace
(e.g.:
apps/myappname/flux.yaml) -
The kustomization manifest will refer to the app manifest
-
Add the kustomization manifest to the top-level
flux-systemkustomization
Creating the manifests
- All commands below should be executed at the root of the repository
.lab[
-
Put application manifests in their directory:
mkdir -p apps/dockercoins cp ~/container.training/k8s/dockercoins.yaml apps/dockercoins/ -
Create kustomization manifest:
flux create kustomization dockercoins \ --source=GitRepository/flux-system \ --path=./apps/dockercoins/manifests/ \ --target-namespace=dockercoins \ --prune=true --export > apps/dockercoins/flux.yaml
]
Creating the target namespace
-
When deploying helm releases, it is possible to automatically create the namespace
-
When deploying kustomizations, we need to create it explicitly
-
Let's put the namespace with the kustomization manifest
(so that the whole app can be mediated through a single manifest)
.lab[
- Add the target namespace to the kustomization manifest:
echo "--- kind: Namespace apiVersion: v1 metadata: name: dockercoins" >> apps/dockercoins/flux.yaml
]
Linking the kustomization manifest
-
Edit
clusters/dev/flux-system/kustomization.yaml -
Add a line to reference the kustomization manifest that we created:
- ../../../apps/dockercoins/flux.yaml -
git addour manifests,git commit,git push(check with
git statusthat we haven't forgotten anything!) -
flux reconcileor wait for the changes to be picked up
Installing with Helm
-
We're going to see two different workflows:
-
installing a third-party chart
(e.g. something we found on the Artifact Hub) -
installing one of our own charts
(e.g. a chart we authored ourselves)
-
-
The procedures are very similar
Installing from a public Helm repository
- Let's install kube-prometheus-stack
.lab[
- Create the Flux manifests:
mkdir -p apps/kube-prometheus-stack flux create source helm kube-prometheus-stack \ --url=https://prometheus-community.github.io/helm-charts \ --export >> apps/kube-prometheus-stack/flux.yaml flux create helmrelease kube-prometheus-stack \ --source=HelmRepository/kube-prometheus-stack \ --chart=kube-prometheus-stack --release-name=kube-prometheus-stack \ --target-namespace=kube-prometheus-stack --create-target-namespace \ --export >> apps/kube-prometheus-stack/flux.yaml
]
Enable the app
-
Just like before, link the manifest from the top-level kustomization
(
flux-systemin namespaceflux-system) -
git add/git commit/git push -
We should now have a Prometheus+Grafana observability stack!
Installing from a Helm chart in a git repo
-
In this example, the chart will be in the same repo
-
In the real world, it will typically be in a different repo!
.lab[
- Generate a basic Helm chart:
mkdir -p charts helm create charts/myapp
]
(This generates a chart which installs NGINX. A lot of things can be customized, though.)
Creating the Flux manifests
- The invocation is very similar to our first example
.lab[
-
Generate the Flux manifest for the Helm release:
mkdir apps/myapp flux create helmrelease myapp \ --source=GitRepository/flux-system \ --chart=charts/myapp \ --target-namespace=myapp --create-target-namespace \ --export > apps/myapp/flux.yaml -
Add a reference to that manifest to the top-level kustomization
-
git add/git commit/git pushthe chart, manifest, and kustomization
]
Passing values
-
We can also configure our Helm releases with values
-
Using an existing
myvalues.yamlfile:flux create helmrelease ... --values=myvalues.yaml -
Referencing an existing ConfigMap or Secret with a
values.yamlkey:flux create helmrelease ... --values-from=ConfigMap/myapp
Gotchas
-
When creating a HelmRelease using a chart stored in a git repository, you must:
-
either bump the chart version (in
Chart.yaml) after each change, -
or set
spec.chart.spec.reconcileStrategytoRevision
-
-
Why?
-
Flux installs helm releases using packaged artifacts
-
Artifacts are updated only when the Helm chart version changes
-
Unless
reconcileStrategyis set toRevision(instead of the defaultChartVersion)
More gotchas
-
There is a bug in Flux that prevents using identical subcharts with aliases
-
See fluxcd/flux2#2505 for details
Things that we didn't talk about...
-
Bucket sources
-
Image automation controller
-
Image reflector controller
-
And more!
???
:EN:- Implementing gitops with Flux :FR:- Workflow gitops avec Flux