GitOps is a set of practices to deploy applications using Git. Application definitions, configurations, and connectivity are to be stored in a version control software such as Git. Git then serves as the single source of truth for the declarative infrastructure and its hosted applications.
Using GitOps means that any change to the deployment must be addressed in a git commit. A continuous delivery operator then diffs the commit and synchronizes the state between the repository and the targeted environment.
The main advantage of GitOps is how every change is versioned and verifiable. Versionning makes it easy to roll back to a previous state in case of errors. Disaster recovery is also simplified. The source of truth remains unchanged and you only need to switch the targeted environment.
The article present how we use ArgoCD to synchronize the state of our Kubernetes clusters. It covers its installation and usages using a simple example application hosted on GitHub.
Since Kubernetes manifests are declarative, it fits perfectly the CI/CD pattern and most GitOps tools focus on Kubernetes.
In practice
It is a good practice to isolate your application source code from your deployment state definitions between 2 distinct Git repositories. YAML files are used to describe the Kubernetes cluster, including Deployments, ConfigMap, Secrets, …
The deployment state repository is organized with the layout:
./myapp-ops
├── base
│ ├── deployment.yaml
│ ├── kustomization.yaml
│ └── service.yaml
├── dev
│ ├── deployment-patch.yaml
│ └── kustomization.yaml
└── prod
├── deployment-patch.yaml
└── kustomization.yaml
Here we are using kustomize for our declarative configuration customization. dev
and prod
directory defines the state of our application and shares a common base
. Dev and Prod can be deployed in the same or different Kubernetes clusters according to our needs.
The typical workflow for a new feature in an application using GitOPs is as follow:
- The code is pushed to the code repository.
- The code is built and tested in the CI platform.
- The code is shipped: a docker image is built and pushed to a registry.
- The CI pipeline commits and pushes a new version into to the deployment repository.
- This push triggers a synchronization: the new code is automatically deployed to the target infrastructure.
Users are free to commit to the deployment repository by themselves, for example they can set the number of ReplicaSet of a deployment.
ArgoCD
ArgoCD is a GitOps operator that synchronizes the state described in a Git repository with a deployment in one or multiple Kubernetes clusters.
ArgoCD supports multiple format for the declarative definitions (Kustomize, Helm, Ksonnet or plain-YAML).
It is implementend as a Kubernetes controller that monitors the Git repository and the live deployment. If for some reason the live status deviates from the target (waiting for user input, deployment failed, manual rollback…), the application is considered OutOfSync
.
ArgoCD Installation
A simple ArgoCD installation is straightforward:
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath=".data.password" | base64 -d && echo
kubectl patch svc argocd-server -n argocd -p '"spec": "type": "LoadBalancer"'
kubectl port-forward svc/argocd-server -n argocd 8080:443
The next step is to install the argocd-cli
command following the official ArgoCD CLI installation.
More documentation on the installation (User Management, High Availability, Observability …) are available here.
ArgoCD Usage
Now let’s create an ArgoCD app using the CLI. It can be done easily through the Web UI.
argocd login $myargocd:8443
argocd app create demo-app-dev --repo https://github.com/PACordonnier/demo-cicd-ops.git --path dev --dest-server https://kubernetes.default.svc --dest-namespace dev
argocd app get demo-app-dev
Name: demo-app-dev
Project: default
Server: https://kubernetes.default.svc
Namespace: dev
URL: https://192.168.39.5/applications/demo-app-dev
Repo: https://github.com/PACordonnier/demo-cicd-ops.git
Target:
Path: dev
SyncWindow: Sync Allowed
Sync Policy: Automated
Sync Status: Synced to (babc0df)
Health Status: Healthy
$ argocd app set demo-app --sync-policy auto
Navigating the Web UI, we can see all the objects managed by ArgoCD as well as their current state:
Conclusion
If you are using Kubernetes for your deployment and struggle to be aware of what is deployed on your environments, GitOps is for you. Implementing it is no rocket science and can only benefit your DevOps compliance.
ArgoCD is a great product. It solves a real problem while being convenient and easy to use.