GitOps in Kubernetes with Argo CD
What is GitOps?
Some advantages of using GitOps include:
ArgoCD basics
Deploying to Kubernetes with ArgoCD
Some ArgoCD concepts you should know
Deploying using the declarative approach
Deploying with helm
When some developers think of Infrastructure as Code (IaC), what typically comes to mind is using tools like Terraform to provision virtual machines and other cloud infrastructure.
In this tutorial, however, we will be taking a look at a Continuous Delivery strategy that allows us to not only define our infrastructure as code, but our application configuration as well using ArgoCD. Ready? Let’s dive into it!
What is GitOps?
GitOps is a Continuous Delivery strategy where our infrastructure and application configuration are defined as code and stored centrally in a version control system like Git. GitOps uses Git as a single source of truth. This means that it uses what is defined in the Git repository to configure your infrastructure and applications.
When deploying applications to Kubernetes with traditional DevOps CI/CD pipelines, an external tool like Jenkins is usually responsible for applying the Kubernetes manifests into the cluster. However, in a GitOps workflow, an agent is installed in the cluster and continually checks the Git repository for changes. When any change is detected, it attempts to update the cluster to reflect these changes. This way, the entire system can be defined declaratively and access to the cluster can be controlled.
Some advantages of using GitOps include:
- Faster and safer deployments
- Ease of performing rollbacks
- Better traceability
- It makes it easy to eliminate configuration drifts
Some popular GitOps tools include: ArgoCD, FluxCD and JenkinsX. In this article, we will focus on ArgoCD: an open source tool GitOps continuous delivery tool for Kubernetes, that’s part of the Cloud Native Computing Foundation.
ArgoCD basics
In this section, we will take a deep dive into ArgoCD, what it is, how to install, and how to deploy a basic application into it.
ArgoCD allows us to use Git as a single source of truth. This means that we define all our application configuration as code in a Git repository and ArgoCD updates our cluster to match what is defined in the repository.
In addition to watching the Git repository, it also watches the Kubernetes cluster for changes and syncs the state of the cluster back to what is defined in the Git repository if a change is detected in the cluster. Interestingly, a single ArgoCD installation can be used to manage multiple clusters as well.
Let’s install ArgoCD and take a look at it in action.
Prerequisites
To fully understand what will be covered in this part of the tutorial, here are the things you should set up on your computer:
- A Kubernetes cluster: We will be deploying applications to Kubernetes and as such, you need to have access to a Kubernetes cluster. For this tutorial, we will be using a tool called minikube to setup a local Kubernetes cluster for development. You can install it here.
- kubectl: We need kubectl in order to run commands against our Kubernetes cluster. You can install it here.
- Helm: Helm is a package manager for Kubernetes. Later in the tutorial, we will take a look at how we can deploy helm charts with ArgoCD so you need to have it installed. Follow the steps here to install it.
Finally, you’ll need to have basic knowledge of Kubernetes and the kubectl command-line tool.
Installation
The first thing we need to do is create a new namespace to group all the ArgoCD resources using the
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
Now, if you run the command
kubectl get pod -n argocd
With this pods now running, we will be able to see the ArgoCD web user interface (UI). But before we do that, we need to generate a password that will be used to access the ArgoCD UI. Run the command below to generate the password:
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -D; echo
Make sure you store this password securely as it will be used to gain access to your ArgoCD UI. Now, port-forward the argocd-server service to port 8080 of your local machine.
kubectl port-forward svc/argocd-server -n argocd 8080:443
Navigate to
http://localhost:8080
Sign in with the username
admin
Note: If you get a “Your connection is not private” message when trying to access the ArgoCD UI, ignore it and proceed. You received the message because ArgoCD uses a self-signed certificate which your browser does not trust.
Deploying to Kubernetes with ArgoCD
Now that we have ArgoCD installed in our Kubernetes Cluster, let’s deploy a basic application with it.
First, you need an application to deploy right? I have created a Git repository for this tutorial here, so go ahead and fork it. The repository contains all the files we will be using throughout the course of this tutorial.
In the web UI, click on
Create application
New app
- Application Name: This is the name of the ArgoCD application you are creating. You can call this anything you want but we will be calling it .
web-app
- Sync policy: This determines whether ArgoCD will automatically sync the cluster whenever a change is detected in Git. Set this to Manual for now.
- Project: Set this to .
default
- Source: Set this to the URL of the Git repository you forked in the previous step.
- Path: This is the folder in the repository where your application manifest files live. In our case, the folder is called .
demo
- Cluster URL: This refers to the URL of the Kubernetes cluster we are connecting to. Since we are connecting to a local cluster, set this to .
https://kubernetes.default.svc
- Namespace: This refers to the namespace where we will be deploying our application. Set this to .
default
Keep the other options as default and click on the Create button. This will create a new ArgoCD application.
Give it a few seconds and you should see that our application is
OutOfSync
sync
Click on synchronize and ArgoCD will now sync your cluster with the Git repository.
Now, if you should open another terminal window and run the command
kubectl get pod
To verify all is as it should be, run the command
kubectl port-forward svc/argocd-svc 8081:80
http://localhost:8081
Alright! We have successfully installed ArgoCD and deployed an application into a Kubernetes cluster with it. Now, let’s get an understanding of some ArgoCD concepts we need to get out of the way.
Some ArgoCD concepts you should know
Application health
As you saw in the demo above, ArgoCD keeps track of the sync status of all your applications, whether they are
Synced
OutOfSync
- Healthy: The resource is at a 100% optimal state.
- Progressing: The resource is not yet healthy but can still reach the Healthy state.
- Suspended: The resource is suspended or paused. Example a cron job that is currently not being executed.
- Missing: The resource can’t be found in the cluster.
- Degraded: The resource couldn’t reach an healthy state or failed.
- Unknown: The resource health state is unknown.
The health checks vary depending on the type of Kubernetes resource. For custom resources, you can write your own health-checks using Lua script. To learn more about ArgoCD health-checks, check out the official documentation.
Sync strategies
In the demo above, we used the Manual sync policy when we were creating our application. That means that ArgoCD will detect cluster changes but will do nothing about it. There are 3 parameters you can set when configuring the sync strategy.
- Manual/automatic sync: The manual sync has already been discussed in this article so let’s talk about the automatic sync here. The automatic sync basically means that whenever a change is detected in our Git repository, ArgoCD should update the cluster state to match it, automatically.
- Auto-prune: If this option is enabled, whenever a file is deleted in our Git repository, ArgoCD will delete the corresponding resource from the cluster. ArgoCD will never delete any resource from the cluster otherwise.
- Self heal: If this option is enabled, any manual change in the cluster will automatically be reverted by ArgoCD.
Note: Self heal and Auto-prune are only available for automatic sync.
By default, ArgoCD checks the Git repository for changes every 3 minutes. However, this can be changed as needed. For a full GitOps structure, it is usually advisable to enable Automatic sync, Auto-prune and Self heal.
In the next section, we will take a look at the various ArgoCD deployment strategies and how to implement them.
ArgoCD deployment strategies
There are multiple ways to deploy applications using ArgoCD. We’ve already used one above where we deployed the sample app from the UI. However, you could also deploy applications using the ArgoCD command line tool, the declarative approach, helm, and the ArgoCD CLI.
Deploying using the declarative approach
You can create ArgoCD components such as applications and Projects using manifest files like you would when creating any other Kubernetes resources. You create a YAML file and define the specifications of the application, then you apply it using the kubectl apply command. In the example below, we will be creating an ArgoCD application using the declarative approach.
First, delete the web-app application you created in the previous section.
Now create a file called application.yaml and paste in the following code.
apiVersion: argoproj.io/v1alpha1kind: Applicationmetadata:name: declarative-appnamespace: argocdspec:project: defaultsource:repoURL: https://github.com/utibeabasi6/argocd-configtargetRevision: HEADpath: "demo"destination:server: https://kubernetes.default.svcnamespace: defaultsyncPolicy:automated:selfHeal: trueprune: true
Let’s take a look at what each line of this code is doing. First we are using the
argoproj.io/v1alpha1
Application
In the metadata section, we are defining the Application name as
declarative-app
argocd
Under spec, we set the project to
default
repoURL
syncPolicy
Now apply this file just like you would with any other Kubernetes resource by running
kubectl apply -f application.yaml -n argocd
application.yaml
If you notice, we are deploying this in the argocd namespace. This is because all argocd components must be deployed in the namespace where ArgoCD was installed. By default, this is
argocd
When deploying applications with ArgoCD, it can become quite challenging to write the different YAML files for your configuration. But with just a few clicks on Telepresence you can now manage the entire canary release and continuous delivery workflow via Argo from a single pane of glass. Here’s a tutorial on how to deploy applications with Argo via Telepresence.
Deploying with helm
Helm is a package manager for Kubernetes. It allows you to package, distribute and install multiple Kubernetes manifests with a single command. You can get a primer on helm from the official website.
Apart from traditional Kubernetes manifests like deployments and services, ArgoCD also has native support for helm charts. Let’s take a look at how to do this.
In the ArgoCD UI, create a new application and fill in the values as you did for the demo application except now, you will set the name to
helm-demo
Automatic
helm
In the repository you forked earlier, I had created a basic helm chart in the
helm
Helm
values.yaml
Now, create the application by clicking the
Create
helm
One thing to note is that when ArgoCD deploys a helm chart, the chart is now managed by ArgoCD and will no longer show up if you run the
helm list
ArgoCD has a command line tool that allows you to perform all the operations we have been doing from the UI, programmatically. You can install the CLI for your operating system by following the instructions here.
Next, log in to ArgoCD by running the command
argocd login localhost:8080 --username admin --password <your_password>
Replace
your_password
Now to deploy an application from the command line, run the following command from your terminal:
argocd app create cli-app \--repo https://github.com/utibeabasi6/argocd-config \--path cli \--dest-server https://kubernetes.default.svc \--dest-namespace default
Now, if you head over to the UI, you will see the
cli-ap
But if you observe, you will see that the app is un-synced since we did not enable automatic sync. Now let’s sync the app from the command line. Run the command
argocd app sync cli-app
Head back to the UI and you will see that the cli-app has now been synced.
To delete applications via the CLI, run the command
argocd app delete <application_name>
Conclusion
It can get challenging deploying applications to Kubernetes. Thankfully, tools like ArgoCD have been invented to streamline the process and significantly improve developer experience.
In this article, we have taken a look at ArgoCD, how to install it, how to deploy applications with it and some deployment strategies you can implement when using ArgoCD. I hope this article was helpful and insightful. Thank you for reading!✌️