On a chilly November morning in 2020, it's GitOps Days, and we heard Alexis Richardson via Video Conferencing speak. Git allowed us to do Cloud-native development. It gave us the tooling for a distributed source control, continuous integration, container image distribution, and others.
The rate of development improved with Git. However, the one thing that Git did not give us is better operations. Git focuses on collaboration between developers and versioning, but it was never intended to help in operations. However, this was the case before GitOps.
GitOps gives you a mechanical, programmatic, automated way to operate. But why? Why would you want this new way to operate? Why does this matter?
Ok, before we dig deep into any answers, let's start with another question: How do you know your systems are in a correct state now?
If your auditors come to your office the next morning and ask if all your applications are running in your Kubernetes Cluster in a correct state now? How do you prove that?
I'm your host Kassandra Russell. In this episode, we will dive deep into GitOps and its raison d'etre.
We will answer questions you may have asked about GitOps, like the advantages and disadvantages of adopting it. We will also walk through the important patterns and security considerations in adopting GitOps.
Why move to this model? How can it help me? What do I do next? There are so many questions when adopting a new model of working. It can even seem overwhelming at times. But before that.
Let's start with a bit of history. Here at Faun, we went through DevOps' adoption as the de facto culture for working in the cloud.
In this podcast, we discussed Kubernetes and how it won the container orchestration war. To recall, one of the biggest strengths of using Kubernetes was the declarative nature of how everything is defined.
Let's say you want to create a pod. Instead of going through a wizard or a dialog box, you instead create data, usually in JSON or YAML format.
YAML and JSON formats are constrictive in a way because they do not allow you to write the logic in them. This means you cannot write if-else statements or any other procedural functions to control resource creation.
In a nutshell, they allow you to declare intent rather than a procedural instruction.
Declaring intent or declarative instruction means you allow the system to figure out any way to get towards that intention without giving explicit instruction on how to do it.
For a concrete real-world example: Imagine you are on vacation in Tokyo, you went to Starbucks again for a second time. You queued up in the cashier and started to order: "Latte please with two shots of espresso."
The way you ordered your drink is declarative in nature. You declare the end result of your intent.
Imagine a second scenario, where instead of going to Starbucks, you went to a cooking class, where they taught you how to make Japanese pizza.
First, you chop the spring onions, then slide the bacon into bite-size pieces. Brush the top of your pizza dough with okonomiyaki sauce, then top with all veggies and bacon add some melty cheese.
Cook the pizza for 15 minutes. Then once done, garnish the Okonomiyaki, the Japanese pizza, with brown sauce, tempura flakes, and Aonori seaweed. Enjoy!.
What you just heard is an example of a procedural approach to solve a problem.
Procedural means that there is a single way, and the goal is usually secondary to the process.
Declarative means there is more than one way to achieve a goal, and intent matters more. In effect, you can get the desired state of any system upfront if you use the declarative approach.
The desired state is the foundation of GitOps.
If we have the desired state of any application, cluster, environment, or any system, does that mean we can automate all of those?
The big answer is YES!
Albert Einstein popularized an equation. E equals MC squared. Very simple and concise formula. Let's use the same thought to define what is Gitops.
GitOps equals Desired State plus Automation.
Just like how we derived a lot of insights into Einstein's formula, we can derive insights into our GitOps formula.
Let's look back at one of the previous questions asked in the introduction.
Hello, I'm the Auditor of PKMG company. I'm here to audit all your deployments in your Kubernetes cluster if they are in the correct state. Finally, I would check your cluster as well for the correct state to make sure that there is no misconfiguration. For the first time, it will be a manual audit; however, moving forwards, I will be expecting a weekly report of the correctness of both your cluster and applications.
What is the correct state? Do we have a way to prove the state of the application? What about the cluster? Is there a way we can prove the state of the cluster?
GitOps allows us to declare what the correct state is on Git. This idea of "Is everything in the correct state" can be answered through GitOps. This is done by simply comparing the declared state in Git against the actual state of the cluster.
What do we mean here?
Imagine you declare in Git that the cluster should have 100 nodes, but in actuality, the cluster had 99, then your cluster is not in the correct state.
Yes, this is a simplistic example of how GitOps assesses the correctness of the state. Let's go for a realistic example.
Let's say you are running an e-commerce application sending lots of boxes of goodies to your customers. One of the services you use in order to get payments from your customers is the eloquently called payments application.
One day your payment application stopped working started replying with a timeout. You started to wonder why.
Since your app was deployed using GitOps, you started looking at the correct state of the payments application in Git. Then you read that the Payments Application should be deployed with 100 Pods. But when you logged into your Kubernetes cluster, you spotted only 50 pods. You manually changed the application to have 100 Pods, and the payments app started working again!
Now the application is in the correct state. This is a very simple but straightforward way to describe applications.
In reality, though, you will probably not do this manually.
Another key concept of GitOps is automation. If you can declare what the correct state is, then the next thing to do is create an Automation.
The primary purpose of automation is to ensure that the correct state is the same as the actual state all the time. This is achieved by creating an infinitely looping controller. In GitOps terms, we call these "software agents."
In our example, the software agent is supposed to automatically fix the payment application and run a command to force the application to create 50 more pods to reach the correct state of 100 pods.
In other words, software agents run reconciliation loops to force the actual state to be the same as the correct state.
We will discuss this topic in more detail in the next episode.
How about the disadvantages?
One reason not to use GitOps is the high upfront investment in teaching your developers this new model of operations. This is more around the fundamental issue that change is hard.
Any change is hard. This is especially true for more established companies with a well-defined process.
They rely on these processes to ensure the availability and consistency of their services. In consequence, within this type of organization, a lot of change should happen when adopting GitOps.
Another issue is the fact that since deployments are done declaratively, changes happen on an eventual consistency model. This means that once you make a deployment or a change in the correct state, it doesn't happen right away; it happens eventually. There are ways to force those changes right away, but by default, it is eventually consistent.
Last but not least, GitOps is a relatively new concept. There are not many tools that allow you to implement its principles. Nevertheless, here at Faun, we will update you with any new tools or frameworks that we come across to help your journey in adopting GitOps. We curate plenty of useful and new tools weekly on Faun newsletters, so If you are not subscribed, join us on "www.faun.dev/join"
To summarize, this is what you should keep in mind:
GitOps is not a replacement for DevOps, but a paradigm that relies on your app's state using Git as a single source of truth.
GitOps allows to know the state's correctness and measure it at any time. With GitOps, you can easily redeploy your applications and clusters on any Kubernetes cluster, and you will always get the same result; however, don't confuse it with Infrastructure-as-code.
GitOps has several disadvantages since it's relatively new. However, its declarative nature allows for more advanced capabilities like the auditability of all the changes, increases your development teams' autonomy, brings you closer to a DevOps culture, and improves security.
In this episode, we discussed the basics, advantages, and disadvantages of GitOps.
There are still many unanswered questions like how does GitOps work with databases or other stateful applications? How do we ensure Observability for GitOps enabled clusters or applications? And how do we use GitOps in a non-kubernetes environment? So, stay tuned for the next part. We will learn how to deploy an application using a GitOps pipeline and try to answer most of your questions about this new paradigm.