Lesson: Pull-Based Deployment with Argo CD
What you'll learn
- The GitOps principle: Git as the single source of truth for what runs in your cluster.
- What an Argo CD Application is, what sync means, and how drift detection works.
- How pull-based deployment contrasts with the push-based CI you've seen so far.
- How to deploy an app to the lab's live Kubernetes cluster with Argo CD.
By the end you can explain GitOps to a teammate and define an Argo CD Application that deploys to the lab cluster.
The lesson
In the concepts chapter you met pull deployment: instead of the CI pipeline pushing changes into production, a tool inside the environment watches Git and pulls changes in. GitOps is that idea made into a discipline, and Argo CD is the most popular tool for doing it on Kubernetes. This chapter shows how it works and has you deploy to the lab's real cluster (master 10.100.100.7).
1. The GitOps principle
GitOps rests on one rule: the desired state of your system is described declaratively in Git, and an automated agent continuously makes the cluster match Git.
"Declaratively" means you describe what you want (e.g. "3 replicas of myapp version abc123"), not how to get there. Kubernetes manifests (YAML) are already declarative, which is why GitOps and Kubernetes fit so well.
The four GitOps principles, in plain words:
- Declarative — the whole system is described as data, not scripts.
- Versioned in Git — that description lives in Git, so it has history, review, and rollback.
- Pulled automatically — an agent applies the Git state; no human runs
kubectl apply. - Continuously reconciled — the agent constantly checks that reality matches Git and corrects any difference.
The practical payoff: Git is the single source of truth. Want to know what's running? Read the repo. Want to roll back? git revert. Want an audit trail? It's the commit history.
2. Push CI vs pull GitOps
Compare the two models for the deploy step:
PUSH (classic CI deploy):
+-----------+ builds image +-----------+ kubectl apply +-----------+
| CI runner |----------------> | registry | | cluster |
| (Gitea, | |10.100.100.6|<-- CI also reaches|10.100.100.7|
| .11) |---- has cluster credentials --- and pushes ----->| |
+-----------+ +-----------+ +-----------+
The CI runner needs production credentials. It initiates the change.
PULL (GitOps with Argo CD):
+-----------+ builds image +-----------+
| CI runner |----------------> | registry |
| (.11) | |10.100.100.6|
+-----+-----+ +-----------+
| updates a manifest in Git (image tag = new sha)
v
+-----------+ Argo CD watches & pulls +-----------+
| Git repo |<------------------------------| Argo CD |
| (manifests)| | (in cluster|
+-----------+ | .7) |
+-----------+
CI only touches Git. Argo CD, inside the cluster, pulls and applies.
The crucial difference: in the pull model, production credentials never leave the cluster. Your CI runner only needs write access to a Git repo and the image registry — not to the cluster. That shrinks the blast radius if your CI is ever compromised, and it means every change to production is a Git commit you can see and revert.
3. The Argo CD Application
Argo CD runs inside your Kubernetes cluster. You tell it what to manage by creating an Application — itself a Kubernetes resource. An Application answers three questions: where is the desired state (source)?, where should it go (destination)?, and how should it sync?
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp
namespace: argocd
spec:
project: default
source:
repoURL: https://gitea.example.com/intern/myapp-deploy.git
targetRevision: main # which branch/tag to track
path: k8s # folder of manifests within the repo
destination:
server: https://kubernetes.default.svc # the cluster Argo CD lives in
namespace: myapp
syncPolicy:
automated:
prune: true # delete resources removed from Git
selfHeal: true # undo manual changes that drift from Git
Read it as a sentence: "Watch the k8s/ folder on the main branch of this repo; keep namespace myapp in this cluster matching it; do it automatically."
4. Sync, drift, and self-heal
Two concepts make Argo CD powerful:
-
Sync = the act of making the cluster match Git. Argo CD compares the manifests in Git (desired) with what's actually running (live). If they differ, the Application is OutOfSync; running a sync applies the Git version. With
syncPolicy.automated, this happens on its own whenever Git changes. -
Drift detection = Argo CD continuously notices when the live cluster diverges from Git — for example if someone manually runs
kubectl editand bumps the replica count. The Application goes OutOfSync and Argo CD shows you exactly what differs. WithselfHeal: true, it automatically reverts the cluster back to what Git says. Git wins — always.
Git says: replicas=3 Live cluster: replicas=5 (someone edited it)
| |
+-----> Argo CD compares <-+
|
status = OutOfSync, diff shown
|
selfHeal -> sets replicas back to 3
prune: true extends this to deletions: if you remove a resource from Git, Argo CD removes it from the cluster too. This is what "Git is the source of truth" really means in practice — the cluster has no state that isn't in Git.
5. How a deploy actually flows in the lab
Putting the whole module together, here's the end-to-end flow you'll build across the assignments:
- You push app code to Gitea. The Actions runner on
10.100.100.11builds a container image tagged with the commit SHA and pushes it to the registry at10.100.100.6(Module chapter 2). - The image tag in your deployment manifest (in a Git repo Argo CD watches) is updated to the new SHA — either by hand at first, or automated later.
- Argo CD, running in the cluster (
10.100.100.7), sees the manifest changed, marks the Application OutOfSync, and syncs — pulling the new image and rolling out the update. - If anyone manually messes with the running app, drift detection flags it and
selfHealputs it back.
You never run kubectl apply against production yourself. You commit to Git; Argo CD does the rest.
6. When push is still fine
GitOps isn't mandatory for everything. For a tiny project, a push-based kubectl apply step in your CI is simpler and perfectly acceptable. GitOps shines when you have multiple environments or clusters, want strong audit/rollback, and want to keep cluster credentials out of CI. As the number of things you deploy grows, pull-based GitOps scales better and is safer.
Dig deeper
- Argo CD — Getting Started
- Argo CD — Application specification reference
- Argo CD — Automated sync policy (prune & self-heal)
- OpenGitOps — GitOps Principles
- Argo CD — Tracking and deployment strategies
Search terms
what is gitops explained simplyargo cd application crd tutorialargo cd sync drift self healpush vs pull deployment kubernetes argo cdargo cd automated sync prune selfhealgitops single source of truth git
Check yourself
- State the one rule that GitOps rests on.
- In the pull model, why don't your CI runner need credentials to the cluster?
- What three questions does an Argo CD
Applicationanswer? - What does it mean for an Application to be OutOfSync, and what does
selfHeal: truedo about it? - Walk through, in order, what happens in the lab from "you push app code" to "the new version is running" without you ever typing
kubectl apply.
No comments to display
No comments to display