This post offers a brief introduction to GitOps and an overview of Argo CD, an open-source project implementing the GitOps approach. We had this opportunity at Packmind to experiment Argo CD, so we wanted to share with your our insights.
❓ What is GitOps?
GitOps is a concept promoted by WeaveWorks in 2017, with the core idea of describing the state of infrastructure in a Git repository. And Git is in the single source of truth.
Do you use Kubernetes and have dozens of YAML files? Maybe you even use Helm to deploy your app as a Chart? You now assume that all these configuration files are stored within a Git repository.
Every time developers perform modifications in the source code of your applications, your existing continuous integration process is executed: unit tests, packaging, and finally, a new Docker image is pushed. Your new Docker image is ready, and your CI pipeline ends by patching the infrastructure configuration on Git.
Finally, the Git operator (your GitOps tool) listens to any changes in the Git repo, identifies the delta between the current deployment and the configuration in Git, and applies the modification in production. This operator is thus the only entity allowed to perform changes in your environments.
Here is an overview of the GitOps workflow:
✨ Benefits of GitOps
Adopting a GitOps workflow presents many advantages:
- Using Git as a single truth of source reduces the risks of errors due to manual operations through any CLI or web interface. All the modifications in your production environment come from a Git commit.
- Each modification to the deployment environment is recorded in Git: we know what changed, when, and why (thanks to a commit message). You can consider it as documentation of your infrastructure. It's easy to review each modification and validate it through a pull request.
- Do you face issues after a new deployment and need to restore to the previous version? Very simple: revert the last commit and rollback your application.
- It becomes trivial to observe the difference between the configuration in Git and what is really deployed in your environment. So before each redeployment, you know what has changed.
🔎 Discover Argo CD
Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes. It's an open-source project and part of the Cloud Native Computing Foundation. We're now going to provide a quick demo on how to deploy your applications through Argo CD.
Setup
You'll find on the documentation a Getting Started section explaining how to install Argo CD, and expose it outside your Kubernetes Cluster.
$> kubectl create namespace argocd
$> kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
Get default password
When you first reach the welcome screen, you'll be prompted with a login/password. The default login is admin. To retrieve that password, you need to run the following command:
$> kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
The documentation explains how to update this password.
Configure our first project
On the menu on the left side, select the item "Manage your repositories, project, settings" item.
We're going to add first a repository (use yours, of course):
I'm using a public one here containing some charts. Now let's add a new project called wordpress. We're adding our source repository :
Let's also add the possible destination for this project. In this example, we will use the "dev" namespace we've created for this tutorial.
Now, let's go back to the main menu and let's create a new Application:
- Choose the project created previously
- Let the "Sync policy" as Manual
- Choose the repository containing your Git files, and set the path and/or the Git branch to synchronize. If it's a Helm chart, specify which values to use.
Validate the application, and click on "Sync". You'll see all your K8S components deployed. The UI is pretty cool, by the way:
Example of redeployment
In this example, we're now going to upgrade the WordPress version we're using. We update the Docker image tag :
Now, let's see what happens in Argo. If we click on the "Refresh" button, it forces the Git pull operation, but otherwise, it's automatic and takes a few seconds/minutes to be detected. This detects the new commit and marks the app as OutOfSync:
And then, if we click on "Diff", we can see the delta between what's deployed and configuration in the Git repository:
If we click on "Sync", Argo will redeploy the app. 🚀
Note that you've got the option to sync and deploy your app automatically. This can make sense in Dev environments if you're pushing new modifications every day. You need to edit the project and click on Enable Auto-Sync.
That's it for the Argo CD tour. The tool is very intuitive and does not offer a wide range of features. It goes straight to the goal.
🔣 Handle multiple environments of the same application
It's common to have different environments for your application: dev, staging, production,... Argo CD, like any GitOps, is designed to handle this situation. With Argo CD, we chose to create separate applications for each environment.
You can also create one project per application. The way you create an application depends on your infrastructure configuration. One method consists of using different branches in your Git repository and applying the pull request mechanism when changes need to be applied from a dev environment to staging and then to production, for instance. If you use Helm or any templating module, you can also use specific files in YAML containing all the values for your environments: values-dev.yaml, values-staging.yaml, values-prod.yaml, ...
✏️ Patch your infrastructure during your CI/CD
In our context, we had a dozen of micro-services, each having its own Docker image and a separate Git repository for the source code. The description of our Kubernetes infrastructure was in a single Git repository. One challenge we had was to redeploy the app on the Dev environment every day after each commit. However, as the Docker image name did not change after each commit, we had to find a way to inform the GitOps operator that something had changed.
Our strategy was to use metadata for each K8S Deployment element with a label corresponding to the Git commit (of the micro-service) used to build to Docker image. Something like this:
apiVersion: v1
kind: Pod
metadata:
labels:
app: analyzer
commit: 06d604bad53b
During our CI process with Jenkins (but you can do it with any tool), we used the script yq to patch the Git repository with the commit ID. So after each CI build, we patched the Git infrastructure.
That suited our needs, so we kept this process. Please note that there are certainly more proper ways to handle this situation: feel free to tell us in comments how you did ;)
🤗 That's all folks! We hope you now understand what GitOps is and how powerful it can be in managing your deployments. The feedback we had at Packmind was very positive. We'd be happy to receive your feedback and thoughts about Argo CD if you had a chance to use it.
Top comments (0)