Skip to main content
RunBook Academy

Git, CI/CD & GitOpsLXXXVII · GitOps During IncidentsFoundations

The incident versus GitOps tension — when the model fights the responder

Advanced⏱ ~22 mingit

What you'll learn

  • Recognise the structural conflict between incident response and the GitOps reconciliation loop
  • Identify the three incident shapes that make the model fight the responder
  • Apply the rule that the controller pauses during a declared incident rather than reverting the emergency edit
  • Distinguish pause-and-resume from disable-and-re-enable as the production discipline

Prerequisites

Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x

Not yet marked complete on this device.

The GitOps model assumes that every change to a running system is sourced in a Git commit and applied by a reconciliation loop. The loop is continuous, periodic, and context-blind: it does not know whether the operator who last touched the cluster is on-call, off-call, asleep, or in the middle of an incident. It reads the branch tip, computes the diff against the observed state, and applies the patch.

Incident response assumes the opposite: that the operator can act on the cluster with whatever urgency the situation demands, using whichever tool is closest, without waiting for a commit, a CI run, or a controller tick.

These two contracts collide. The collision is the GitOps-incidents topic of this part.

sequenceDiagram
    participant O as Operator
    participant K as Cluster
    participant G as Git
    participant R as Reconciler
    Note over O,R: Normal operation
    G->>R: new commit
    R->>K: apply diff
    Note over O,R: Incident begins
    O->>K: kubectl edit (emergency)
    K-->>R: observed state differs from Git
    R->>K: revert emergency edit (self-heal)
    O->>R: must pause reconciler

When the model fights the responder

The model fights the responder whenever the recovery action would otherwise be reverted by the next reconciliation tick. The tick is fast - typically ninety seconds in Argo CD, sixty seconds in Flux - so the responder has roughly one tick to apply the edit and document it before the controller reverts it. Three shapes produce the fight:

  • The one-line fix. A missing environment variable, a wrong image tag, a configmap key that needs a single value. The fix is kubectl edit in seconds; the commit-and-push cycle is minutes. The controller reverts the edit on the next tick if the responder does not pause it first.
  • The destructive deletion. A controller is in a loop and the only recovery is to delete the resource. The deletion is urgent; the commit-and-apply cycle would let the controller re-create the resource before the deletion takes effect.
  • The controller-induced incident. The reconciler itself is the cause of the divergence. The fix is to suspend the controller, not to commit around it - committing while the controller is still running produces a new desired state that the controller continues to mis-apply.

In each shape, the responder and the reconciler want different things. The responder wants the edit preserved. The reconciler wants the cluster to match Git. The reconciler wins on the next tick unless the responder pauses it.

The reconciliation loop is blind to the incident

The reconciler has no signal that an incident is in progress. It reads Git, renders the desired state, queries the cluster, computes the diff, applies the patch. The “incident is in progress” state is invisible to it. The production answer is to make the incident state visible - by suspending the affected Application, by writing a structured message to the incident channel, by recording the suspension timestamp. The controller’s blind spot is by design; the operator’s job is to fill it.

flowchart LR
    A["Declared incident"] --> B["Suspend affected Application"]
    B --> C["Apply emergency edit"]
    C --> D["Document in incident channel"]
    D --> E["Stop the bleeding"]
    E --> F["Commit change to Git"]
    F --> G["Resume reconciler"]
    G --> H["Validate convergence"]

The rule: pause rather than fight

The rule is short. During a declared incident that requires breaking the model, the responder pauses the reconciler on the affected Application, applies the edit, documents the break, and commits after the bleeding stops. The responder does not disable the reconciler globally, does not re-apply the edit every tick, and does not walk away without committing. The model is broken for the duration of the incident and repaired at the end of it.

Production discipline

  1. Suspend first, edit second. The order is non-negotiable. An edit applied while the controller is running will be reverted on the next tick.
  2. Document the break during the incident. Every emergency edit appears in the incident channel within five minutes of being applied.
  3. Commit before resuming. The reconciler is resumed only after the Git state matches the cluster state. A reconciler resumed before the commit produces a reversion loop.

Cross-course references

  • This course, Part LXXV-04 (Emergency drift) - the drift category produced when the GitOps model is broken to stop the bleeding.
  • This course, Part LXXXVI-05 (Unhealthy deployment) - the failure mode where the reconciler is Synced but the application is Degraded; the boundary that triggers the one-line-fix shape.
  • Kubernetes for Production Sysadmins - Parts on incident response cover the cluster-side mechanics of emergency interventions.

Quiz

Knowledge check · 4 questions

  1. Q1. An on-call engineer needs to change one environment variable on a Deployment to recover a service. Self-heal is on and the reconciliation interval is 90 seconds. What is the correct immediate sequence?

  2. Q2. The GitOps reconciler can distinguish between an operator's emergency edit during an incident and a manual mistake, and will preserve the former while reverting the latter.

  3. Q3. Name the three incident shapes that cause the GitOps model to fight the responder, and the production discipline that resolves each.

  4. Q4. Diagnose why the on-call engineer is fighting the reconciler, and identify the missing step that would have prevented the fight.

    At 03:14 a Deployment is in CrashLoopBackOff because a configmap key was renamed. The on-call engineer at 03:15 runs `kubectl set env` to fix the reference. At 03:16 the controller reverts the edit. The engineer re-applies the edit. At 03:17 the controller reverts it again. By 03:30 the engineer has re-applied the edit six times and the incident is still open. Self-heal is on; the Application is automated.

Passing score: 75%. Answers are checked in this browser.