K3s, a stripped-down Kubernetes distribution, and Argo CD, a declarative GitOps continuous delivery tool, form a surprisingly powerful combination for managing Kubernetes clusters, especially in resource-constrained environments.
Let’s watch Argo CD in action, deploying an application to a K3s cluster.
First, we need a K3s cluster. A minimal install looks like this:
curl -sfL https://get.k3s.io | sh -
sudo k3s kubectl get nodes
This spins up a single-node K3s cluster. Now, we’ll install Argo CD. We can apply its manifest directly:
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
After a minute, Argo CD’s components will be running. We can expose the UI and CLI using a LoadBalancer service (or NodePort/port-forwarding for local testing).
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
You’ll then get an external IP for argocd-server. The default credentials are admin and the password found in the argocd-initial-secrets secret.
Now, let’s set up a Git repository to hold our application’s desired state. A simple kustomization.yaml and a deployment manifest will do:
gitops-repo/my-app/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
commonLabels:
app: my-nginx
gitops-repo/my-app/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: my-nginx
replicas: 2
template:
metadata:
labels:
app: my-nginx
spec:
containers:
- name: nginx
image: nginx:1.21.6
ports:
- containerPort: 80
With our Git repository ready, we tell Argo CD about it and create an application. We can do this via the UI or the CLI.
CLI approach:
First, log in to Argo CD:
argocd login <ARGO_CD_SERVER_IP>
Then, create the application, pointing to our Git repo and the path containing our manifests:
argocd app create my-nginx-app \
--repo https://github.com/your-username/gitops-repo \
--path my-app \
--dest-server https://kubernetes.default.svc \
--dest-namespace default
Argo CD will now continuously monitor the specified Git repository. When it detects a change in the my-app directory, it will automatically reconcile the state of the default namespace in our K3s cluster to match the manifests in Git. You can see this happening in the Argo CD UI, where it shows the desired state (from Git) and the current state (in the cluster), highlighting any differences. A click of "Sync" (or auto-sync enabled) brings the cluster in line.
The core problem Argo CD solves is drift: the inevitable divergence between your intended infrastructure state and its actual state. By enforcing Git as the single source of truth, Argo CD automates the detection and remediation of this drift. It works by continuously comparing the desired state defined in your Git repository with the live state of your Kubernetes cluster. When a discrepancy is found, Argo CD can automatically update the cluster to match Git, or it can flag the drift for manual intervention.
Internally, Argo CD operates as a set of controllers within your Kubernetes cluster. The argocd-repo-server fetches manifests from Git repositories. The argocd-application-controller compares these manifests against the live state of your cluster, using Kubernetes API calls. When a sync is triggered, it generates and applies the necessary Kubernetes API calls (e.g., kubectl apply) to bring the cluster into the desired state.
The "dest-server" parameter in argocd app create is a crucial lever. While https://kubernetes.default.svc points to the current cluster where Argo CD is running, you can point Argo CD to other Kubernetes clusters. This allows a single Argo CD instance to manage multiple clusters, making it a powerful tool for multi-cluster GitOps. You simply register the target cluster with Argo CD and then specify its server endpoint when creating the application.
The secret to truly declarative deployments with Argo CD isn’t just having manifests in Git; it’s treating Git as the only way to change your cluster’s state. Any direct kubectl commands or UI modifications bypass Argo CD and will be corrected (or flagged) on the next sync cycle. This strict adherence ensures that the Git history becomes a complete audit log of all changes to your infrastructure.
The next concept you’ll likely explore is managing Argo CD applications themselves using GitOps.