Managing code changes in a Kubernetes cluster can be complex, particularly when multiple applications are involved. Keeping track of changes, versions, and dependencies can be challenging, and conflicts can arise that impact cluster stability.
GitOps provides a solution to these challenges by leveraging Git as the source of truth for all changes to the cluster. By committing all configuration changes and updates to a Git repository, GitOps provides a centralized location for tracking all changes to the cluster, while also providing a standardized approach to deploying and updating applications.
In this article, we will explore the GitOps methodology and take a closer look at Flux, a popular GitOps tool used for managing Kubernetes clusters.
What is GitOps?
GitOps is a software development approach that emphasizes using Git as the primary tool for managing infrastructure and application deployments. Essentially, GitOps means that all changes to infrastructure and application code are made through Git commits and that these changes trigger automated deployment pipelines to update the running environment. This approach enables teams to easily track changes, and rollback deployments, and ensure that the production environment matches the desired state described in Git.
The GitOps principles are essential for modern software development and deployment practices. These principles allow teams to automate the management of their infrastructure and applications, and ensure that their deployments are consistent and reliable.
In this section, we will discuss the four (4) key principles of GitOps, which are:
1. The entire system is described declaratively
GitOps mandates infrastructure and application code to be declared in a declarative way. A declarative approach involves specifying the desired end result rather than providing specific instructions on how to accomplish the task.
For example, in Kubernetes, to describe the desired state of an application through a declarative approach, we define the desired state in a YAML file, and Kubernetes takes care of managing the underlying infrastructure to ensure that the application is running as intended.
Say we want to deploy a simple web application in a Kubernetes cluster, we define the desired state of the application using a Kubernetes Deployment object, which includes the container image, number of replicas, and other specifications. Here is an example YAML file:
apiVersion: apps/v1 kind: Deployment metadata: name: my-webapp spec: replicas: 3 selector: matchLabels: app: my-webapp template: metadata: labels: app: my-webapp spec: containers: - name: my-webapp-container image: my-webapp-image:latest ports: - containerPort: 80
This YAML file describes the desired state of Kubernetes Deployment for our web application.
We want to have three replicas of our container, which will be managed by a Kubernetes ReplicaSet. The container will listen on port 80, and the image used will be my-webapp-image:latest.
Kubernetes will take care of ensuring that the desired state is met, even if there are changes in the underlying infrastructure.
2. The desired system state is versioned in Git
The desired state is the ideal state that developers and operators aim to achieve and maintain. This state is stored in Git to keep track of changes made to the system over time, revert to previous versions, and collaborate with others to make changes. By storing the desired state in Git, developers can maintain consistency, reliability, and security, while also working in an agile way to continually improve the system over time.
3. Approved changes can be automatically applied to the system
After the desired state has been stored in Git, GitOps operators, also known as software agents, automatically retrieve the desired state from Git and apply it to one or more Kubernetes targets. A software agent is a software component that continuously monitors the changes made to a Git repository and triggers the deployment of those changes to a target environment, such as a Kubernetes cluster. This process occurs without the need for manual intervention, allowing for seamless and efficient deployment of the desired state.
4. Software agents ensure correctness and reconcile the system to match the desired state
GitOps operators follow a continuous loop that involves observing the repository for any changes in the desired state. This process entails comparing the difference between the actual state and the desired state, after which the operators automatically take action to reconcile the two states.
The GitOps workflow
GitOps Pipeline: Source Weaveworks
Assuming that your code is stored on a Git repository and contains Kubernetes manifests such as helm charts, Kustomizations, etc, the task at hand is to retrieve these manifests from the repository and deploy them to your Kubernetes cluster.
Within your Kubernetes cluster, there exist multiple namespaces, services, and various cloud-native tools installed. A Kubernetes beginner typically resorts to the “Imperative” method of deployment, which involves utilizing the following command to apply a configuration file:
kubectl apply -f "filename"
Imperative approach involves providing specific instructions or commands on how to accomplish the task rather than specifying the desired end result. GitOps discourages this.
One of the limitations of the imperative approach is that any modifications made to the Kubernetes manifest stored in the Git repository will not automatically reflect on the Kubernetes cluster. As a result, the kubectl apply command must be executed again to synchronize the cluster with the updated manifest.
In a scenario where multiple team members are making changes to the manifests files in a Git repository, it can be a daunting task to monitor the changes taking place in the cluster. Tracking who deployed what resource, what was deployed, or when it was deployed can become a challenging feat, resulting in a state of confusion when an issue arises and needs to be resolved. The lack of knowledge of the root cause of the problem can lead to significant delays in fixing the issue.
By implementing a GitOps tool like Flux, you can efficiently track the changes in the cluster, which ensures that any issue that arises can be fixed promptly. With GitOps, you can know that any change made to the cluster is being tracked, and in the event of an issue, the cause can be easily identified, and the problem resolved quickly.
How it works
With GitOps you deploy an agent into your Kubernetes cluster. The agent in this case is Flux. Flux helps you to manage the resources in your Kubernetes cluster.
As teams make changes to the Git Repository, they make changes just to the code. A CI/CD pipeline running in that repository tests the code changes made, and after passing the tests, the changes get deployed to the repository. Once the changes have been deployed, the agent living in your cluster is responsible to pull that change into your Kubernetes cluster and deploys it to the specific resource the change was made to.
How does the agent know about the Kubernetes manifest?
The agent responsible for deploying and managing Kubernetes resources can know about the Kubernetes manifest by:
- Reading the manifest files directly from a version control system, such as a Git repository, or a local file system.
- Receiving the manifest as input from a user or another system
However, the Cluster administrator remains at the center of the process as he/she is the one who tells the agent where the manifest files are located. The agent is then responsible to detail who deployed what, what is deployed, and when it was deployed to the cluster.
What is Flux?
Flux is a package management system that operates on a Git-based platform, delivering a range of smooth and incremental deployment solutions for Kubernetes. Its primary objective is to maintain synchronization between Kubernetes clusters and configuration sources such as Git repositories. It achieves this by automating the updating of configurations whenever new code is available for deployment.
Flux is a powerful GitOps tool that is constructed using a variety of specialized components, collectively known as the GitOps Toolkit. These components include Flux Controllers, composable APIs, and reusable Go packages that are designed to enhance the functionality of GitOps.
Flux Controllers in the GitOps Toolkit
Source: Flux Docs
Source Controller: It automates the process of obtaining files from external sources and integrating them into application code. This includes sources such as Git, OCI, Helm repositories, and S3-compatible buckets. The source controller makes it easier and faster for developers to develop and deploy applications without worrying about the details of accessing and integrating external resources.
Image Reflector Controller: It monitors container registries for changes and updates the Kubernetes cluster with the latest images.
Image Automation Controller: It automates the process of updating the container image in the repository and commits changes to the repository automatically.
Kustomize Controller: It applies Kubernetes manifests generated by Kustomize to a cluster and ensures the desired state of the cluster.
Helm Controller: It automates the deployment of Helm charts to a cluster and ensures that the desired state of the cluster is maintained.
Notification Controller: It sends notifications to users and teams about changes made to the Kubernetes cluster, such as deployments and configuration updates.
Benefits of Flux
In this section, we will look at some of the benefits of Flux which include:
Flux automates the deployment process by continuously monitoring and updating Kubernetes resources in real time. This automation reduces the likelihood of human error and improves reliability by ensuring that the correct resources are deployed to the correct environments consistently.
Flux is designed to work well in large-scale Kubernetes environments. It can handle multiple clusters, applications, and even entire infrastructures at once, which makes it a great tool for managing complex deployments.
Flux provides easy rollbacks in case of deployment failures or errors. It does this by using a Git-based version control system, which allows developers to roll back to a previous working version of the deployment. This feature reduces downtime and improves service availability, ensuring that the application remains operational even in the event of a deployment failure.
Flux CD can be integrated with a range of tools, including monitoring, logging, and testing frameworks. This integration allows developers to manage the entire deployment process from a single platform, which improves collaboration and streamlines the deployment process.
Flux uses the GitOps methodology, which means that all changes to the deployment process are stored in version control. This provides greater transparency, auditability, and reproducibility of the deployment process, allowing developers to easily track changes and roll back to previous versions if necessary.
Flux is highly customizable and can be tailored to fit specific deployment requirements. This customization allows developers to automate their deployment process in a way that meets their unique needs, improving efficiency and reducing errors.
GitOps and Flux represent a powerful approach to software development and deployment that can help teams achieve greater speed, reliability, and scalability.
By using Git as the single source of truth, GitOps enables teams to manage updates across multiple environments and platforms, while Flux provides automation tools for managing Kubernetes clusters. This approach facilitates collaboration, continuous delivery, and scalability, making it well-suited for modern cloud-native environments.
Ultimately, the adoption of GitOps and Flux is expected to lead to faster, more reliable, and more efficient software development and deployment.