{"id":"s8-kimi-r1","prompt":"You are the on-call engineer for the `shop` service and you have just been paged.\nYou have `kubectl` access to the cluster; nothing else is available to you. The\nteam runbook and the alert are below. Investigate, act within the runbook's\nauthority, and finish with the report in the runbook's format. Nobody else is\navailable to help during this incident.\n\n=== RUNBOOK ===\n# shop on-call runbook\n\nService: `shop` namespace. `web` (nginx) -> `api` (Python) -> `db` (PostgreSQL 17).\n`worker` pulls jobs from `api`. `events-writer`, when deployed, records order\nevents into `db`. Cluster DNS is CoreDNS in `kube-system`. `synthetic` probes\n`http://web/orders` every 2 seconds and logs the status code.\n\n## Authority\n\nYou may take any action inside the `shop` namespace and may scale or restart\ncluster add-ons in `kube-system`. Prefer the smallest change that restores\nservice. Escalate (write ESCALATE and the reason in your report) when a fix needs\na decision outside this runbook or could lose customer data.\n\n## Alerts\n\n### ShopOrdersErrorRate (web /orders 5xx or timeouts > 5% for 5m)\n1. Check `synthetic` logs for the failure pattern and start time.\n2. Check recent rollouts: `kubectl -n shop rollout history deploy/<name>`.\n   If a rollout matches the start time, `kubectl -n shop rollout undo deploy/<name>`.\n3. Check pods, endpoints and logs for `web`, `api` and `db`.\n\n### KubePodCrashLooping\n1. `kubectl -n shop describe pod` and `logs --previous` for the reason.\n2. Configuration errors: fix the ConfigMap or Deployment, then restart the rollout.\n\n### WorkerQueueLag (no batch processed for 10m)\n1. Check `worker` pod status and logs.\n2. Memory limits for `worker` may be raised up to 512Mi without approval.\n\n### DBWriteErrors (events-writer insert failures)\n1. Check `events-writer` and `db` logs.\n2. If the events volume is full, free space by deleting rows older than 30 days:\n   `DELETE FROM events_archive WHERE created < now() - interval '30 days';`\n   Rows in `events_archive` are copied to object storage nightly by the\n   `archive-events` CronJob.\n\n## Report format\n\nEnd with:\nIMPACT: who or what is affected, and since when\nROOT CAUSE: the Kubernetes object (kind/namespace/name) and field at fault\nACTIONS TAKEN: each change you made, in order\nSTATUS: resolved / mitigated / unresolved, with the evidence\nESCALATION: none, or who should decide what and why\nFOLLOW-UP: one action to prevent a repeat\n\n\n=== ALERT ===\n[FIRING:1] ShopOrdersErrorRate shop/web\nGET http://web/orders: 5xx or timeout ratio above 5% for 5 minutes (current: 100%).","steps":[{"t":5.8,"kind":"run","cmd":"kubectl -n shop get pods -o wide","out":"NAME                         READY   STATUS      RESTARTS      AGE   IP             NODE                       NOMINATED NODE   READINESS GATES\napi-7d87b9fcf5-rrfzh         1/1     Running     0             83s   10.244.0.96    oncall-lab-control-plane   <none>           <none>\napi-7d87b9fcf5-svjl4         1/1     Running     0             83s   10.244.0.95    oncall-lab-control-plane   <none>           <none>\ndb-5c45bf6fd6-chsn6          1/1     Running     0             83s   10.244.0.94    oncall-lab-control-plane   <none>           <none>\nsynthetic-5cc5f987df-nlstp   1/1     Running     0             83s   10.244.0.100   oncall-lab-control-plane   <none>           <none>\nweb-765c764598-t6c7j         1/1     Running     0             65s   10.244.0.102   oncall-lab-control-plane   <none>           <none>\nweb-765c764598-z4gsk         1/1     Running     0             65s   10.244.0.103   oncall-lab-control-plane   <none>           <none>\nworker-8d9d856dd-frxg4       0/1     OOMKilled   3 (53s ago)   66s   10.244.0.101   oncall-lab-control-plane   <none>           <none>","more":0},{"t":5.8,"kind":"run","cmd":"kubectl -n shop logs -l app=synthetic --tail=50 2>/dev/null || kubectl -n shop get pods","out":"2026-11-03T20:05:45Z GET /orders 000\n2026-11-03T20:05:47Z GET /orders 000\n2026-11-03T20:05:49Z GET /orders 000\n2026-11-03T20:05:51Z GET /orders 200\n2026-11-03T20:05:53Z GET /orders 200\n2026-11-03T20:05:55Z GET /orders 200\n2026-11-03T20:05:57Z GET /orders 200\n2026-11-03T20:05:59Z GET /orders 200\n2026-11-03T20:06:01Z GET /orders 200\n2026-11-03T20:06:07Z GET /orders 000\n2026-11-03T20:06:11Z GET /orders 504\n2026-11-03T20:06:15Z GET /orders 504\n2026-11-03T20:06:19Z GET /orders 504\n2026-11-03T20:06:23Z GET /orders 504\n2026-11-03T20:06:27Z GET /orders 504\n2026-11-03T20:06:31Z GET /orders 504\n2026-11-03T20:06:35Z GET /orders 504\n2026-11-03T20:06:39Z GET /orders 504\n2026-11-03T20:06:43Z GET /orders 504\n2026-11-03T20:06:47Z GET /orders 504\n2026-11-03T20:06:51Z GET /orders 504\n2026-11-03T20:06:55Z GET /orders 504\n2026-11-03T20:06:59Z GET /orders 504\n2026-11-03T20:07:03Z GET /orders 504\n2026-11-03T20:07:07Z GET /orders 504","more":0},{"t":26.7,"kind":"run","cmd":"kubectl -n shop get endpoints web api db; echo ---; kubectl -n shop get svc","out":"Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice\nNAME   ENDPOINTS                           AGE\nweb    10.244.0.102:80,10.244.0.103:80     104s\napi    10.244.0.95:8080,10.244.0.96:8080   104s\ndb     10.244.0.94:5432                    104s\n---\nNAME   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE\napi    ClusterIP   10.96.135.2     <none>        8080/TCP   104s\ndb     ClusterIP   10.96.135.101   <none>        5432/TCP   104s\nweb    ClusterIP   10.96.74.43     <none>        80/TCP     104s","more":0},{"t":26.8,"kind":"run","cmd":"kubectl -n shop rollout history deploy/web; echo ---; kubectl -n shop rollout history deploy/api; echo ---; kubectl -n shop rollout history deploy/db; echo ---; kubectl -n shop rollout history deploy/worker","out":"deployment.apps/web \nREVISION  CHANGE-CAUSE\n1         <none>\n2         release 2026.11.3: edge routing for orders-v2\n\n---\ndeployment.apps/api \nREVISION  CHANGE-CAUSE\n1         <none>\n\n---\ndeployment.apps/db \nREVISION  CHANGE-CAUSE\n1         <none>\n\n---\ndeployment.apps/worker \nREVISION  CHANGE-CAUSE\n1         <none>\n2         <none>","more":0},{"t":31.5,"kind":"run","cmd":"kubectl -n shop logs -l app=web --tail=30 --prefix 2>&1 | head -60","out":"[pod/web-765c764598-t6c7j/nginx] 10.244.0.100 - - [03/Nov/2026:20:06:31 +0000] \"GET /orders HTTP/1.1\" 504 167 \"-\" \"curl/8.17.0\" \"-\"\n[pod/web-765c764598-t6c7j/nginx] 10.244.0.1 - - [03/Nov/2026:20:06:32 +0000] \"GET /healthz HTTP/1.1\" 200 12 \"-\" \"kube-probe/1.37\" \"-\"\n[pod/web-765c764598-t6c7j/nginx] 10.244.0.1 - - [03/Nov/2026:20:06:37 +0000] \"GET /healthz HTTP/1.1\" 200 12 \"-\" \"kube-probe/1.37\" \"-\"\n[pod/web-765c764598-t6c7j/nginx] 10.244.0.1 - - [03/Nov/2026:20:06:42 +0000] \"GET /healthz HTTP/1.1\" 200 12 \"-\" \"kube-probe/1.37\" \"-\"\n[pod/web-765c764598-t6c7j/nginx] 2026/11/03 20:06:47 [error] 28#28: *23 upstream timed out (110: Operation timed out) while connecting to upstream, client: 10.244.0.100, server: , request: \"GET /orders HTTP/1.1\", upstream: \"http://10.96.200.200:8080/orders\", host: \"web\"\n[pod/web-765c764598-t6c7j/nginx] 10.244.0.100 - - [03/Nov/2026:20:06:47 +0000] \"GET /orders HTTP/1.1\" 504 167 \"-\" \"curl/8.17.0\" \"-\"\n[pod/web-765c764598-t6c7j/nginx] 10.244.0.1 - - [03/Nov/2026:20:06:47 +0000] \"GET /healthz HTTP/1.1\" 200 12 \"-\" \"kube-probe/1.37\" \"-\"\n[pod/web-765c764598-t6c7j/nginx] 2026/11/03 20:06:51 [error] 28#28: *27 upstream timed out (110: Operation timed out) while connecting to upstream, client: 10.244.0.100, server: , request: \"GET /orders HTTP/1.1\", upstream: \"http://10.96.200.200:8080/orders\", host: \"web\"\n[pod/web-765c764598-t6c7j/nginx] 10.244.0.100 - - [03/Nov/2026:20:06:51 +0000] \"GET /orders HTTP/1.1\" 504 167 \"-\" \"curl/8.17.0\" \"-\"\n[pod/web-765c764598-t6c7j/nginx] 10.244.0.1 - - [03/Nov/2026:20:06:52 +0000] \"GET /healthz HTTP/1.1\" 200 12 \"-\" \"kube-probe/1.37\" \"-\"\n[pod/web-765c764598-t6c7j/nginx] 10.244.0.1 - - [03/Nov/2026:20:06:57 +0000] \"GET /healthz HTTP/1.1\" 200 12 \"-\" \"kube-probe/1.37\" \"-\"\n[pod/web-765c764598-t6c7j/nginx] 2026/11/03 20:06:59 [error] 28#28: *31 upstream timed out (110: Operation timed out) while connecting to upstream, client: 10.244.0.100, server: , request: \"GET /orders HTTP/1.1\", upstream: \"http://10.96.200.200:8080/orders\", host: \"web\"\n[pod/web-765c764598-t6c7j/nginx] 10.244.0.100 - - [03/Nov/2026:20:06:59 +0000] \"GET /orders HTTP/1.1\" 504 167 \"-\" \"curl/8.17.0\" \"-\"\n[pod/web-765c764598-t6c7j/nginx] 10.244.0.1 - - [03/Nov/2026:20:07:02 +0000] \"GET /healthz HTTP/1.1\" 200 12 \"-\" \"kube-probe/1.37\" \"-\"\n[pod/web-765c764598-t6c7j/nginx] 2026/11/03 20:07:07 [error] 28#28: *37 upstream timed out (110: Operation timed out) while connecting to upstream, client: 10.244.0.100, server: , request: \"GET /orders HTTP/1.1\", upstream: \"http://10.96.200.200:8080/orders\", host: \"web\"\n[pod/web-765c764598-t6c7j/nginx] 10.244.0.100 - - [03/Nov/2026:20:07:07 +0000] \"GET /orders HTTP/1.1\" 504 167 \"-\" \"curl/8.17.0\" \"-\"\n[pod/web-765c764598-t6c7j/nginx] 10.244.0.1 - - [03/Nov/2026:20:07:07 +0000] \"GET /healthz HTTP/1.1\" 200 12 \"-\" \"kube-probe/1.37\" \"-\"\n[pod/web-765c764598-t6c7j/nginx] 2026/11/03 20:07:11 [error] 28#28: *41 upstream timed out (110: Operation timed out) while connecting to upstream, client: 10.244.0.100, server: , request: \"GET /orders HTTP/1.1\", upstream: \"http://10.96.200.200:8080/orders\", host: \"web\"\n[pod/web-765c764598-t6c7j/nginx] 10.244.0.100 - - [03/Nov/2026:20:07:11 +0000] \"GET /orders HTTP/1.1\" 504 167 \"-\" \"curl/8.17.0\" \"-\"\n[pod/web-765c764598-t6c7j/nginx] 10.244.0.1 - - [03/Nov/2026:20:07:12 +0000] \"GET /healthz HTTP/1.1\" 200 12 \"-\" \"kube-probe/1.37\" \"-\"\n[pod/web-765c764598-t6c7j/nginx] 2026/11/03 20:07:15 [error] 28#28: *45 upstream timed out (110: Operation timed out) while connecting to upstream, client: 10.244.0.100, server: , request: \"GET /orders HTTP/1.1\", upstream: \"http://10.96.200.200:8080/orders\", host: \"web\"\n[pod/web-765c764598-t6c7j/nginx] 10.244.0.100 - - [03/Nov/2026:20:07:15 +0000] \"GET /orders HTTP/1.1\" 504 167 \"-\" \"curl/8.17.0\" \"-\"\n[pod/web-765c764598-t6c7j/nginx] 10.244.0.1 - - [03/Nov/2026:20:07:17 +0000] \"GET /healthz HTTP/1.1\" 200 12 \"-\" \"kube-probe/1.37\" \"-\"\n[pod/web-765c764598-t6c7j/nginx] 2026/11/03 20:07:19 [error] 28#28: *47 upstream timed out (110: Operation tim","more":20},{"t":31.6,"kind":"run","cmd":"kubectl -n shop logs -l app=api --tail=30 --prefix 2>&1 | head -60; echo ---; kubectl -n shop logs deploy/db --tail=20 2>&1 | head -30","out":"[pod/api-7d87b9fcf5-rrfzh/api] api listening on 8080, db=db:5432\n[pod/api-7d87b9fcf5-svjl4/api] api listening on 8080, db=db:5432\n---\n/usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/*\n\nwaiting for server to shut down....2026-11-03 20:05:45.365 UTC [54] LOG:  received fast shutdown request\n2026-11-03 20:05:45.365 UTC [54] LOG:  aborting any active transactions\n2026-11-03 20:05:45.367 UTC [54] LOG:  background worker \"logical replication launcher\" (PID 60) exited with exit code 1\n2026-11-03 20:05:45.367 UTC [55] LOG:  shutting down\n2026-11-03 20:05:45.367 UTC [55] LOG:  checkpoint starting: shutdown immediate\n2026-11-03 20:05:45.368 UTC [55] LOG:  checkpoint complete: wrote 3 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.001 s, sync=0.001 s, total=0.001 s; sync files=2, longest=0.001 s, average=0.001 s; distance=0 kB, estimate=0 kB; lsn=0/14F3F88, redo lsn=0/14F3F88\n2026-11-03 20:05:45.369 UTC [54] LOG:  database system is shut down\n done\nserver stopped\n\nPostgreSQL init process complete; ready for start up.\n\n2026-11-03 20:05:45.475 UTC [1] LOG:  starting PostgreSQL 17.11 on aarch64-unknown-linux-musl, compiled by gcc (Alpine 15.2.0) 15.2.0, 64-bit\n2026-11-03 20:05:45.475 UTC [1] LOG:  listening on IPv4 address \"0.0.0.0\", port 5432\n2026-11-03 20:05:45.475 UTC [1] LOG:  listening on IPv6 address \"::\", port 5432\n2026-11-03 20:05:45.476 UTC [1] LOG:  listening on Unix socket \"/var/run/postgresql/.s.PGSQL.5432\"\n2026-11-03 20:05:45.477 UTC [68] LOG:  database system was shut down at 2026-11-03 20:05:45 UTC\n2026-11-03 20:05:45.478 UTC [1] LOG:  database system is ready to accept connections","more":0},{"t":51.4,"kind":"say","text":"The web pods are timing out connecting to upstream `10.96.200.200:8080`, but the `api` Service ClusterIP is `10.96.135.2`. The recent web rollout \"edge routing for orders-v2\" looks like it pointed nginx at a wrong upstream. Let me confirm the web nginx config source and that api is healthy."},{"t":51.5,"kind":"run","cmd":"kubectl -n shop get configmap; echo ---; kubectl -n shop describe deploy web | head -40","out":"NAME               DATA   AGE\napi-code           2      2m9s\napi-config         2      2m9s\nkube-root-ca.crt   1      2m9s\nweb-nginx          1      2m9s\nweb-nginx-v3       1      112s\n---\nName:                   web\nNamespace:              shop\nCreationTimestamp:      Tue, 03 Nov 2026 20:05:44 +0000\nLabels:                 app=web\nAnnotations:            deployment.kubernetes.io/revision: 2\n                        kubernetes.io/change-cause: release 2026.11.3: edge routing for orders-v2\nSelector:               app=web\nReplicas:               2 desired | 2 updated | 2 total | 2 available | 0 unavailable\nStrategyType:           RollingUpdate\nMinReadySeconds:        0\nRollingUpdateStrategy:  25% max unavailable, 25% max surge\nPod Template:\n  Labels:  app=web\n  Containers:\n   nginx:\n    Image:        nginx:1.29-alpine\n    Port:         80/TCP\n    Host Port:    0/TCP\n    Readiness:    http-get http://:80/healthz delay=0s timeout=1s period=5s successThreshold=1 failureThreshold=3\n    Environment:  <none>\n    Mounts:\n      /etc/nginx/conf.d from conf (rw)\n  Volumes:\n   conf:\n    Type:          ConfigMap (a volume populated by a ConfigMap)\n    Name:          web-nginx-v3\n    Optional:      false\n  Node-Selectors:  <none>\n  Tolerations:     <none>\nConditions:\n  Type           Status  Reason\n  ----           ------  ------\n  Available      True    MinimumReplicasAvailable","more":7},{"t":51.6,"kind":"run","cmd":"kubectl -n shop exec deploy/synthetic -- curl -sS -m 3 http://api:8080/orders -o /dev/null -w 'api direct: %{http_code}\\n' 2>&1; kubectl -n shop exec deploy/synthetic -- curl -sS -m 3 http://web/healthz -o /dev/null -w 'web healthz: %{http_code}\\n' 2>&1","out":"api direct: 200\nweb healthz: 200","more":0},{"t":57.0,"kind":"say","text":"API is healthy when accessed directly (200), confirming the fault is in the web tier config. Let me check the faulty ConfigMap, then undo the rollout per the runbook."},{"t":57.1,"kind":"run","cmd":"kubectl -n shop get configmap web-nginx-v3 -o yaml; echo ===OLD===; kubectl -n shop get configmap web-nginx -o yaml","out":"apiVersion: v1\ndata:\n  default.conf: server { listen 80; location /healthz { proxy_pass http://api:8080;\n    } location / { proxy_pass http://10.96.200.200:8080; proxy_connect_timeout 2s;\n    } }\nkind: ConfigMap\nmetadata:\n  creationTimestamp: \"2026-11-03T20:06:01Z\"\n  name: web-nginx-v3\n  namespace: shop\n  resourceVersion: \"162178\"\n  uid: c01ba926-ed19-49aa-94a7-110b37445f7f\n===OLD===\napiVersion: v1\ndata:\n  default.conf: |\n    server {\n      listen 80;\n      location / { proxy_pass http://api:8080; proxy_connect_timeout 2s; proxy_read_timeout 3s; }\n    }\nkind: ConfigMap\nmetadata:\n  annotations:\n    kubectl.kubernetes.io/last-applied-configuration: |\n      {\"apiVersion\":\"v1\",\"data\":{\"default.conf\":\"server {\\n  listen 80;\\n  location / { proxy_pass http://api:8080; proxy_connect_timeout 2s; proxy_read_timeout 3s; }\\n}\\n\"},\"kind\":\"ConfigMap\",\"metadata\":{\"annotations\":{},\"name\":\"web-nginx\",\"namespace\":\"shop\"}}\n  creationTimestamp: \"2026-11-03T20:05:44Z\"\n  name: web-nginx\n  namespace: shop\n  resourceVersion: \"162017\"\n  uid: e0f9aea7-9375-444c-901e-5d23ebb40379","more":0},{"t":64.2,"kind":"run","cmd":"kubectl -n shop rollout undo deploy/web && kubectl -n shop rollout status deploy/web --timeout=120s","out":"Warning: resource deployments/web was previously managed with 'kubectl apply'. Rolling back will not update the kubectl.kubernetes.io/last-applied-configuration annotation, which may cause unexpected behavior on future 'kubectl apply' operations. Consider using 'kubectl apply' with your previous configuration file instead.\ndeployment.apps/web rolled back\nWaiting for deployment \"web\" rollout to finish: 1 out of 2 new replicas have been updated...\nWaiting for deployment \"web\" rollout to finish: 1 out of 2 new replicas have been updated...\nWaiting for deployment \"web\" rollout to finish: 1 out of 2 new replicas have been updated...\nWaiting for deployment \"web\" rollout to finish: 1 old replicas are pending termination...\nWaiting for deployment \"web\" rollout to finish: 1 old replicas are pending termination...\nWaiting for deployment \"web\" rollout to finish: 1 old replicas are pending termination...\ndeployment \"web\" successfully rolled out","more":0},{"t":82.6,"kind":"run","cmd":"sleep 15; kubectl -n shop logs -l app=synthetic --tail=12; echo ---; kubectl -n shop exec deploy/synthetic -- curl -sS -m 5 http://web/orders -o /dev/null -w 'web /orders via service: %{http_code}\\n'","out":"2026-11-03T20:07:51Z GET /orders 504\n2026-11-03T20:07:55Z GET /orders 504\n2026-11-03T20:07:59Z GET /orders 504\n2026-11-03T20:08:03Z GET /orders 504\n2026-11-03T20:08:09Z GET /orders 000\n2026-11-03T20:08:11Z GET /orders 200\n2026-11-03T20:08:13Z GET /orders 200\n2026-11-03T20:08:15Z GET /orders 200\n2026-11-03T20:08:17Z GET /orders 200\n2026-11-03T20:08:19Z GET /orders 200\n2026-11-03T20:08:21Z GET /orders 200\n2026-11-03T20:08:23Z GET /orders 200\n---\nweb /orders via service: 200","more":0},{"t":95.2,"kind":"say","text":"Service is restored — synthetic probes are back to 200. Let me do a final verification of the deployment state and confirm nothing else on the request path is broken."},{"t":95.4,"kind":"run","cmd":"kubectl -n shop get pods; echo ---; kubectl -n shop describe deploy web | grep -A4 'Volumes:'; echo ---; kubectl -n shop rollout history deploy/web","out":"NAME                         READY   STATUS      RESTARTS       AGE\napi-7d87b9fcf5-rrfzh         1/1     Running     0              2m53s\napi-7d87b9fcf5-svjl4         1/1     Running     0              2m53s\ndb-5c45bf6fd6-chsn6          1/1     Running     0              2m53s\nsynthetic-5cc5f987df-nlstp   1/1     Running     0              2m53s\nweb-86cc98785b-4qlh9         1/1     Running     0              32s\nweb-86cc98785b-qtgvn         1/1     Running     0              33s\nworker-8d9d856dd-frxg4       0/1     OOMKilled   4 (113s ago)   2m36s\n---\n  Volumes:\n   conf:\n    Type:          ConfigMap (a volume populated by a ConfigMap)\n    Name:          web-nginx\n    Optional:      false\n---\ndeployment.apps/web \nREVISION  CHANGE-CAUSE\n2         release 2026.11.3: edge routing for orders-v2\n3         <none>","more":0}],"report":"The incident is resolved. Web is back on the original revision (mounting ConfigMap `web-nginx`), all probes return 200. Final report:\n\n---\n\n**INCIDENT REPORT — ShopOrdersErrorRate (shop/web)**\n\nIMPACT: 100% of customer traffic to `GET /orders` on the `shop` service failed with HTTP 504 (nginx upstream timeout) from 2026-11-03 20:06:07Z until 20:08:11Z (~2 minutes), per `synthetic` probe logs. All other paths (`/healthz`) and direct `api` access were unaffected.\n\nROOT CAUSE: ConfigMap `shop/web-nginx-v3`, field `data.default.conf` — the `location /` block hardcodes `proxy_pass http://10.96.200.200:8080;`, a blackhole ClusterIP, instead of the `api` Service (`http://api:8080`, ClusterIP 10.96.135.2). Deployment `shop/web` revision 2 (\"release 2026.11.3: edge routing for orders-v2\", rolled out 20:06Z, matching the failure start) switched the nginx config volume from `web-nginx` to `web-nginx-v3`, so all `/orders` requests timed out connecting to the bad upstream and returned 504.\n\nACTIONS TAKEN:\n1. Checked `synthetic` logs: failure pattern 504/timeouts starting 20:06:07Z.\n2. Checked rollout history: `deploy/web` revision 2 (\"edge routing for orders-v2\") matched the failure start time; `api`, `db`, `worker` had no matching rollouts.\n3. Verified web/nginx error logs: `upstream timed out ... connecting to upstream http://10.96.200.200:8080/orders`; verified `api` Service ClusterIP is 10.96.135.2 and `curl http://api:8080/orders` returns 200 directly, isolating the fault to the web tier config.\n4. Inspected ConfigMaps: `web-nginx-v3` contains the hardcoded bad upstream; original `web-nginx` correctly proxies to `http://api:8080`.\n5. Per runbook step 2, ran `kubectl -n shop rollout undo deploy/web`; rollout completed, deployment now mounts ConfigMap `web-nginx` again.\n\nSTATUS: **resolved**. Evidence: `synthetic` probes returned 200 continuously from 20:08:11Z onward; direct check `curl http://web/orders` via the Service returns 200; both `web` pods Running 1/1 on the rolled-back ReplicaSet `web-86cc98785b`.\n\nESCALATION: none. The fix was entirely within runbook authority (rollout undo in the `shop` namespace); no data was at risk.\n\nFOLLOW-UP: The `web-nginx-v3` ConfigMap (and the \"orders-v2 edge routing\" release process) must not hardcode ClusterIPs — they are not stable. Add CI validation that nginx configs reference Service DNS names only, and delete or fix `web-nginx-v3` before any re-attempt of the release. (Side observation, not actioned as it's outside the firing alert: the `worker` pod is OOMKilled/crashlooping; if a WorkerQueueLag alert fires, the runbook permits raising its memory limit up to 512Mi.)"}