Add admission_webhook_outage_hotel_reservation problem - #758
Conversation
|
This looks awesome! Great work! |
|
This is a one of the most thoughtful PR I've ever read. Thank you! This is incredibly interesting! We will review soon. @Saadmrp1038 |
|
Amazing PR @samiamjidkhan! |
Agreed! |
Saadmrp1038
left a comment
There was a problem hiding this comment.
@samiamjidkhan The PR looks great! Thanks for your effort.
I left some comments below. Please ping me when you have addressed them.
Feel free to ping us if you have any questions or confusions!
Thanks for the review @Saadmrp1038! Both points addressed in the latest commit: Names: Webhook + backend service renamed to MitigationOracle: Added |
|
The changes look good. I ran and tested the problem multiple times. Everything seems to be working correctly now. Congrats on the first PR merged here @samiamjidkhan 🎉 |
Add
admission_webhook_outage_hotel_reservationproblemAdds a new problem simulating an admission-webhook outage — a well-attested production failure class not currently covered by the SREGym catalogue. Includes a minimal
mcp-serverRBAC expansion (9 lines of YAML) needed for agents to mitigate this class of failure; rationale below. The PR can be landed as one piece or split (the problem alone is still a legitimate benchmark result under the default RBAC; see Stratus Run 1).1. The real-world failure story
When a
ValidatingWebhookConfigurationwithfailurePolicy: Failpoints at a backend whose endpoints are missing or unreachable, every admission request the webhook intercepts is rejected by the kube-apiserver. Because admission control sits in the request path for every matching CREATE, the cluster (or matchingnamespaceSelectorscope) loses the ability to create pods even though deployments, images, and nodes are all healthy. Recovery requires an operator with cluster-scoped permissions onadmissionregistration.k8s.io.Three public postmortems anchor this simulation, all listed on k8s.af (the failure-story aggregator referenced in the SREGym evaluation task spec):
ValidatingWebhookConfigurationon a GKE cluster interacted badly with GKE node auto-repair, causing prolonged downtime and a failed master upgrade. (Original blog redirects through Venafi → CyberArk post-acquisition; k8s.af is the canonical pointer.)kubectl delete ValidatingWebhookConfigurationplus the mutating counterpart — the same mitigation surface our problem expects.MutatingAdmissionWebhookfailure mode among other things.Recurring upstream issues confirm the class is ongoing: kubernetes/kubernetes#80313 (dead-TCP-affected webhooks) and cert-manager/cert-manager#5870 (cert-manager webhook gateway timeouts).
2. How the failure is simulated on SREGym
New problem class at
sregym/conductor/problems/admission_webhook_outage.py.inject_faultinstalls a cluster-scopedValidatingWebhookConfigurationwithfailurePolicy: Failand anamespaceSelectorscoped tohotel-reservation, whoseclientConfig.servicepoints at a service indefault/that does not exist. It then deletes one pod from therecommendationdeployment so the ReplicaSet's recreate attempt hits the broken webhook and is rejected.caBundleis intentionally omitted so the apiserver uses its system trust roots and the failure surfaces at the backend-lookup step (service not found), matching the documented narrative rather than a cert-parsing error.The problem is registered as
"admission_webhook_outage_hotel_reservation"in theDIRECT K8S APIsection ofregistry.py. The class is parameterised overapp_name(hotel_reservation / social_network / astronomy_shop) so sibling variants are a one-line follow-up.recover_faultis idempotent: if the agent already removed the webhook during mitigation, recovery logsalready absentand exits cleanly. The conductor's existing baseline reconcile (validating_webhook_configs_deleted) verifies no leftovers either way. The genericMitigationOracleaccepts all three valid mitigation paths — delete the webhook, patchfailurePolicytoIgnore, or restore the backend service — since each results in pod health.3. Problem runtime behaviour
Verified across 5 end-to-end runs on a 4-node ARM kind cluster (1 control-plane + 3 workers, 16 GiB Docker).
inject_faultruntimerecommendationReplicaSet atdesired=1, current=0, ready=0; the other 18 hotel-reservation pods stay healthyWarning FailedCreate ... failed calling webhook "sregym-admission-webhook-outage.sregym.io": failed to call webhook: Post "https://sregym-faulty-webhook-svc.default.svc:443/validate?timeout=5s": service "sregym-faulty-webhook-svc" not foundnamespaceSelectorconfines the fault to hotel-reservationrecover_faultdeletes the webhook; conductor reconcile reportsvalidating_webhook_configs_deleted: []A clean human-driven run (me, via the CLI) scored 100/100 on diagnosis (
D1=D2=D3=1.0, all 9 judge checklist questions Yes), mitigation passed, TTL=181.7 s, TTM=228.9 s. Back-to-backstartcycles work without manual intervention; the baseline reconcile handles even mid-mitigation abnormal exits.4. Agent behaviour (Stratus, GPT-5)
Ran Stratus twice — both runs are informative.
validatingwebhookconfigurations; tried 14 increasingly creative workarounds (delete the Deployment; recreate with a new label to evade an imagined objectSelector; relabel an existing pod andkubectl execthe recommendation binary inside it; attempt RBAC self-escalation viaclusterrolebinding) — all denied.kubectl patch ... failurePolicy=Ignore→kubectl scale deploy/recommendation 0→1→kubectl delete validatingwebhookconfiguration ...→ verified 19/19 pods Running → submitted. Cluster genuinely healthy. But then TIMEOUT (900 s) because Stratus's internalClusterStateOraclecould not reach127.0.0.1:16443(Connection refused), the driver triggered a deterministic rollback that tried to re-create the deleted webhook (blocked by this PR's RBAC scope, which excludescreate), and the agent retried until timeout.The D2 nit in both runs is the judge preferring "present with no endpoints" over "not found" — both are technically true of this fault.
Run 1 is itself a research finding. It demonstrates that admission-webhook outages of this form cannot be self-mitigated by an agent restricted to namespace-scoped workload RBAC, mirroring the real-world property that on-call engineers typically need a break-glass admin kubeconfig to recover from these incidents.
Run 2 is a separate finding worth flagging to the Stratus team: when
ClusterStateOraclecannot reach127.0.0.1:16443after a successful submit, the retry/rollback heuristic produces an outcome strictly worse than accepting the submission — it actively tries to undo correct mitigations. In our case the RBAC scope happened to prevent the rollback from succeeding, which was fortunate.RBAC change rationale
mcp_server/k8s/clusterrole.yamladds one rule:get/list/watchlets the agent discover that a webhook is the root cause;delete/patch/updatelets it execute any of the three valid mitigations.createis deliberately excluded — the framework controls webhook installation viainject_fault, and an agent re-creating a faulty webhook to "undo" a correct mitigation is exactly the pathological behaviour Run 2 illustrated. This mirrors the least-privilege scope an on-call SRE would expect on a temporary elevated kubeconfig.If the maintainers prefer to land the RBAC change separately, the problem file can ship as-is — Run 1's TIMEOUT is itself a legitimate benchmark floor.
Notes for reviewers
kubernetesclient.NetworkPolicyBlockstyle (dict-shaped resource bodies) to avoid version-skew on typed-class names across kubernetes-client releases.social_network/astronomy_shopare a one-line follow-up; happy to add in a separate PR if useful.