GitOps is a modern way to manage Kubernetes deployments.
Key points:
- Git = Source of Truth → All Kubernetes manifests live in Git.
- Declarative → You describe what you want (YAML), not how to do it.
- Pull-based → A tool (like Argo CD) pulls from Git and updates the cluster.
- Continuous Reconciliation → It keeps checking if the cluster matches Git, and fixes it if not.
Why GitOps?
- Every change is tracked in Git history.
- Easy rollbacks.
- Fewer manual mistakes.
- Strong security (no direct cluster access for everyone).
Definition: Argo CD is a GitOps operator for Kubernetes that:
- Continuously monitors a Git repo.
- Deploys changes automatically or manually.
- Shows visual status in a Web UI.
- Can manage multiple clusters.
Argo CD Components:
- argocd-server → Web UI + API.
- application-controller → Syncs Git with cluster.
- repo-server → Fetches Git repo, processes Helm/Kustomize.
- Redis → Cache for performance.
- You define your Kubernetes YAML in Git.
- Argo CD pulls those files.
- It compares Git (desired state) vs Cluster (live state).
- If different → you sync manually or auto-sync.
- If auto-sync + self-heal → it updates automatically.
We install Argo CD in its own namespace:
kubectl create namespace argocd
kubectl apply -n argocd \
-f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yamlCheck if all pods are running:
kubectl get pods -n argocdSince we’re using a self-managed kubeadm cluster, we’ll use NodePort:
kubectl -n argocd patch svc argocd-server \
-p '{"spec":{"type":"NodePort","ports":[{"name":"https","port":443,"targetPort":8080,"nodePort":30080}]}}'
# Switch the existing service to an internet-facing ELB
kubectl patch svc argocd-server -n argocd -p '{"spec":{"type":"LoadBalancer"}}'
# (Optional but recommended) ensure it listens on 80/443 cleanly
kubectl patch svc argocd-server -n argocd --type='json' -p='[
{"op":"replace","path":"/spec/ports/0/port","value":80},
{"op":"replace","path":"/spec/ports/1/port","value":443}
]'
Get Node Public IP:
kubectl get nodes -o wideOpen browser:
https://<NODE_PUBLIC_IP>:30080
Note: Accept security warning (self-signed certificate).
Get the admin password:
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -d; echo- Username:
admin - Password: (from above)
We will deploy the Guestbook app.
kubectl create namespace dev- Go to: https://github.com/argoproj/argocd-example-apps
- Click Fork into your GitHub account.
-
Click NEW APP.
-
Fill in:
- Application Name:
guestbook-dev - Project:
default - Sync Policy: Manual (first time)
- Repository URL: (Your fork HTTPS URL)
- Revision:
main - Path:
guestbook - Cluster URL:
https://kubernetes.default.svc - Namespace:
dev
- Application Name:
Click CREATE.
- Open the new app.
- Click SYNC → Synchronize.
- Argo CD will create Kubernetes resources.
kubectl get pods -n dev
kubectl get svc -n devYou should see the guestbook pods running.
Step 1 – Enable Auto-Sync
- In the app → App Details → Actions → Enable Auto-Sync.
- Check Prune and Self-Heal.
Step 2 – Change in Git → Auto Deployment
- In your fork, edit
guestbook-ui-deployment.yaml:
replicas: 1change to:
replicas: 3- Commit and push.
- Argo CD will detect the change and deploy automatically.
Step 3 – Self-Heal Manually scale in cluster:
kubectl scale deploy guestbook-ui -n dev --replicas=5- Wait ~1 min → Argo CD will revert it back to 3.
Summary for Students:
- Argo CD is a GitOps tool for Kubernetes.
- Everything comes from Git.
- You can deploy manually or automatically.
- Self-Heal enforces Git state on the cluster.
- NodePort is easiest for accessing Argo CD in self-managed clusters.
# Install Argo CD
kubectl create ns argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# Access via NodePort
kubectl -n argocd patch svc argocd-server -p '{"spec":{"type":"NodePort","ports":[{"name":"https","port":443,"targetPort":8080,"nodePort":30080}]}}'
kubectl get nodes -o wide # get public IP
# Get password
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo
# Create namespace for app
kubectl create ns dev
# Verify resources
kubectl get pods -n dev
kubectl get svc -n dev- Try deploying another app from the same repo.
- Enable auto-sync + self-heal for it.
- Change replicas in Git and watch Argo CD update.
- Delete a pod manually → see self-heal recreate it.