2026-08-29
Server-side apply's conflict resolution assumes a static world: manager A owns a field, manager B tries to write it, someone wins. But real systems are dynamic — sometimes ownership should move. A human operator patches a Deployment's replica count during an incident; later, the HPA needs to take back control. Neither "force always" nor "reject always" is correct. You need explicit handoff.
The pattern has three moves:
managedFields entry.autoscaling.alpha/managed-by: hpa — that tells each controller whether it's allowed to touch the field right now.Concrete example. A team runs a Deployment with HPA managing spec.replicas. During a Black Friday incident, an SRE runs kubectl scale deployment web --replicas=50. This kicks the SRE (kubectl) into the field's manager list alongside the HPA. Now the HPA's next reconcile fires a conflict error and stops adjusting. Replicas stay pinned at 50 for hours after the incident ends.
The fix: an admission webhook watches for manual scale commands, sets an annotation incident-scaling: active, and after 30 minutes automatically issues a server-side apply that omits spec.replicas under the SRE's manager name. That drops the SRE's ownership. The HPA's next reconcile sees a clean field, claims it, and resumes autoscaling.
Rule of thumb — the 3-manager ceiling. If any single field ends up with more than 3 managers in its managedFields history, you have a handoff bug, not a coexistence pattern. Real coexistence tops out at 2 managers with a fence annotation; anything beyond that means controllers are silently trampling ownership and you're one conflict away from a stuck resource. Audit with kubectl get deploy web -o json | jq '.metadata.managedFields | length'.
What breaks without handoff:
managedFields grows unbounded as tools rotate through the resource.Design the handoff protocol before you have three tools writing the same field. Retrofitting it after the fact means walking every stuck resource in production.
