Argo CD can run in high availability (HA) mode, but it doesn’t actually make the application highly available; it makes the control plane highly available.
Let’s see Argo CD in action. Imagine you have a Kubernetes cluster and you want to deploy an application using GitOps. You’ve got your application definition in a Git repository.
# Example Git Repository Content: app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
destination:
namespace: default
server: https://kubernetes.default.svc
project: default
source:
repoURL: https://github.com/your-username/your-repo.git
targetRevision: HEAD
path: path/to/your/app
syncPolicy:
automated:
prune: true
selfHeal: true
When you create this Application custom resource in your argocd namespace, Argo CD’s controller, running in the argocd namespace, detects it.
kubectl apply -f app.yaml
The controller then fetches the manifests from your Git repository (https://github.com/your-username/your-repo.git) and compares them to the desired state in your Kubernetes cluster. If there’s a difference, it creates, updates, or deletes Kubernetes resources to match the Git state.
Now, what happens if that single Argo CD controller pod dies? Your applications stop being reconciled. New deployments won’t be picked up, and if a manual sync was in progress, it might be left in an inconsistent state. This is where High Availability comes in.
To run Argo CD in HA mode, you deploy multiple replicas of the Argo CD controller. The key is that these controllers coordinate via a shared PostgreSQL database. Each controller instance watches the PostgreSQL database for changes to Argo CD’s internal state and the desired state of applications.
Here’s how you typically configure it in your argocd-ha StatefulSet definition (or when installing via Helm):
# Example argocd-ha StatefulSet snippet
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: argocd-server
namespace: argocd
spec:
replicas: 3 # <-- This is the HA part
template:
spec:
containers:
- name: argocd-server
# ... other container config ...
env:
- name: ARGOCD_APPLICATION_CONTROLLER_REPLICAS
value: "3" # <-- Inform controllers about the HA setup
- name: ARGOCD_DB_USER
valueFrom:
secretKeyRef:
name: argocd-db
key: user
- name: ARGOCD_DB_PASSWORD
valueFrom:
secretKeyRef:
name: argocd-db
key: password
- name: ARGOCD_DB_HOST
value: "argocd-postgresql.argocd.svc.cluster.local"
- name: ARGOCD_DB_PORT
value: "5432"
- name: ARGOCD_DB_NAME
value: "argocd"
The ARGOCD_APPLICATION_CONTROLLER_REPLICAS environment variable tells the controller instances how many replicas are expected. This is crucial for leader election and ensuring only one controller is actively reconciling at any given moment. The PostgreSQL database acts as the single source of truth for both the application state and the controller’s internal state.
When a controller pod starts, it attempts to acquire a lock in the PostgreSQL database. The controller that successfully acquires the lock becomes the "leader" and is responsible for reconciling applications. If the leader pod fails, the lock is released, and another available controller pod will acquire it, becoming the new leader. This failover happens automatically.
The argocd-server deployment also typically runs with multiple replicas, often behind a Kubernetes Service of type LoadBalancer or Ingress, to ensure the UI and API are always accessible. However, the application reconciliation HA is handled by the argocd-application-controller component, which is often deployed as a separate StatefulSet or managed within the main argocd-server StatefulSet.
The most surprising thing about Argo CD HA is that while you run multiple controller pods, only one is actively performing synchronization operations at any given time. The others are on standby, ready to take over. This prevents race conditions where multiple controllers might try to update the same resource simultaneously, leading to unpredictable states.
The next logical step is to explore how Argo CD handles secrets and credentials for accessing Git repositories and Kubernetes clusters in an HA setup.