# Desired state and reconciliation

> Declare what should exist; a controller keeps comparing it with what does and closes the gap.

Concept · Running systems · https://levelcode.org/concepts/reconciliation-loops

Imperative operations say *what to do*: "start 3 more containers." Declarative systems say *what should be true*: "there should be 5 replicas of this image." A **controller** then runs a **reconciliation loop** that keeps comparing the two and acting to close the gap:

```text
loop:
    desired  = read spec        (what you declared)
    actual   = observe world    (what exists right now)
    if actual != desired:
        take one step towards desired
```

Kubernetes is built entirely from these loops. You `apply` a Deployment saying `replicas: 5`. The Deployment controller makes sure a ReplicaSet exists. The ReplicaSet controller notices only 3 Pods and creates 2. The scheduler assigns them to nodes, and each node's kubelet starts their containers. Every component reconciles its own small piece.

## Why it's robust

- **Self-healing for free.** Delete a Pod, or lose a node, and the loop sees 4 instead of 5 and creates another. Nothing special handles the failure; it's just another difference to close.
- **Idempotent by design.** Applying the same spec twice changes nothing. Re-running after a crash is always safe.
- **Level-triggered, not edge-triggered.** Controllers act on *current state*, not on a stream of events they might have missed. A controller that was down for ten minutes simply reconciles whatever it finds when it comes back.
- **Status records progress.** Objects carry `spec` (desired) and `status` (observed), so you can always see how far from done the system is.

## The same idea elsewhere

- **Terraform and other IaC:** `plan` compares the code with the real infrastructure, and `apply` closes the gap. Changes made by hand in the console show up as **drift**.
- **GitOps (Argo CD, Flux):** the desired state is a Git repository, and a controller continuously syncs the cluster to it. Rollback is `git revert`.
- **Autoscalers:** the HPA's desired replica count is computed from metrics, then reconciled like any other.

## Caveats

- **Convergence takes time.** "Applied" doesn't mean "running." Wait on status conditions or rollout status in your pipelines.
- **Two controllers fighting over one field** (for example, the HPA and a hard-coded `replicas` in your GitOps manifests) will flip it back and forth forever. Give each field one owner.
- **Manual fixes get reverted.** Change the source of truth instead.

[Readiness checks](https://levelcode.org/concepts/liveness-readiness) are part of the "observe" step: they tell the controllers which Pods actually count.
