2026-07-18 · trace
Once I push to git, how does the change actually reach the cluster — without anyone running kubectl?
The first time I set up ArgoCD, I kept looking for the step where something "pushes" to the cluster. There isn't one. That absence is the whole idea, and it took me a while to stop looking for it.
In a normal pipeline, CI ends by running kubectl apply — the pipeline reaches
into the cluster and changes it. GitOps inverts that. Nothing reaches in.
Instead, git holds the desired state, and an agent inside the cluster
continuously pulls git and makes the cluster match. So I stopped asking "how does
my change get deployed?" and started asking a better question: what is the
cluster's source of truth, and who reconciles toward it?
The trace
Say I change application code and push it. Here's the actual path:
1. CI builds an artifact, not a deployment
The commit triggers GitHub Actions, which builds a container image and pushes it to a registry, tagged with the commit SHA. Notice what CI does not do: it never talks to the cluster. Its only job is to turn source into an immutable, addressable image.
2. The new tag is written back to git
The desired state of the cluster lives in a git repo — Helm values and manifests that say "run image X." So something has to update "image X" to the tag CI just produced. Argo CD Image Updater watches the registry, sees the new tag, and commits that change back to the git repo. This surprised me: the pipeline's output isn't a running Pod — it's a git commit.
3. ArgoCD notices git and the cluster disagree
An ArgoCD Application points at that repo. ArgoCD constantly compares two
things: the desired state (git) and the live state (the cluster). The moment the
Image Updater's commit lands, they diverge — ArgoCD marks the app
OutOfSync.
4. Sync converges the cluster toward git
With automated sync on, ArgoCD renders the Helm chart with the new values and applies the result — creating, updating, or pruning resources until the live cluster matches git exactly. The Deployment rolls out the new image; the old Pods go away. The cluster converged; nobody deployed to it.
5. It keeps watching
This is the part that changed how I think. Reconciliation doesn't stop after the
sync. If someone hand-edits a resource with kubectl, ArgoCD sees the drift from
git and (with self-heal) undoes it. The cluster isn't set to a state — it's
held at a state.
What I understood
- Git is the source of truth, not a trigger. The repo doesn't kick off a deploy; it describes reality, and the cluster is made to agree.
- It's a control loop, not a pipeline. "The pipeline pushes to the cluster" and "an agent pulls git and reconciles" produce the same Pods but are opposite mental models — and only the second one self-heals and detects drift.
- CI and CD are cleanly split. CI produces an image and a git commit. CD (ArgoCD) is the only thing with cluster credentials. That boundary is a security property, not just tidiness.
- Rollback is
git revert. If the state lives in git, going back is just moving git back and letting reconciliation do the rest.