history: kr2 k3s hang 근본원인 확정(Type=notify+TimeoutStartSec=0)+조치(TimeoutStartSec=300 drop-in, apisix-etcd reinit). HAProxy 변경 금지 명시
This commit is contained in:
@@ -30,14 +30,30 @@ sudo systemctl start k3s # 재기동 → 정상 leader(postgres-2)에
|
||||
```
|
||||
- 복구 후 4노드 전부 Ready (kr1/kr2 control-plane, hp1/hp2 worker, v1.34.7+k3s1).
|
||||
|
||||
## 재발 패턴 / 교훈
|
||||
## 확정 근본 원인 (2026-06-11 정밀 분석)
|
||||
|
||||
- **동일 패턴 재발**: [[2026-05-23-kr1-k3s-stuck-cascade]] (kr1 12h stuck), [[2026-04-08-patroni-failover-incident]] (read-only 직결 참조 사고)와 같은 계열.
|
||||
- 근본: kine이 **노드 IP 직결**(read-write 윈도우 의존) + k3s가 기동 시점 all-read-only면 **deadlock/hang**해 자가복구 못 함.
|
||||
- 개선 후보:
|
||||
1. kr2(및 kr1) k3s의 kine 연결을 노드 IP 직결 → **OpenWrt HAProxy(192.168.9.1:5432, leader 라우팅)** 경유로 변경 (2026-04-08 교훈과 동일 방향).
|
||||
2. k3s.service에 watchdog/healthcheck(`Restart=on-failure` + 기동 실패 감지) 보강 — 현재 hang은 Restart로 안 잡힘(프로세스가 살아있는 채 멈춤).
|
||||
3. Patroni failover 빈도 자체 점검 (왜 22:55에 전환됐는지 — etcd DCS 안정성).
|
||||
1. 22:55:08 **Patroni가 잠깐 all-read-only** (DCS/etcd-nas 순간 블립으로 failsafe 추정. 현재 etcd-nas DCS·Patroni 모두 정상). postgres-2 patroni 로그에 명시적 failover 라인은 없음 → 클린 failover가 아니라 일시적 전원 read-only 윈도우.
|
||||
2. 실행 중이던 kr2 k3s가 read-only로 **leader-election lease 갱신 실패** → `leaderelection lost` → controller-manager 종료 → **k3s.service exit code=1**.
|
||||
3. systemd가 재시작(Restart=always) → 아직 read-only 윈도우 → kine 기동이 `Configuring pgx pool`에서 hang.
|
||||
4. **k3s.service `Type=notify` + `TimeoutStartSec=0`(무한)** 이라, 기동 중 READY 전송 전 hang하면 systemd가 **영원히 대기**(activating 8h). Restart=always는 프로세스가 안 죽으니 무용.
|
||||
|
||||
## 적용한 조치 (2026-06-11)
|
||||
|
||||
1. **k3s hang 자동복구** (핵심 재발방지): kr1·kr2에 systemd drop-in
|
||||
`/etc/systemd/system/k3s.service.d/timeout-override.conf` → `TimeoutStartSec=300`.
|
||||
→ 기동 hang 시 5분 후 systemd가 kill, Restart=always로 재시도. DB가 RW 될 때까지 5분 주기 self-heal. (8h 행 → 최대 ~5분)
|
||||
- datastore-endpoint는 **변경하지 않음** (아래 주의 참조).
|
||||
2. 즉시 복구: hang PID SIGKILL + `systemctl start k3s` → 4노드 Ready.
|
||||
3. 동반 손상 `apisix-etcd-1`(kr1) 멤버: `etcdctl member remove` + 데이터 wipe + 파드 재기동으로 fresh 재합류(새 id `d2504d737a8e493f`). etcd 3/3 healthy 복구.
|
||||
|
||||
## ⚠️ 주의 — datastore를 HAProxy로 바꾸지 말 것
|
||||
|
||||
당초 [[2026-04-08-patroni-failover-incident]] 교훈("HAProxy 경유")을 떠올렸으나, **[[../infra/data/postgresql-ha|postgresql-ha]] 기준 HAProxy(192.168.9.1:5432)는 2026-04-16 폐기**되었고 현재 K3s kine은 **pgx multi-host(`target_session_attrs=read-write`) 3노드 직결이 정식 구성**이다(앱은 pgpool-II 경유). HAProxy는 현재 죽어있는 게 정상. → datastore-endpoint 변경은 정식 결정을 되돌리는 것이므로 금지. 문제는 endpoint가 아니라 **k3s 기동 hang 자가복구 부재**였고, 그것을 TimeoutStartSec로 해결함.
|
||||
|
||||
## 재발 패턴
|
||||
|
||||
- **3회째 동일 계열**: [[2026-04-08-patroni-failover-incident]], [[2026-05-23-kr1-k3s-stuck-cascade]], 본건.
|
||||
- 남은 더 깊은 원인(선택): Patroni가 왜 순간 all-read-only가 됐는지(etcd-nas DCS 블립 빈도) — DCS 안정성 점검 시 근절 가능. 현재는 hang 자가복구로 영향(8h→5분) 최소화 완료.
|
||||
|
||||
## 참조
|
||||
- [[../infra/data/postgresql-ha|postgresql-ha]] · [[../infra/compute/hosts/incus-kr2|incus-kr2]]
|
||||
|
||||
Reference in New Issue
Block a user