Managing a Kubernetes cluster with Helm and FluxCD
As seen in my previous article, after successfully setting up a Kubernetes Cluster you can install applications on it using the Helm CLI. This is convenient to get started but might not scale well with multiple people administering the cluster.
To make collaboration easier and avoid making mistakes by simply mistyping Helm commands, it is recommended to adopt a GitOps workflow. This consists of using Git to version control the state of the cluster. In this article, I will explain how to use FluxCD to achieve this.
Getting started with FluxCD
First of all, make sure you have a running Kubernetes cluster and have installed kubectl and helm.
Then you will need to create a Git repository at your favorite provider (GitHub, Bitbucket, etc…).
Once this is done, clone it locally and create a releases
folder inside of it.
This folder will contain the files defining your Helm releases (a release is an instance of a chart running on a cluster).
Let’s start by creating a release for my favorite IRC client, The Lounge.
To do this, create a file in releases/thelounge.yaml
containing the following data:
---
apiVersion: helm.fluxcd.io/v1
kind: HelmRelease
metadata:
name: thelounge
namespace: default
annotations:
fluxcd.io/automated: "false"
fluxcd.io/tag.chart-image: semver:~4.0
spec:
releaseName: thelounge
chart:
repository: https://halkeye.github.io/helm-charts/
name: thelounge
version: 4.3.0
values:
ingress:
enabled: true
hosts:
- YOUR.OWN.DOMAIN
This will be using the chart available on Artifact Hub, and the software will be running on the default namespace, and we ask for an ingress to be created. Don’t forget to commit and push the release!
After creating this repository, you should install FluxCD on your cluster. To do this simply run the following commands:
helm repo add fluxcd https://charts.fluxcd.io
kubectl apply -f https://raw.githubusercontent.com/fluxcd/helm-operator/master/deploy/crds.yaml
kubectl create ns flux
helm upgrade -i flux fluxcd/flux \
--set git.url=git@github.com:[USERNAME]/[REPO] \
--set git.branch=[BRANCH] \
--namespace flux
helm upgrade -i helm-operator fluxcd/helm-operator \
--set git.ssh.secretName=flux-git-deploy \
--set helm.versions=v3 \
--namespace flux
You should now see 3 pods running in the flux namespace:
flux-memcached-869757cb88-77br8 1/1 Running 0 100s
flux-59cb4447b9-thpr9 1/1 Running 0 101s
helm-operator-686dc669cd-g8kn7 1/1 Running 0 89s
Finally, you will need to give read and write access to your git repository to FluxCD. To do this, install fluxctl and run:
fluxctl identity --k8s-fwd-ns flux
This will print an RSA key that needs to be added as a deploy key to your repository.
For GitHub users, go to https://github.com/YOURUSERNAME/YOURUSER/settings/keys/new
to add the key (tick the give write access checkbox).
Your release should start getting installed on your cluster soon. You can check the state of your helm releases by running
kubectl get hr
If needed, you can check the FluxCD logs with
kubectl -n flux logs deployment/flux -f
If you want to manually trigger FluxCD to re-read your git repository, use the command:
fluxctl sync --k8s-fwd-ns flux
Adding your charts
Of course, you might not be able to do exactly what you want using the charts publicly available. FluxCD allows you to add your charts directly through Git.
First, create a charts
directory.
Inside this directory, run the following command to create a chart named mychart
:
helm create mychart
This will generate a sample chart defining everything that’s required to launch an Nginx server in production.
To run this chart, you will have to define a release for it in your releases
folder:
---
apiVersion: helm.fluxcd.io/v1
kind: HelmRelease
metadata:
name: myrelease
namespace: default
annotations:
fluxcd.io/automated: "false"
fluxcd.io/tag.chart-image: glob:3.1.1-debian-9-*
spec:
releaseName: myrelease
chart:
git: ssh://git@github.com/[USER]/[REPO]
ref: [BRANCH]
path: charts/mychart
values:
ingress:
enabled: true
hosts:
- host: YOUR.OTHER.DOMAIN
paths: ["/"]
Like in the previous example, don’t forget to git commit
and git push
.
FluxCD will automatically create the new release and you will see a magnificent Nginx welcome page appear at the specified domain.
To be able to display something else than the Nginx welcome page, we will give it a configuration file.
For this purpose, you can define a configmap in charts/mychart/templates/configmap.yaml
.
The following config will redirect every request to a URL of our choice:
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-conf
data:
nginx.conf: |
events {
worker_connections 1024;
}
http {
server {
listen 80 default_server;
return 301 {{ .Values.redirect }};
}
}
You will then need to declare the volume by adding this value to spec.template.spec
in charts/mychart/templates/deployment.yaml
:
volumes:
- name: nginx-conf
configMap:
name: nginx-conf
To mount the configuration file into the Nginx container, you need to add the following lines to spec.template.spec.containers[0]
in the same file:
volumeMounts:
- mountPath: /etc/nginx/
readOnly: true
name: nginx-conf
Finally, bump the version
in charts/mychart/Chart.yaml
, and set the redirect URL in releases/myrelease.yaml
by editing the values section like this:
values:
ingress:
enabled: true
hosts:
- host: YOUR.OTHER.DOMAIN
paths: ["/"]
redirect: "https://www.youtube.com/watch?v=cFVF26XPcAU"
Dive deeper
As this article only really scratches the surface of what Helm and FluxCD can do, I recommend you to also check out the official FluxCD docs and their example repository, as well as the Helm Chart Template Developer’s Guide.
The source code for the examples shown in this article is available on GitHub.