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.
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.
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 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
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.
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:
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.