The advancement of cloud native has given rise to new tools and frameworks that resonate with modern stack. One of them is GitOps – a new way of working that has become an established modus operandi for cloud native systems. In this article we will explore what GitOps is, delve into its basic principles, and see what makes it different from traditional ways of code delivery.
What is GitOps?
First introduced in 2017, GitOps is a Git-centric operating model for Kubernetes-based cloud-native systems. It uses a declarative approach to define and manage each layer of modern applications’ stack: infrastructure, network, application code, and the GitOps pipeline itself.
GitOps assumes the idea that what can be described can be automated. Thus, its basic rule is describing everything (code, config, monitoring & policy) and then keeping it within the version control system to modify and track changes.
Apart from storing the cluster state in Git, GitOps’ central principle is implementing a nonstop reconciliation loop that will constantly monitor a source of truth (Git repository) and synchronize it with the real world (Kubernetes cluster).
The GitOps working model streamlines the developer’s workflow in a cloud. First, it enables developers to efficiently perform operation tasks by using their familiar toolkit i.e. pool requests and commits to a repository. Second, by separating stream-aligned teams (Dev) and platform teams (Ops), GitOps facilitates the idea of a self-service platform for developers. With this approach, developers use pre-defined templates of cloud resources created by the platform team whenever they are ready to deploy code. As a result, devs spend less time on operating tasks, while ops can rest assured that the infrastructure the deployed code works in is deployed from their approved templates.
Principles of GitOps
GitOps remains a comparatively new approach to software delivery. In order to bring consistency to its underlying principles, CNCF created the GitOps Working Group (WG), whose task is to define a vendor-neutral, principle-led meaning of GitOps. The WG has prepared and formulated 4 fundamental principles of GitOps that are documented within the CNCF OpenGitOps project:
- Declarative. The system uses declarative tools such as Kubernetes, Docker, and Terraform. Configuration of components is defined by a set of facts, not instructions.
- Versioned and immutable. The entire system, including application code, config, monitoring, and policy is described in code and kept in version control. This approach enables users to have an ultimate point (Git repository) from which everything is managed.
- Pulled automatically. Having pushed the declared state to Git, the next step is to allow automatic appliance of proclaimed changes to a system. This is done programmatically without human interaction with the cluster.
- Continuously reconciled. Software agents continuously monitor the state of systems. Whenever the desired state deviates from the actual one, the agents inform you and take actions to re-establish the conformity.
The logical outcome of GitOps principles is that definitions in Git describe the state of our systems. All operations are performed through Git, by humans proposing changes and machines converging them into the desired state. Before applying, all changes must go through the Git review process as PRs – changing the system directly via kubectl is discouraged.
GitOps implies that our infrastructure is immutable, i.e. that it has its components replaced rather than changed. Creating new resources is based on images, which is more reliable because we then know exactly what we’ll get. In the case of GitOps, immutability also simplifies the work that machines need to do to converge the actual into the desired state.
GitOps pipeline is different from typical CI/CD in terms of the arrangement of the delivery process. To understand these differences, let’s have a closer look at a typical pipeline.
Traditional CI/CD combines code assembling, testing, and delivery within a single workflow that completes with deployment to a target environment:
Example of typical CI/CD pipeline. Source: Weaveworks
CI includes code building and testing, where an output is then delivered to a container repository. The CD system deploys a container automatically or by request. This is a push mode pipeline that has the CI/CD system deploying ready containers directly to a cluster.
The GitOps pipeline is designed in a different way. It is a pull mode based system with a controller inside a cluster to check infrastructure repositories against changes and implementing them with each new commit.
Traditional CI/CD puts CI at the center of the development pipeline, taking Git and CD as supporting components. Git serves as a place to obtain input for a build, whereas CD is an extended functionality of CI aimed to deliver build’s artifacts to target environments, as shown on the example diagram.
In the GitOps model, Git is the key element of the pipeline. It is the one source of truth for every part of the system – the code, configuration, and full stack. CI services, code assembling, and testing are all necessary to create deployable artifacts, but the overall delivery process is coordinated by the automated deployment system triggered by repository updates.
Example of GitOps pipeline. Source: Weaveworks
On the diagram above we can see a GitOps pipeline that is triggered by pull requests and orchestrated by Weave Flux. The pipeline centers around Git as a single source of truth for manifests, or a configuration repository. Developers push the updated code to a code repo, from where it is taken by the CI tool and a new Docker image is built. The Flux Automator detects the image, pulls it out of the repository and updates its YAML in the configuration repo. The Deployment Synchronizer then discovers that the cluster is outdated, extracts the changed manifests from the configuration repo and deploys the new image to the cluster.
GitOps decouples CI and CD by having them executed by different controllers. This approach has certain advantages behind it:
- Lighter pipelines. Unlike traditional CI/CD, a GitOps pipeline doesn’t involve release to a target environment, which makes its logic simpler.
- Enhanced security. In a typical push-mode pipeline the CI/CD system makes direct deployment to a cluster, which involves granting the cluster access rights to CI/CD tools. With the GitOps approach, all work is done within the cluster’s trust domain, eliminating the need to share cluster credentials with 3-d party tools.
- Flexibility. Sometimes you need to deliver code to multiple platforms simultaneously, like with Edge computing or multi-cloud cluster installation, but some of the clusters may not be available at this time, causing your pipeline to fail. With decoupled CI and CD, the CD part can catch up later when the clusters are restarted.
However, separating CI and CD could have a downside too. Since these processes are implemented in different pipelines, you need a customized solution to notify the CD system about the status of a build and whether it is ready to be picked up by the CD controller.
GitOps is an approach to software delivery that has been designed specifically for cloud-native systems. Its core principle – reconciling actual and desired states – derives from the main logic of Kubernetes controllers, except that they look into a Git repo and not the Kubernetes API. In doing so, GitOps reinforces Kubernetes’ native features of self-healing and high availability.
Successful GitOps implementation relies on continuous monitoring to observe changes and requires a declarative approach to configuration management.
Overall, GitOps is a perfect way of doing DevOps and configuration in general in the era of cloud native. Leverage an opportunity to streamline your development process. Contact our team to have your processes aligned according to GitOps’ best practices.