“What is GitOps?” – a question which has seen increasing popularity on Google searches and blog posts in the last three years. If you want to know why then read on. In this post, we will try to discover GitOps concept, and answer this questions :What is GitOps? Where Did It Come From? and Why Should You Care? The short answers to these questions:
Where did GitOps come from?
What does it mean?
In a nutshell, GitOps is a practice (Git Operation) that allows you to use GIT and code repository as your configuration source of truth. Then, an engineer can pull the change to alter or update your system’s configuration.
Should you care?
So let me tell you a story about GitOps approach.
The scene: spring 2016, a peaceful morning in London, at Weaveworks. The sun is shining. Birds tweet.
I’m about to make a change that will probably wipe out all our systemsTom
Tom, are you sure we want to do that?Decent person
Oops – I’ve just deleted all our Kubernetes clusters on AWSTom
It took the team less than 45 minutes to completely rebuild our entire systems. 45 minutes was a pretty good outcome – made possible by “GitOps”.
Okay, to be fair, probably every Continuous Deployment technology promises to make deploying faster and allows you to deploy more often.
But here is what special about GitOps.
GitOps is pretty Git-ty
GitOps requires the desired state of the system to be stored in version control. All changes to the desired state are fully traceable commits associated with committer information, commit IDs and time stamps. This means that both the application and the infrastructure are now versioned artifacts and can be audited using the gold standards of software development and delivery.
Using Git to manage infrastructure might seem like kind of a strange hack—like using a hammer to paint a wall or driving your car into the water. But when you look more closely, you realize that the practice behind GitOps makes a lot of sense:
- Use Git as a source of truth
- Drive operations through git repo
- Get version control, history, peer review and rollback
- Webhooks: push to trigger build/test
- PR’s & merge branch to deploy
GitOps in Practice
The entire system is described declaratively. Declarative means that configuration is guaranteed by a set of facts instead of by a set of instructions. Kubernetes is just one example of many modern cloud native tools that are “declarative” and that can be treated as code.
The canonical desired system state is versioned in Git. It means, you have a single place from which everything is derived and driven.
Approved changes to the desired state are automatically applied to the system. Software agents ensure correctness and alert on divergence.
Software agents ensure correctness and alert on divergence. The use of agents also ensures that your entire system is self-healing. And by self-healing, we don’t just mean when nodes or pods fail—those are handled by Kubernetes— but in a broader sense, like in the case of human error.
What happens when you adopt GitOps?
⦁ Any developer that uses Git can start deploying new features to “Kubernetes”
⦁ The same workflows are maintained across development and operations
⦁ All changes can be triggered, stored, validated and audited in Git
⦁ Ops changes can be observed and monitored
⦁ Ops changes can be made by pull request including rollbacks, but remember:
How to adopt GitOps?
Your everyday CI/CD Pipeline:
When you push that code to Git, the continuous integration tool kicks off unit tests that eventually build the Docker image that gets pushed to the container registry. With a typical CI/CD pipeline, Docker images are deployed using some sort of bash script or another method of talking directly to the cluster API.
Security wise: you have to share your API credentials with the CI tooling. If someone breaks into your CI tool, they will have total control over your production cluster. But what happens if your cluster goes down, You would have to run all of your CI jobs to rebuild everything and then re-apply all the workloads to the new cluster.
Let’s see how we can improve the typical CI/CD pipeline with GitOps.
GitOps Deployment Pipeline:
With this pattern, an agent acts on behalf of the cluster. It listens for events relating to custom resource changes, and then applies those changes based on a deployment policy.
- The development team writes and then pushes code into a code repo.
- CI/CD tool kicks off unit tests that build the Docker image.
- Docker images are deployed using some sort of bash script.
- The Deployment Automator updates the YAML
- Flux detects that the cluster is out of date, triggers deployments, and automatically updates Kubernetes
Getting your hands dirty
Flux is a tool that automatically ensures that the state of a cluster matches the config in git.
- It monitors all relevant image repositories
- Detects new images
- Triggers deployments and updates the desired running configuration based on that
fluxctl provides an API that can be used from the command line. To install the CLI with Homebrew:
brew install fluxctl
Export your credentials:
export GITHUB_TOKEN=<your-token> export GITHUB_USER=<your-username>
Check your Kubernetes cluster:
flux check --pre
Install Flux onto your cluster:
flux bootstrap github \ --owner=$GITHUB_USER \ --repository=fleet-infra \ --branch=main \ --path=./clusters/my-cluster \ --personal
See Installation for more info.
The bootstrap command above does following:
- Creates a git repository
fleet-infraon your GitHub account
- Adds Flux component manifests to the repository
- Deploys Flux Components to your Kubernetes Cluster
- Configures Flux components to track the path
/clusters/my-cluster/in the repository
Clone the git repository:
git clone https://github.com/$GITHUB_USER/fleet-infra cd fleet-infra
Add podinfo repository to Flux:
flux create source git podinfo \ --url=https://github.com/stefanprodan/podinfo \ --branch=master \ --interval=30s \ --export > ./clusters/my-cluster/podinfo-source.yaml
git add -A && git commit -m "Add podinfo GitRepository" git push
Deploy podinfo application:
flux create kustomization podinfo \ --target-namespace=default \ --source=podinfo \ --path="./kustomize" \ --prune=true \ --interval=5m \ --export > ./clusters/my-cluster/podinfo-kustomization.yaml
git add -A && git commit -m "Add podinfo Kustomization" git push
Watch Flux sync the application:
flux get kustomizations --watch
kubectl -n default get deployments,services