From d0666c5ba0b57553195a725a3b3da3655614afa0 Mon Sep 17 00:00:00 2001 From: DongHyeonka Date: Fri, 4 Sep 2026 12:25:30 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20A-4=20=E2=80=94=20a=20dead=20pod=20repo?= =?UTF-8?q?rts=20healthier=20than=20a=20live=20one?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Kubernetes keeps calling the node Ready for forty seconds while users already see failures, and the pod on the powered-off machine stays ready=true because its kubelet can no longer contradict itself. Eviction waits another five minutes, then the StatefulSet refuses to recreate its pod and the replacement Deployment pod cannot schedule because the local-path volume is pinned to the dead node. Killing the server node instead shows the opposite shape: containerd keeps the workload running while the API server, Traefik and the observability stack disappear, so the outage is the missing path rather than the missing application. Traefik at one replica is the ingress single point of failure. Co-Authored-By: Claude Opus 5 --- .../console-2026-09-04T02-56-16-987Z.log | 74 ++++ .../console-2026-09-04T03-23-15-961Z.log | 20 + .../page-2026-09-04T03-23-16-267Z.yml | 44 ++ .../page-2026-09-04T03-23-27-151Z.yml | 159 +++++++ docs/evidence/a4-node-loss/01-baseline.txt | 20 + .../a4-node-loss/02-worker-node-killed.txt | 17 + .../a4-node-loss/03-state-during-loss.txt | 28 ++ .../a4-node-loss/04-eviction-timing.txt | 15 + docs/evidence/a4-node-loss/05-recovery.txt | 18 + .../06-control-plane-inventory.txt | 19 + .../a4-node-loss/07-control-plane-loss.txt | 19 + .../08-control-plane-recovery.txt | 13 + docs/evidence/a4-node-loss/README.md | 23 + .../a4-node-loss/a4-up-dropped-per-node.png | Bin 0 -> 80937 bytes docs/experiment-a4-node-loss.md | 397 ++++++++++++++++++ 15 files changed, 866 insertions(+) create mode 100644 .playwright-mcp/console-2026-09-04T03-23-15-961Z.log create mode 100644 .playwright-mcp/page-2026-09-04T03-23-16-267Z.yml create mode 100644 .playwright-mcp/page-2026-09-04T03-23-27-151Z.yml create mode 100644 docs/evidence/a4-node-loss/01-baseline.txt create mode 100644 docs/evidence/a4-node-loss/02-worker-node-killed.txt create mode 100644 docs/evidence/a4-node-loss/03-state-during-loss.txt create mode 100644 docs/evidence/a4-node-loss/04-eviction-timing.txt create mode 100644 docs/evidence/a4-node-loss/05-recovery.txt create mode 100644 docs/evidence/a4-node-loss/06-control-plane-inventory.txt create mode 100644 docs/evidence/a4-node-loss/07-control-plane-loss.txt create mode 100644 docs/evidence/a4-node-loss/08-control-plane-recovery.txt create mode 100644 docs/evidence/a4-node-loss/README.md create mode 100644 docs/evidence/a4-node-loss/a4-up-dropped-per-node.png create mode 100644 docs/experiment-a4-node-loss.md diff --git a/.playwright-mcp/console-2026-09-04T02-56-16-987Z.log b/.playwright-mcp/console-2026-09-04T02-56-16-987Z.log index 499e5a5..fb86694 100644 --- a/.playwright-mcp/console-2026-09-04T02-56-16-987Z.log +++ b/.playwright-mcp/console-2026-09-04T02-56-16-987Z.log @@ -53,3 +53,77 @@ [ 502295ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 [ 511625ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 [ 524619ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 533050ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 553189ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 571699ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 575413ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 588005ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 599161ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 608816ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 619031ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 626612ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 639003ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 655077ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 674532ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 677197ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 696027ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 709512ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 727505ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 747139ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 754565ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 773682ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 784674ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 787399ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 802845ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 825589ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 832768ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 842043ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 852717ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 871748ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 876571ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 894491ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 895515ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 904310ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 916681ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 934752ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 941175ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 946004ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 960849ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 962180ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 984446ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 997579ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1010105ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1027190ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1043388ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1061311ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1066040ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1080349ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1092336ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1104312ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1109362ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1127047ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1134728ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1154899ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1161253ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1174971ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1184491ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1185340ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1189111ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1196984ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1204794ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1247961ms] [WARNING] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: WebSocket is closed before the connection is established. @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1286322ms] [WARNING] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: WebSocket is closed before the connection is established. @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1319329ms] [WARNING] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: WebSocket is closed before the connection is established. @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1362771ms] [WARNING] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: WebSocket is closed before the connection is established. @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1396881ms] [WARNING] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: WebSocket is closed before the connection is established. @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1434184ms] [ERROR] Failed to load resource: the server responded with a status of 502 () @ https://app2.hyeonworks.com/api/user/auth-tokens/rotate:0 +[ 1443506ms] [WARNING] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: WebSocket is closed before the connection is established. @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1465016ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 502 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1513337ms] [WARNING] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: WebSocket is closed before the connection is established. @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1556906ms] [WARNING] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: WebSocket is closed before the connection is established. @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1562963ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 502 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1572896ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 502 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1576390ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 503 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1593794ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: HTTP Authentication failed; no valid credentials available @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1600651ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: HTTP Authentication failed; no valid credentials available @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 1616424ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: HTTP Authentication failed; no valid credentials available @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 diff --git a/.playwright-mcp/console-2026-09-04T03-23-15-961Z.log b/.playwright-mcp/console-2026-09-04T03-23-15-961Z.log new file mode 100644 index 0000000..102ab83 --- /dev/null +++ b/.playwright-mcp/console-2026-09-04T03-23-15-961Z.log @@ -0,0 +1,20 @@ +[ 268ms] [WARNING] is deprecated. Please include @ https://app2.hyeonworks.com/login:0 +[ 379ms] [VERBOSE] [DOM] Input elements should have autocomplete attributes (suggested: "username"): (More info: https://goo.gl/9p2vKq) %o @ https://app2.hyeonworks.com/login:0 +[ 10453ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 10532ms] [WARNING] is deprecated. Please include @ https://app2.hyeonworks.com/explore?schemaVersion=1&panes=%7B%22ich%22%3A%7B%22datasource%22%3A%22PBFA97CFB590B2093%22%2C%22queries%22%3A%5B%7B%22refId%22%3A%22A%22%2C%22expr%22%3A%22up%7Bjob%3D%7E%5C%22keycloak%7Cnode-exporter%5C%22%7D%22%2C%22range%22%3Atrue%2C%22instant%22%3Afalse%2C%22editorMode%22%3A%22code%22%2C%22legendFormat%22%3A%22%7B%7Bjob%7D%7D+%E2%80%94+%7B%7Bpod%7D%7D%7B%7Bnode%7D%7D%22%2C%22datasource%22%3A%7B%22type%22%3A%22prometheus%22%2C%22uid%22%3A%22PBFA97CFB590B2093%22%7D%7D%5D%2C%22range%22%3A%7B%22from%22%3A%22now-55m%22%2C%22to%22%3A%22now%22%7D%7D%7D&orgId=1:0 +[ 11687ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 13737ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 15113ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 20185ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 27259ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 40154ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 41870ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 50493ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 54082ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 60121ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 74362ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 83269ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 95349ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 98008ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 104458ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 +[ 123816ms] [ERROR] WebSocket connection to 'wss://app2.hyeonworks.com/api/live/ws' failed: Error during WebSocket handshake: Unexpected response code: 400 @ https://app2.hyeonworks.com/public/build/1518.a3f1f690c084a37f01c7.js:362 diff --git a/.playwright-mcp/page-2026-09-04T03-23-16-267Z.yml b/.playwright-mcp/page-2026-09-04T03-23-16-267Z.yml new file mode 100644 index 0000000..9ec7240 --- /dev/null +++ b/.playwright-mcp/page-2026-09-04T03-23-16-267Z.yml @@ -0,0 +1,44 @@ +- main [ref=f6e7]: + - generic [ref=f6e9]: + - generic [ref=f6e11]: + - generic [ref=f6e12]: + - img "Grafana" [ref=f6e13] + - heading "Welcome to Grafana" [level=1] [ref=f6e15] + - generic [ref=f6e19]: + - generic [ref=f6e20]: + - generic [ref=f6e21]: Email or username + - textbox "Email or username" [active] [ref=f6e28]: + - /placeholder: email or username + - generic [ref=f6e29]: + - generic [ref=f6e30]: Password + - generic [ref=f6e36]: + - textbox "Password" [ref=f6e37]: + - /placeholder: password + - switch "Show password" [ref=f6e39] [cursor=pointer] + - button "Log in" [ref=f6e42] [cursor=pointer] + - link "Forgot your password?" [ref=f6e45] [cursor=pointer]: + - /url: /user/password/send-reset-email + - list [ref=f6e49]: + - listitem [ref=f6e50]: + - link "Documentation" [ref=f6e53] [cursor=pointer]: + - /url: https://grafana.com/docs/grafana/latest/?utm_source=grafana_footer + - text: "|" + - listitem [ref=f6e54]: + - link "Support" [ref=f6e57] [cursor=pointer]: + - /url: https://grafana.com/products/enterprise/?utm_source=grafana_footer + - text: "|" + - listitem [ref=f6e58]: + - link "Community" [ref=f6e61] [cursor=pointer]: + - /url: https://community.grafana.com/?utm_source=grafana_footer + - text: "|" + - listitem [ref=f6e62]: + - link "Open Source" [ref=f6e63] [cursor=pointer]: + - /url: https://grafana.com/oss/grafana?utm_source=grafana_footer + - text: "|" + - listitem [ref=f6e64]: + - link "Grafana v11.4.0 (b58701869e)" [ref=f6e65] [cursor=pointer]: + - /url: https://github.com/grafana/grafana/blob/main/CHANGELOG.md + - text: "|" + - listitem [ref=f6e66]: + - link "New version available!" [ref=f6e69] [cursor=pointer]: + - /url: https://grafana.com/grafana/download?utm_source=grafana_footer \ No newline at end of file diff --git a/.playwright-mcp/page-2026-09-04T03-23-27-151Z.yml b/.playwright-mcp/page-2026-09-04T03-23-27-151Z.yml new file mode 100644 index 0000000..943ed02 --- /dev/null +++ b/.playwright-mcp/page-2026-09-04T03-23-27-151Z.yml @@ -0,0 +1,159 @@ +- generic [active] [ref=f9e1]: + - generic [ref=f9e4]: + - link "Skip to main content" [ref=f9e5] [cursor=pointer]: + - /url: "#pageContent" + - banner [ref=f9e7]: + - generic [ref=f9e8]: + - link [ref=f9e10] [cursor=pointer]: + - /url: / + - img "Grafana" [ref=f9e11] + - generic [ref=f9e14]: + - button "Search or jump to..." [ref=f9e18] [cursor=pointer] + - generic [ref=f9e19]: ctrl+k + - generic [ref=f9e23]: + - button "New" [ref=f9e24] [cursor=pointer] + - button "Help" [ref=f9e30] [cursor=pointer] + - button "News" [ref=f9e33] [cursor=pointer] + - button "Profile" [ref=f9e36] [cursor=pointer]: + - img "User avatar" [ref=f9e37] + - generic [ref=f9e38]: + - button "Open menu" [ref=f9e40] [cursor=pointer] + - navigation "Breadcrumbs" [ref=f9e43]: + - list [ref=f9e44]: + - listitem [ref=f9e45]: + - link "Home" [ref=f9e46] [cursor=pointer]: + - /url: / + - listitem [ref=f9e50]: + - link "Explore" [ref=f9e51] [cursor=pointer]: + - /url: /explore + - listitem [ref=f9e55]: + - generic "Prometheus" [ref=f9e56] + - generic [ref=f9e57]: + - generic [ref=f9e60]: + - button "Copy shortened URL" [ref=f9e61] [cursor=pointer] + - button "Open copy link options" [ref=f9e64] [cursor=pointer] + - button "Toggle top search bar" [ref=f9e68] [cursor=pointer] + - main [ref=f9e74]: + - generic [ref=f9e76]: + - heading "Explore" [level=1] [ref=f9e77] + - generic [ref=f9e82]: + - navigation "Explore toolbar" [ref=f9e84]: + - navigation "Search links" [ref=f9e86]: + - generic [ref=f9e87]: + - button "Content outline" [expanded] [ref=f9e89] [cursor=pointer]: + - generic [ref=f9e92]: Outline + - generic [ref=f9e97] [cursor=pointer]: + - img "Prometheus logo" [ref=f9e99] + - textbox "Select a data source" [ref=f9e100]: + - /placeholder: "" + - generic [ref=f9e104]: + - button "Split the pane" [ref=f9e106] [cursor=pointer]: + - generic [ref=f9e109]: Split + - button "Add" [ref=f9e111] [cursor=pointer] + - generic [ref=f9e116]: + - 'button "Time range selected: Last 55 minutes" [ref=f9e117] [cursor=pointer]' + - button "Zoom out time range" [ref=f9e122] [cursor=pointer] + - generic [ref=f9e126]: + - button "Run query" [ref=f9e127] [cursor=pointer] + - button "Auto refresh turned off. Choose refresh time interval" [ref=f9e131] [cursor=pointer] + - generic [ref=f9e135]: + - generic [ref=f9e139]: + - button "Collapse outline" [expanded] [ref=f9e141] [cursor=pointer]: + - img "arrow-from-right" [ref=f9e142] + - button "Queries" [ref=f9e145] [cursor=pointer]: + - img "arrow" [ref=f9e146] + - button "Graph" [ref=f9e150] [cursor=pointer]: + - img "graph-bar" [ref=f9e151] + - generic [ref=f9e158]: + - generic [ref=f9e160]: + - generic "Query editor row" [ref=f9e163]: + - generic [ref=f9e164]: + - generic [ref=f9e166]: + - generic [ref=f9e167]: + - button "Collapse query row" [expanded] [ref=f9e168] [cursor=pointer] + - generic [ref=f9e171]: + - button "Query editor row title A" [ref=f9e172] [cursor=pointer]: + - generic [ref=f9e173]: A + - emphasis [ref=f9e174]: (Prometheus) + - generic [ref=f9e175]: + - button "Show data source help" [ref=f9e177] [cursor=pointer] + - button "Duplicate query" [ref=f9e181] [cursor=pointer] + - button "Hide response" [ref=f9e185] [cursor=pointer] + - button "Remove query" [ref=f9e189] [cursor=pointer] + - button "Drag and drop to reorder" [ref=f9e192]: + - img "Drag and drop to reorder" [ref=f9e193] + - generic [ref=f9e196]: + - generic [ref=f9e197]: + - button "Kick start your query" [ref=f9e198] [cursor=pointer] + - generic [ref=f9e201]: + - generic [ref=f9e202] [cursor=pointer]: Explain + - generic [ref=f9e203]: + - checkbox "Explain Toggle switch" [ref=f9e204] + - generic "Toggle switch" [ref=f9e205] [cursor=pointer] + - radiogroup [ref=f9e210]: + - generic [ref=f9e211]: + - radio "Builder" [ref=f9e212] [cursor=pointer] + - generic [ref=f9e213] [cursor=pointer]: Builder + - generic [ref=f9e214]: + - radio "Code" [checked] [ref=f9e215] [cursor=pointer] + - generic [ref=f9e216] [cursor=pointer]: Code + - generic [ref=f9e218]: + - generic [ref=f9e220]: + - button "Metrics browser" [ref=f9e221] [cursor=pointer] + - code [ref=f9e228]: + - generic [ref=f9e229]: + - generic [ref=f9e234]: "up{job=~\"keycloak|node-exporter\"}" + - textbox "Editor content;Press Alt+F1 for Accessibility Options." [ref=f9e239]: "up{job=~\"keycloak|node-exporter\"}" + - 'button "Options Legend: {{job}} — {{pod}}{{node}} Format: Time series Step: auto Type: Range Exemplars: false" [ref=f9e245] [cursor=pointer]': + - generic [ref=f9e249]: + - heading "Options" [level=6] [ref=f9e250] + - generic [ref=f9e251]: + - generic [ref=f9e252]: "Legend: {{job}} — {{pod}}{{node}}" + - generic [ref=f9e253]: "Format: Time series" + - generic [ref=f9e254]: "Step: auto" + - generic [ref=f9e255]: "Type: Range" + - generic [ref=f9e256]: "Exemplars: false" + - generic [ref=f9e257]: + - button "Add query" [ref=f9e258] [cursor=pointer] + - button "Query history" [ref=f9e262] [cursor=pointer] + - button "Query inspector" [ref=f9e266] [cursor=pointer] + - main [ref=f9e270]: + - region [ref=f9e272]: + - generic [ref=f9e273]: + - heading "Graph" [level=2] [ref=f9e275] + - radiogroup [ref=f9e278]: + - generic [ref=f9e279]: + - radio "Lines" [checked] [ref=f9e280] [cursor=pointer] + - generic [ref=f9e281] [cursor=pointer]: Lines + - generic [ref=f9e282]: + - radio "Bars" [ref=f9e283] [cursor=pointer] + - generic [ref=f9e284] [cursor=pointer]: Bars + - generic [ref=f9e285]: + - radio "Points" [ref=f9e286] [cursor=pointer] + - generic [ref=f9e287] [cursor=pointer]: Points + - generic [ref=f9e288]: + - radio "Stacked lines" [ref=f9e289] [cursor=pointer] + - generic [ref=f9e290] [cursor=pointer]: Stacked lines + - generic [ref=f9e291]: + - radio "Stacked bars" [ref=f9e292] [cursor=pointer] + - generic [ref=f9e293] [cursor=pointer]: Stacked bars + - list [ref=f9e311]: + - listitem [ref=f9e312]: + - button "keycloak — keycloak-1kc-lab-1" [ref=f9e316] [cursor=pointer] + - listitem [ref=f9e317]: + - button "keycloak — keycloak-1kc-lab-1" [ref=f9e321] [cursor=pointer] + - listitem [ref=f9e322]: + - button "keycloak — keycloak-0kc-lab-2" [ref=f9e326] [cursor=pointer] + - listitem [ref=f9e327]: + - button "keycloak — keycloak-0kc-lab-2" [ref=f9e331] [cursor=pointer] + - listitem [ref=f9e332]: + - button "keycloak — keycloak-0kc-lab-2" [ref=f9e336] [cursor=pointer] + - listitem [ref=f9e337]: + - button "node-exporter — kc-lab-1" [ref=f9e341] [cursor=pointer] + - listitem [ref=f9e342]: + - button "node-exporter — kc-lab-2" [ref=f9e346] [cursor=pointer] + - generic [ref=f9e351]: + - alert + - alert + - complementary + - complementary \ No newline at end of file diff --git a/docs/evidence/a4-node-loss/01-baseline.txt b/docs/evidence/a4-node-loss/01-baseline.txt new file mode 100644 index 0000000..ea9de8e --- /dev/null +++ b/docs/evidence/a4-node-loss/01-baseline.txt @@ -0,0 +1,20 @@ +=== A-4 기준선 === +kc-lab-1 Ready true +kc-lab-2 Ready + +a2-probe true kc-lab-2 +keycloak-0 true kc-lab-2 +keycloak-1 true kc-lab-1 +postgres-7b474b88c8-2gf27 true kc-lab-2 + +=== PVC 가 어느 노드에 묶여 있는가 (재배치 가능성) === + persistentvolumeclaim/postgres-data → kc-lab-2 + +=== 서비스 정상 확인 === + https://auth.hyeonworks.com/realms/master HTTP 200 + +=== VM 상태 === +-------------------------- + 1 kc-lab-1 running + 2 kc-lab-2 running + diff --git a/docs/evidence/a4-node-loss/02-worker-node-killed.txt b/docs/evidence/a4-node-loss/02-worker-node-killed.txt new file mode 100644 index 0000000..a8ab55d --- /dev/null +++ b/docs/evidence/a4-node-loss/02-worker-node-killed.txt @@ -0,0 +1,17 @@ +=== 워커 노드(kc-lab-2) 전원 차단 — virsh destroy 는 종료 신호가 없다 === +차단 시각: 12:07:43 +Domain 'kc-lab-2' destroyed + + + +15초 node=Ready | keycloak-0=Running postgres-7b474b88c8-2gf27=Running | 외부 HTTP 000 + +30초 node=Ready | keycloak-0=Running postgres-7b474b88c8-2gf27=Running | 외부 HTTP 000 + +45초 node=NotReady | keycloak-0=Running postgres-7b474b88c8-2gf27=Running | 외부 HTTP 503 + +60초 node=NotReady | keycloak-0=Running postgres-7b474b88c8-2gf27=Running | 외부 HTTP 503 + +75초 node=NotReady | keycloak-0=Running postgres-7b474b88c8-2gf27=Running | 외부 HTTP 503 + +90초 node=NotReady | keycloak-0=Running postgres-7b474b88c8-2gf27=Running | 외부 HTTP 503 + +105초 node=NotReady | keycloak-0=Running postgres-7b474b88c8-2gf27=Running | 외부 HTTP 503 + +120초 node=NotReady | keycloak-0=Running postgres-7b474b88c8-2gf27=Running | 외부 HTTP 503 + +135초 node=NotReady | keycloak-0=Running postgres-7b474b88c8-2gf27=Running | 외부 HTTP 503 + +150초 node=NotReady | keycloak-0=Running postgres-7b474b88c8-2gf27=Running | 외부 HTTP 503 + +165초 node=NotReady | keycloak-0=Running postgres-7b474b88c8-2gf27=Running | 외부 HTTP 503 + +180초 node=NotReady | keycloak-0=Running postgres-7b474b88c8-2gf27=Running | 외부 HTTP 503 diff --git a/docs/evidence/a4-node-loss/03-state-during-loss.txt b/docs/evidence/a4-node-loss/03-state-during-loss.txt new file mode 100644 index 0000000..a5d5557 --- /dev/null +++ b/docs/evidence/a4-node-loss/03-state-during-loss.txt @@ -0,0 +1,28 @@ +=== 파드 상태의 진실 — Running 인데 노드가 없다 === +a2-probe Running true kc-lab-2 +keycloak-0 Running true kc-lab-2 +keycloak-1 Running false kc-lab-1 +postgres-7b474b88c8-2gf27 Running true kc-lab-2 + +=== 재배치가 시도되었는가 === +10m Warning Unhealthy pod/keycloak-0 Readiness probe failed: Get "http://10.42.1.67:9000/health/ready": context deadline exceeded (Client.Timeout exceeded while awaiting headers) +3m15s Warning NodeNotReady pod/postgres-7b474b88c8-2gf27 Node is not ready +3m15s Warning NodeNotReady pod/keycloak-0 Node is not ready +3m15s Warning NodeNotReady pod/a2-probe Node is not ready +2m27s Warning Unhealthy pod/keycloak-1 Readiness probe failed: Get "http://10.42.0.35:9000/health/ready": context deadline exceeded (Client.Timeout exceeded while awaiting headers) +2s Warning Unhealthy pod/keycloak-1 Readiness probe failed: HTTP probe failed with statuscode: 503 + +=== 노드 taint — 쿠버네티스가 붙인 것 === + node.kubernetes.io/unreachable=:NoSchedule + node.kubernetes.io/unreachable=:NoExecute + +=== Prometheus 가 본 것 (kc-lab-1 에 있어 살아남았다) === + up{job=keycloak pod=keycloak-1 } = 1 + up{job=keycloak pod=keycloak-0 } = 0 + up{job=kubelet pod=- } = 1 + up{job=kubelet pod=- } = 0 + up{job=node-exporter pod=kc-lab-1 } = 1 + up{job=node-exporter pod=kc-lab-2 } = 0 + up{job=prometheus pod=- } = 1 + +=== 진입점이 처음 40초간 000 이었던 이유 — nginx upstream === diff --git a/docs/evidence/a4-node-loss/04-eviction-timing.txt b/docs/evidence/a4-node-loss/04-eviction-timing.txt new file mode 100644 index 0000000..03de449 --- /dev/null +++ b/docs/evidence/a4-node-loss/04-eviction-timing.txt @@ -0,0 +1,15 @@ +=== nginx 설정 위치 찾기 === + +=== NoExecute taint 의 tolerationSeconds — 언제 축출되는가 === + node.kubernetes.io/not-ready NoExecute tolerationSeconds=300 + node.kubernetes.io/unreachable NoExecute tolerationSeconds=300 + +=== 5분 축출 시점까지 관찰 === + +210초 a2-probe:Running keycloak-0:Running keycloak-1:Running postgres-7b474b88c8-2gf27:Running + +240초 a2-probe:Running keycloak-0:Running keycloak-1:Running postgres-7b474b88c8-2gf27:Running + +270초 a2-probe:Terminating keycloak-0:Terminating keycloak-1:Running postgres-7b474b88c8-2gf27:Terminating postgres-7b474b88c8-9cmsv:Pending + +300초 a2-probe:Terminating keycloak-0:Terminating keycloak-1:Running postgres-7b474b88c8-2gf27:Terminating postgres-7b474b88c8-9cmsv:Pending + +330초 a2-probe:Terminating keycloak-0:Terminating keycloak-1:Running postgres-7b474b88c8-2gf27:Terminating postgres-7b474b88c8-9cmsv:Pending + +360초 a2-probe:Terminating keycloak-0:Terminating keycloak-1:Running postgres-7b474b88c8-2gf27:Terminating postgres-7b474b88c8-9cmsv:Pending + +390초 a2-probe:Terminating keycloak-0:Terminating keycloak-1:Running postgres-7b474b88c8-2gf27:Terminating postgres-7b474b88c8-9cmsv:Pending + +420초 a2-probe:Terminating keycloak-0:Terminating keycloak-1:Running postgres-7b474b88c8-2gf27:Terminating postgres-7b474b88c8-9cmsv:Pending diff --git a/docs/evidence/a4-node-loss/05-recovery.txt b/docs/evidence/a4-node-loss/05-recovery.txt new file mode 100644 index 0000000..d70cff4 --- /dev/null +++ b/docs/evidence/a4-node-loss/05-recovery.txt @@ -0,0 +1,18 @@ +=== 새 postgres 가 Pending 인 이유 === +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Warning FailedScheduling 4m45s default-scheduler 0/2 nodes are available: 1 node(s) didn't match PersistentVolume's node affinity, 1 node(s) had untolerated taint(s). no new claims to deallocate, preemption: 0/2 nodes are available: 2 Preemption is not helpful for scheduling. + +=== keycloak-0 대체 파드가 안 생기는 이유 (StatefulSet) === +keycloak 2 1 +keycloak-0 1/1 Terminating 0 30m +keycloak-1 0/1 Running 0 143m + +=== 복구 — 노드 재기동 === +재기동 시각: 12:16:31 +Domain 'kc-lab-2' started + + +30초 node=Ready | Running 파드 3 개 | 외부 HTTP 503 + +60초 node=Ready | Running 파드 3 개 | 외부 HTTP 200 + → 서비스 복귀 diff --git a/docs/evidence/a4-node-loss/06-control-plane-inventory.txt b/docs/evidence/a4-node-loss/06-control-plane-inventory.txt new file mode 100644 index 0000000..022af30 --- /dev/null +++ b/docs/evidence/a4-node-loss/06-control-plane-inventory.txt @@ -0,0 +1,19 @@ +=== 복구 확인 === +keycloak-0 1/1 Running 0 68s +keycloak-1 1/1 Running 0 144m +postgres-7b474b88c8-9cmsv 1/1 Running 0 4m20s + +=== kc-lab-1(k3s server)에 무엇이 있는가 — 이게 곧 영향 범위다 === + keycloak-lab keycloak-1 + kube-system coredns-54996dc9b4-8k8fj + kube-system helm-install-traefik-crd-q29b5 + kube-system local-path-provisioner-77b9867795-g27z8 + kube-system metrics-server-6dc596dfb8-7xxq4 + kube-system svclb-traefik-5eb6a9a1-qwwk5 + kube-system traefik-5d6fcf895-wpfhr + observability grafana-845b5678cf-b6gvc + observability node-exporter-9qk9w + observability prometheus-6774f94f7c-pzr2t + +=== Traefik replica 수 (진입점의 단일 장애점인가) === +traefik 1 1 diff --git a/docs/evidence/a4-node-loss/07-control-plane-loss.txt b/docs/evidence/a4-node-loss/07-control-plane-loss.txt new file mode 100644 index 0000000..348eceb --- /dev/null +++ b/docs/evidence/a4-node-loss/07-control-plane-loss.txt @@ -0,0 +1,19 @@ +=== 컨트롤 플레인 노드(kc-lab-1) 전원 차단 === +차단 시각: 12:18:08 +Domain 'kc-lab-1' destroyed + + + +20초 외부 auth=000 grafana=000 | kubectl: Unable to connect to the server: dial tcp + +40초 외부 auth=000 grafana=000 | kubectl: Unable to connect to the server: dial tcp + +60초 외부 auth=000 grafana=000 | kubectl: Unable to connect to the server: dial tcp + +80초 외부 auth=000 grafana=000 | kubectl: Unable to connect to the server: dial tcp + +100초 외부 auth=000 grafana=000 | kubectl: Unable to connect to the server: dial tcp + +120초 외부 auth=000 grafana=502 | kubectl: Unable to connect to the server: dial tcp + +140초 외부 auth=000 grafana=000 | kubectl: Unable to connect to the server: dial tcp + +160초 외부 auth=000 grafana=000 | kubectl: Unable to connect to the server: dial tcp + +=== 살아 있는 노드에서 직접 확인 — 워크로드는 도는가 === + CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD NAMESPACE + e5f777900b762 60e153026e8f5 4 minutes ago Running keycloak 0 640d4dafaefb3 keycloak-0 keycloak-lab + + 6 diff --git a/docs/evidence/a4-node-loss/08-control-plane-recovery.txt b/docs/evidence/a4-node-loss/08-control-plane-recovery.txt new file mode 100644 index 0000000..0ed0e7b --- /dev/null +++ b/docs/evidence/a4-node-loss/08-control-plane-recovery.txt @@ -0,0 +1,13 @@ +=== 컨트롤 플레인 노드 복구 === +재기동: 12:23:39 +Domain 'kc-lab-1' started + + +30초 외부=502 | kc-lab-1=Ready kc-lab-2=Ready + +60초 외부=200 | kc-lab-1=Ready kc-lab-2=Ready + → 서비스 복귀 (총 60초) + +=== 최종 상태 === +keycloak-0 1/1 Running 0 7m57s +keycloak-1 1/1 Running 1 ( ago) 151m +postgres-7b474b88c8-9cmsv 1/1 Running 0 11m + (prometheus port-forward 재연결 필요) diff --git a/docs/evidence/a4-node-loss/README.md b/docs/evidence/a4-node-loss/README.md new file mode 100644 index 0000000..db38b7d --- /dev/null +++ b/docs/evidence/a4-node-loss/README.md @@ -0,0 +1,23 @@ +# A-4 — 노드 전원 차단 증거 + +2026-09-04 12:07–12:24 KST +해설: [`docs/experiment-a4-node-loss.md`](../../experiment-a4-node-loss.md) + +| 파일 | 무엇을 보여주는가 | +|---|---| +| `01-baseline.txt` | 차단 전 — 양쪽 Ready, **PVC 가 kc-lab-2 에 못박혀 있음**(재배치 불가의 원인), 외부 200 | +| `02-worker-node-killed.txt` | `virsh destroy kc-lab-2` — **40초간 노드가 Ready 로 남아 있고** 외부는 이미 `000`. 이후 `503` | +| `03-state-during-loss.txt` | **죽은 파드가 `ready=true`, 산 파드가 `ready=false`.** `up` 은 정확히 0. `unreachable` taint | +| `04-eviction-timing.txt` | `tolerationSeconds=300` — **5분 뒤** 축출, 새 postgres 는 `Pending` | +| `05-recovery.txt` | `FailedScheduling: didn't match PersistentVolume's node affinity`, StatefulSet `DESIRED=2 CURRENT=1`. 노드 복귀 후 **60초** | +| `06-control-plane-inventory.txt` | kc-lab-1 에 있는 것 목록 — **Traefik `replicas=1`** | +| `07-control-plane-loss.txt` | `virsh destroy kc-lab-1` — 외부 `000`, `kubectl` 불통. **그런데 `crictl ps` 로 보면 keycloak-0 은 Running** | +| `08-control-plane-recovery.txt` | 60초 만에 복귀 | +| `a4-up-dropped-per-node.png` | Grafana — `up` 이 노드별로 0 으로 떨어지는 구간. 12:18–12:23 은 **0 이 아니라 데이터 없음**(관측자가 같이 죽음) | + +## 핵심 네 줄 + +1. **쿠버네티스는 40초 동안 노드가 살아 있다고 말한다.** 사용자는 이미 장애를 겪는 중이다. +2. **죽은 파드의 상태는 화석이다.** `ready=true` 인 파드가 꺼진 기계 위에 있다. +3. **StatefulSet 은 대체 파드를 만들지 않고, PVC 는 재배치를 막는다.** 사람이 개입해야 한다. +4. **컨트롤 플레인 상실 ≠ 워크로드 상실.** 컨테이너는 계속 돌고, 들어갈 문만 사라진다. diff --git a/docs/evidence/a4-node-loss/a4-up-dropped-per-node.png b/docs/evidence/a4-node-loss/a4-up-dropped-per-node.png new file mode 100644 index 0000000000000000000000000000000000000000..606cc6fd982fbfa4c3cc7159f77c3d9ffd400a36 GIT binary patch literal 80937 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ɐ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

PdCIB-Zqgyq4fc-7Kd)iMQD^k56hX@NEoIwF>r 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 N + +keycloak-0 ready=true kc-lab-2 +keycloak-1 ready=true kc-lab-1 +postgres ready=true kc-lab-2 + +PVC postgres-data → kc-lab-2 ← 재배치 가능성을 여기서 이미 알 수 있다 +외부 HTTP 200 +``` + +### 주입 + +```bash +virsh destroy kc-lab-2 +``` + +### 관찰 + +``` + +15초 node=Ready | keycloak-0=Running postgres=Running | 외부 HTTP 000 + +30초 node=Ready | keycloak-0=Running postgres=Running | 외부 HTTP 000 + +45초 node=NotReady | keycloak-0=Running postgres=Running | 외부 HTTP 503 + ... + +180초 node=NotReady | keycloak-0=Running postgres=Running | 외부 HTTP 503 +``` + +### 발견 ① — 쿠버네티스가 알아채는 데 **40초** 걸린다 + +`+15초`, `+30초` 에도 노드는 여전히 `Ready` 다. **기계는 이미 없는데.** + +kube-controller-manager 의 `node-monitor-grace-period` (기본 40초) 동안 +kubelet 의 하트비트가 없어야 `NotReady` 로 바꾼다. + +> **그 40초 동안 쿠버네티스는 거짓말을 한다.** 사용자는 이미 장애를 겪고 있다 +> (`000`). **노드 상태를 알림 근거로 삼으면 항상 늦는다.** + +### 발견 ② — **죽은 파드가 산 파드보다 건강해 보인다** + +``` +POD PHASE READY NODE +keycloak-0 Running true kc-lab-2 ← 기계가 꺼져 있다 +keycloak-1 Running false kc-lab-1 ← 살아 있다 +``` + +**`keycloak-0` 은 `ready=true`, `keycloak-1` 은 `ready=false`.** + +| 왜 | | +|---|---| +| keycloak-0 | kubelet 이 없어 **상태를 갱신할 수 없다.** 마지막으로 보고한 값이 그대로 얼어 있다 | +| keycloak-1 | 살아서 **정직하게 보고한다** — DB 가 없으니 readiness 실패 | + +> **파드 상태는 "지금 어떤가"가 아니라 "마지막으로 그렇게 들었다"이다.** +> 노드가 죽으면 그 노드 파드의 상태는 **화석**이 된다. + +Prometheus 는 정확했다. + +``` + up{job=keycloak pod=keycloak-1} = 1 + up{job=keycloak pod=keycloak-0} = 0 ← 긁기에 실패했다 = 사실 + up{job=kubelet } = 0 + up{job=node-exporter node=kc-lab-2 } = 0 +``` + +**A-2 와 정반대다.** A-2 에서는 `up=1` 인데 서비스가 죽었고, 여기서는 `up=0` +이 정확했다. + +| | `up` 이 잡는가 | +|---|---| +| **대상이 사라짐** (노드 상실) | **잡는다** | +| **대상이 살아서 못 씀** (DB 상실) | **못 잡는다** | + +![up 이 노드별로 0 으로 떨어졌다](evidence/a4-node-loss/a4-up-dropped-per-node.png) + +### 발견 ③ — 축출은 **5분** 뒤에 시작된다 + +쿠버네티스가 노드에 taint 를 붙인다. + +``` + node.kubernetes.io/unreachable=:NoSchedule + node.kubernetes.io/unreachable=:NoExecute +``` + +그런데 모든 파드에는 기본 관용이 붙어 있다. + +``` + node.kubernetes.io/not-ready NoExecute tolerationSeconds=300 + node.kubernetes.io/unreachable NoExecute tolerationSeconds=300 +``` + +``` + +240초 전부 Running + +270초 a2-probe:Terminating keycloak-0:Terminating postgres:Terminating + postgres-...-9cmsv:Pending ← 새 파드가 생겼다 +``` + +**노드가 죽고 약 5분이 지나야 파드가 축출된다.** 잠깐 끊긴 노드가 돌아올 수도 +있으니 성급하게 옮기지 않겠다는 설계다. 대신 **그동안은 아무 일도 일어나지 +않는다.** + +### 발견 ④ — 축출돼도 **갈 곳이 없다** + +``` +Warning FailedScheduling default-scheduler + 0/2 nodes are available: + 1 node(s) didn't match PersistentVolume's node affinity, + 1 node(s) had untolerated taint(s). +``` + +``` + kc-lab-2 → taint 때문에 못 간다 (죽은 노드) + kc-lab-1 → PVC 가 kc-lab-2 에 묶여 있어 못 간다 +``` + +**`local-path` PVC 는 그 노드의 로컬 디스크 디렉터리다.** 노드가 죽으면 +볼륨도 죽는다. 새 파드는 **영원히 Pending** 이다. + +> 결함이 아니라 **조건**이다. 이 실험대는 그걸 알고 `local-path` 를 골랐다. +> 운영이라면 네트워크 스토리지나 DB 복제가 이 자리를 메워야 한다. + +### 발견 ⑤ — StatefulSet 은 **대체 파드를 만들지 않는다** + +``` +NAME DESIRED READY CURRENT +keycloak 2 1 + +keycloak-0 1/1 Terminating 30m ← 30분째 +keycloak-1 0/1 Running +``` + +**`keycloak-0` 이 `Terminating` 에서 영원히 멈춰 있고, 대체 파드가 안 생긴다.** + +| 왜 | | +|---|---| +| StatefulSet 의 계약 | **같은 이름의 파드는 클러스터에 하나뿐**이어야 한다 | +| 컨트롤 플레인이 아는 것 | 노드가 안 보인다 = **파드가 죽었는지 확신할 수 없다** | +| 그래서 | 옛 파드를 확실히 지우기 전엔 새 `keycloak-0` 을 못 만든다 | + +**Deployment 였다면 즉시 새 파드를 만든다.** 이름이 아무래도 되기 때문이다. +StatefulSet 의 "안정된 이름"이라는 이득의 **반대편 비용**이 여기다. + +강제로 진행시키려면 사람이 개입해야 한다. + +```bash +kubectl -n keycloak-lab delete pod keycloak-0 --grace-period=0 --force +``` + +**위험한 명령이다.** 노드가 사실은 살아 있고 네트워크만 끊긴 것이라면 +**같은 이름의 파드 둘이 동시에 존재**하게 된다 (split brain). + +### 복구 + +```bash +virsh start kc-lab-2 +``` + +``` + +30초 node=Ready | Running 파드 3 개 | 외부 HTTP 503 + +60초 node=Ready | Running 파드 3 개 | 외부 HTTP 200 + → 서비스 복귀 +``` + +**60초.** 사람 개입 없이 전부 제자리로 돌아왔다. + +--- + +## 4b. 컨트롤 플레인 노드 상실 (`kc-lab-1`) + +### 이 노드에 무엇이 있었나 — 그게 곧 영향 범위다 + +``` +keycloak-lab keycloak-1 +kube-system coredns +kube-system local-path-provisioner +kube-system metrics-server +kube-system svclb-traefik +kube-system traefik ← replicas=1 +observability grafana +observability prometheus +observability node-exporter +``` + +``` +NAME REPLICAS READY +traefik 1 1 ← 진입점이 한 개다 +``` + +### 주입과 관찰 + +```bash +virsh destroy kc-lab-1 +``` + +``` + +20초 외부 auth=000 grafana=000 | kubectl: Unable to connect to the server + +60초 외부 auth=000 grafana=000 | kubectl: Unable to connect to the server + +120초 외부 auth=000 grafana=502 | kubectl: Unable to connect to the server + +160초 외부 auth=000 grafana=000 | kubectl: Unable to connect to the server +``` + +### 발견 ⑥ — 워크로드는 살아 있는데 **길이 없다** + +살아남은 노드에서 직접 확인했다. + +```bash +ssh kc-lab-2 'sudo crictl ps --name keycloak' +``` + +``` +CONTAINER STATE NAME POD NAMESPACE +e5f777900b76 Running keycloak keycloak-0 keycloak-lab +``` + +**`keycloak-0` 은 멀쩡히 돌고 있다.** 컨테이너 런타임(containerd)은 API 서버 +없이도 이미 떠 있는 파드를 계속 굴린다. + +``` + 죽은 것: API 서버 · 스케줄러 · coredns · Traefik · Prometheus · Grafana + 산 것: keycloak-0 · postgres · containerd + 문제: 들어갈 문(Traefik)이 없다 +``` + +> **컨트롤 플레인 상실은 워크로드 상실이 아니다.** +> 이미 떠 있는 것은 계속 돈다. **새로 뜨거나 옮기거나 고치는 것이 안 될 뿐.** + +### 발견 ⑦ — `000` 과 `503` 의 차이 + +| 코드 | 뜻 | +|---|---| +| **`503`** (4a) | nginx·Traefik 은 살아 있고 **뒤에 보낼 파드가 없다** | +| **`000`** (4b) | curl 이 응답 자체를 못 받았다 — **Traefik 이 없어 nginx 가 죽은 주소를 기다리다 타임아웃** | + +`grafana=502` 가 한 번 찍힌 것이 증거다 — nginx 는 살아서 502 를 만들 수 +있었지만, 대부분은 타임아웃(`--max-time 8`)에 걸렸다. + +**두 코드가 다른 층의 고장을 가리킨다.** + +### 발견 ⑧ — 관측 시스템이 같이 죽으면 **0 이 아니라 구멍이 남는다** + +Prometheus 가 `kc-lab-1` 에 있었다. 그 노드가 죽은 12:18–12:23 구간은 +그래프에 **0 이 아니라 데이터 없음**으로 남는다. + +``` + 대상이 죽음 → up = 0 → "언제 죽었는지" 알 수 있다 + 관측자가 죽음 → 데이터 없음 → "그때 무슨 일이 있었는지" 모른다 +``` + +**계획 단계에서 "관측 스택은 죽이지 않는 노드에 둔다"고 정했던 이유**를 +실제로 확인한 셈이다. 다만 노드가 둘뿐이라 완전히 피할 수는 없다. + +### 복구 + +```bash +virsh start kc-lab-1 +``` + +``` + +30초 외부=502 | kc-lab-1=Ready kc-lab-2=Ready + +60초 외부=200 | kc-lab-1=Ready kc-lab-2=Ready + → 서비스 복귀 (총 60초) +``` + +**Grafana 는 로그인 세션을 잃었다** — 데이터가 `emptyDir` 이라 파드 재시작에 +사라진다. Prometheus 는 PVC 라 지표가 남았다. **의도한 설계대로 동작했다.** + +--- + +## 5. 개념 + +### `node-monitor-grace-period` 와 `tolerationSeconds` + +``` + 기계 정지 + │ + │ 40초 node-monitor-grace-period → 노드 NotReady + │ + │ +300초 tolerationSeconds (NoExecute) → 파드 축출 시작 + │ + ▼ + 총 약 5분 40초 동안 쿠버네티스는 아무것도 하지 않는다 +``` + +**빠른 장애 대응이 필요하면 이 값을 줄여야 하지만**, 짧게 하면 일시적 +네트워크 끊김에도 파드를 옮기게 되어 **불안정해진다.** 맞바꿈이다. + +### `Terminating` 이 안 끝나는 이유 + +``` + 파드 삭제 요청 + └─ kubelet 이 컨테이너를 멈추고 "지웠다"고 보고해야 끝난다 + └─ kubelet 이 없다 → 보고가 없다 → 영원히 Terminating +``` + +`--grace-period=0 --force` 는 **보고를 기다리지 않고 API 에서 지우는 것**이다. +컨테이너가 실제로 죽었는지는 **모른 채** 진행한다. + +### StatefulSet vs Deployment — 노드 상실에서 + +| | Deployment | StatefulSet | +|---|---|---| +| 대체 파드 | **즉시 만든다** (이름 무관) | **안 만든다** (이름이 유일해야) | +| 노드 상실 시 | 자동 회복 | **사람이 강제 삭제해야** | +| 위험 | 없음 | 강제 삭제 시 **중복 실행 가능** | + +**A-0 에서 "로그 대조가 쉬워서" StatefulSet 을 골랐는데, 그 대가가 여기 있다.** + +### `local-path` PVC 와 재배치 + +``` + PVC → PV → nodeAffinity: kubernetes.io/hostname = kc-lab-2 + └─ 그 노드의 /var/lib/rancher/k3s/storage/... 디렉터리 +``` + +**볼륨이 노드에 못박히면 파드도 못박힌다.** 노드가 죽으면 데이터도 함께 +접근 불가가 된다. + +--- + +## 6. 재현 절차 (명령어) + +```bash +export LIBVIRT_DEFAULT_URI=qemu:///system + +# 사전 — PVC 가 어디 묶여 있는지 먼저 본다 (재배치 가능성이 여기서 정해진다) +kubectl -n keycloak-lab get pvc -o name | while read p; do + V=$(kubectl -n keycloak-lab get $p -o jsonpath='{.spec.volumeName}') + kubectl get pv $V -o jsonpath='{.spec.nodeAffinity.required.nodeSelectorTerms[0].matchExpressions[0].values[0]}' +done + +# 4a 워커 상실 +virsh destroy kc-lab-2 +kubectl get node kc-lab-2 # 40초 뒤 NotReady +kubectl -n keycloak-lab get pods -o wide # Running 인 채로 얼어 있다 +kubectl get node kc-lab-2 -o jsonpath='{.spec.taints}' +# 5분 뒤 Terminating + 새 파드 Pending +kubectl -n keycloak-lab describe pod | grep -A4 Events + +# 4b 컨트롤 플레인 상실 — kubectl 이 죽으므로 노드에서 직접 본다 +virsh destroy kc-lab-1 +ssh kc-lab-2 'sudo crictl ps' # 워크로드는 살아 있다 + +# 복구 +virsh start kc-lab-2 && virsh start kc-lab-1 +``` + +--- + +## 7. 다음 실험에 남기는 것 + +| 실험 | 이 실험이 준 것 | +|---|---| +| **A-5** 비대칭 파티션 | 여기서는 노드가 **완전히** 사라졌다. 부분 단절은 더 고약하다 | +| **D-1** 백업·복구 | **PVC 가 노드에 묶여 있다** — 노드가 영영 안 돌아오면 백업이 유일한 길 | +| 구성 개선 | **Traefik `replicas=1` 은 진입점 단일 장애점** — 2로 늘리거나 DaemonSet 으로 | +| 구성 개선 | **Grafana 가 `emptyDir`** — 재시작마다 로그인 세션이 사라진다 |