World map

 

BM: Baca dalam Bahasa Melayu

World K7: Self-Driving

Self-heal and drift

You will learn: what drift is, and how self-heal or Sync puts Git's version back.

Checked with Kubernetes 1.37 on 31 Oct 2026

The problem

You are here: cluster kind-dev namespace default
kubectl get deployment shop shows 1/1 ready, but shop.yaml in Git asks for 3. Terminal output: $ kubectl get deployment shop NAME READY UP-TO-DATE AVAILABLE AGE shop 1/1 1 1 37s

Git asks for 3 trays. The cluster runs 1. The floor no longer matches the order board. This gap is called drift: The floor no longer matches the order board: the cluster differs from Git, often after a change by hand..

Try it

Self-heal is on. Make a manual change with the kubectl button. Then watch.

Change the cluster by hand. Then get that change undone.

Git (the order board)

apps/shop/deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
name: shop
spec:
replicas: 3
# selector and template: same as before
image:
Show the whole file
apiVersion: apps/v1
kind: Deployment
metadata:
  name: shop
  namespace: shop
spec:
  replicas: 3
  selector:
    matchLabels:
      app: shop
  template:
    metadata:
      labels:
        app: shop
    spec:
      containers:
        - name: web
          image: ghcr.io/kedai-kancil/shop:1.4.0

Commits

  1. f89a8e9 Add shopin the cluster

Cluster · namespace shop

Sync: SyncedHealth: Healthy

Deployment shop: 3/3 ready · image 1.4.0

Manual change (drift)
syncPolicy:
  automated:
    selfHeal: true
Show the Argo CD Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: shop
  namespace: argocd
spec:
  project: default
  source:
    repoURL: "https://github.com/kedai-kancil/gitops.git"
    path: apps/shop
    targetRevision: main
  destination:
    server: "https://kubernetes.default.svc"
    namespace: shop
  syncPolicy:
    automated:
      selfHeal: true
Nothing to do. Git and the cluster match.

Predict

Now self-heal: Argo CD puts Git's version back by itself when someone changes the cluster by hand. is off. Someone scales to 1 by hand. What happens?

Pick one answer.

Try it

Self-heal is off. Make the manual change, then undo it yourself.

Change the cluster by hand. Then get that change undone.

Git (the order board)

apps/shop/deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
name: shop
spec:
replicas: 3
# selector and template: same as before
image:
Show the whole file
apiVersion: apps/v1
kind: Deployment
metadata:
  name: shop
  namespace: shop
spec:
  replicas: 3
  selector:
    matchLabels:
      app: shop
  template:
    metadata:
      labels:
        app: shop
    spec:
      containers:
        - name: web
          image: ghcr.io/kedai-kancil/shop:1.4.0

Commits

  1. f89a8e9 Add shopin the cluster

Cluster · namespace shop

Sync: SyncedHealth: Healthy

Deployment shop: 3/3 ready · image 1.4.0

Manual change (drift)
syncPolicy:
  automated:
    selfHeal: false
Show the Argo CD Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: shop
  namespace: argocd
spec:
  project: default
  source:
    repoURL: "https://github.com/kedai-kancil/gitops.git"
    path: apps/shop
    targetRevision: main
  destination:
    server: "https://kubernetes.default.svc"
    namespace: shop
  syncPolicy:
    automated:
      selfHeal: false
Nothing to do. Git and the cluster match.

Try it

This cluster has no GitOps helper. Be the helper. Find the drift, then put the file’s version back.

You are here: cluster kind-dev namespace default

Want 1. See 1. All good.

Want1written on the order for shop
See11 ready
Do All goodGaps fixed: 0
Stalls: 3. Trays: 1 (1 ready). Waiting for a stall: 0.
dev-control-planeOpenManager

No trays here.

dev-workerOpen
  • shop·grxfr
dev-worker2Open

No trays here.

Time: +0s (sped up)

Check

Swipe: good habit or not?

Swipe right for good, left for needs work. Or use the buttons.

1 / 3

Fix production by hand at 2 a.m., and never commit it.

Fix production by hand at 2 a.m., and never commit it.

You did it!

You can now spot drift and get Git’s version back.

Go deeper (optional)

Self-heal waits 5 seconds by default before it syncs again. Some drift is on purpose: an autoscaler changes replicas. Tell Argo CD to ignore that field with ignoreDifferences. Real rep (optional): on a kind cluster, kubectl scale a Deployment, then kubectl apply -f its file. See the count snap back.