Continuous Delivery is a natural extension of Continuous Integration, and a critical part of the deployment process in a Cloud Native organization. When done right, CI/CD simplifies code deployment in several environments. However, we still need to get the code there in the first place. In CI/CD we tend to embrace the mentality that, for code to be generally available, it should be pushed — either to a version control system or to deployment environments,
But what if I tell you that you can pull instead of push?
This is where Flux comes in. Flux, a GitOps operator for Kubernetes, can make this possible. But first, a little background.
Pushing and Pulling
In software design, identifying components’ responsibilities is a main concern. This matters a lot because from them we can infer and determine the interactions between those components, how each one will fulfill a goal, and how the whole orchestration will conduct in a sustainable system.
When we design software, we use multiple patterns and principles, one of which concerns responsibility. When responsible for something, your only concern is doing what you are asked to do and doing it very well. That one focus dictates your actions or behavior.
In the relationship between a sender and a receiver, the sender is responsible for the integrity of what is sent through the channel, and the receiver is responsible for doing something with that input. We can then easily transpose that idea to the relation between a pusher and a puller, where the pusher is responsible for making the data available and the puller responsible for acting on that data.
How Does This Work in GitOps?
GitOps provides a way for developers to manage operational workflows, particularly for Kubernetes, using Git. Pushing code in GitOps can be broken down into four key concepts:
- You declaratively describe the entire desired state of your system in Git.
- What can be described can be automated.
- You push code, not containers.
- Operations by pull requests. Approved changes can be automatically applied to the system.
Using Git, you can version control all the changes you make to your infrastructure. You can then — easily, in case of failure — roll back to the previous working version. Using pull requests to manage these changes to the infrastructure, you can quickly detect breaking changes and prevent them from being applied.
In GitOps, we have a pusher (the developer/ops) whose responsibility is to push changes to a version-control repository of all the changes applied to a set of manifests. We also have a puller (the operator), whose single responsibility is to pull those changes and ensure the cluster state equals the desired state.
When working in such complex processes, separating responsibilities this way serves to make our entire workflow more efficient, more maintainable, and more scalable.
What’s the Role of Flux?
“An operator is a way of building an application and driving an application on top of Kubernetes, behind Kubernetes APIs.”
—Sebastien Pahl, director of engineering, Red Hat
Flux, as we mentioned earlier, is a GitOps operator for Kubernetes. Since it’s an operator it runs directly in the cluster, and it’s attached to a set of permissions through Role-Based Access Control (RBAC). This gives Flux the ability to directly query the API server to operate on the cluster.
In an infrastructure managed by Git, Flux connects to your Git repository and watches for all changes on a specific branch and folder. When a commit occurs, Flux will operate on the cluster in order to deploy those changes.
Using Flux means that no external tool or script, granted with a cluster access, needs to be triggered in the repository pipeline in order for new or changed code to be deployed in the environment.
Instead, we apply the necessary changes to the Git repository and these changes are pulled out of Git and then replicated on the cluster.
So each time I have a new container, I will update these files in Git and the changes will be replicated?
Yes and no.
If the update is only related to the container used, you can have Flux do the job for you directly. It can watch, if you want, changes on your container repository and automatically push it to your environments. Not only that, it can also update your files in your Git repository with this new image and commit the changes.
Isn’t this beautiful?
But, still pay attention: In this case, some things can be automated and others cannot. Usually, the thing that will change in your manifests are containers images. So using it with a tool like Kustomize, you can divide your manifests into multiple pieces. Categorize them into those that can be updated by Flux (resources), and those that require manual intervention through patches.
Welcome to the (Cluster) Federation
Another benefit with Flux — and it an impressive one — is cluster federation. We know it can be tricky to set up cluster federation or to replicate changes in multiple clusters at the same time. With this tool, a Flux operator could be deployed on each cluster, all watching the same Git repository. Whenever a change is made, it will be replicated across your clusters.
Not only that, you can use Flux in conjunction with Flagger, a progressive Kubernetes delivery operator, to automates the promotion of canary deployments and traffic shifting.
Ready to begin? Here’s the full documentation on Flux.
Incorporated into a GitOps workflow, Flux simplifies CI/CD and enables continuous delivery of container images. Meanwhile, Git version control makes sure deployment is reproducible, auditable and, if necessary, revertable. For small companies, using Flux is a quick win towards creating a sustainable delivery process where your teams can deploy code as fast as they create it — with confidence.
Feature image via Pixabay.