GitOps with Flux
Kubernetes has now become de facto standard for container orchestration and cloud native operations. It solves a lot of problems with service discovery, load balancing, horizontal scaling, rolling updates and many more. Kubernetes manifest YAML files allow to describe desirable state of your applications in the cluster with configuration and secrets.
When that is not enough - you can use Helm for packaging and templating of your application resources. This is all great, but you still need a way to apply all of these elements to the cluster. Running
kubectl apply or
helm upgrade from your machine or CI quickly become cumbersome.
This is where GitOps will help.
GitOps is an operational and pipeline pattern that uses Git as a single source of truth for declarative specification of environment. This may sound complex, but in the end it is about having Git repository where you have description of desired state of your environment. Description may came in many forms like raw Kubernetes YAML files, files describing Helm releases or Kustomize YAML files. When you want to change anything in your environment - you should commit change to Git repository and this change will be applied to your Kubernetes cluster.
I really like how Luis Faceira described GitOps in 1 slide:
If you want to learn more about GitOps - there is comprehensive post on Weaveworks blog.
GitOps is great pattern, but you still need to apply environment description to Kubernetes somehow. Some options to do that might be running
kubectl apply command from your CI for all YAML files in repository (on every commit) or having a Ansible playbook with bunch of tasks which would run
helm upgrade or
kubectl apply. These are so called “push” approaches where something external (like CI) need to have access to both - Git repository and Kubernetes cluster. This may be a potential security problem.
Another common problem with this approach is time required to deploy all applications to your cluster. You can run
kubectl apply -f for all files in the Git repository, but it will take more and more time to finish this process as number of application grows for your environment.
Flux tackles this problem a bit differently. It works with “pull” approach. That means it lives inside Kubernetes cluster. Flux monitors Git repository for any commits and apply to Kubernetes only those resources which has been modified. This greatly shorten the time required to deploy changes. Additionally, Flux supports Helm releases and Kustomize.
How does it work
Flux manifest files describes the resources which should be installed in the Kubernetes cluster. For Helm release it could look similar to this one:
apiVersion: helm.fluxcd.io/v1 kind: HelmRelease metadata: name: my-application annotations: fluxcd.io/automated: "true" filter.fluxcd.io/chart-image: semver:~1.10 spec: releaseName: my-app chart: repository: my-charts-repository name: my-app version: 1.0 values: image: myimages/my-app:1.10.3 replicaCount: 3 [...]
When you want to upgrade
my-app on the cluster you just change value in
spec.values.image and push this change to Git repository. Flux will take care of upgrading pods in Kubernetes.
This is not the only option though. In the manifest above, you can see these lines:
fluxcd.io/automated: "true" filter.fluxcd.io/chart-image: semver:~1.10
It enables automated upgrades of your application, when new Docker image in repository is matching the filter from the second line. This filter uses semantic versioning for comparison, but there are other types of filters for version like “glob” and “regexp” as well. That means Flux can not only monitor your Git repository, but also Docker repository for a new tags.
There is a nice diagram from Flux Helm operator documentation showing the connections between all the components.
Secrets with GitOps
It is pretty obvious that keeping secrets (like passwords or private keys) in Git repository is not a good idea. There are tools available which handle this problem, by keeping secrets encrypted in Git repository and decrypting it only inside the cluster:
Other GitOps tools
Flux is not the only existing tool for GitOps. Other worth mentioning tools are Argo CD and Jenkins X. Flux and Argo CD are quite similar in the purpose they serve, but have different, opinionated approach to solve the problem.
Lately, Waveworks and Intuit (companies behind Flux and Argo CD) has announced they join forces to work on Argo Flux, which will combine both tools. However, at the time of writing this post, this is still unknown how this tool will look like and when it will be available. Both companies agree that if you want to go with GitOps - you should try both Flux and Argo CD and choose the tool which fits your needs the best. In the future there should be an easy way to migrate from Argo or Flux to Argo Flux.
Jenkins X is much more then GitOps operator. It provides full pipeline automation including setting up Kubernetes environments, remote development functions, CI/CD and GitOps.