4.4 KiB
4.4 KiB
date, topic, areas, tags
| date | topic | areas | tags | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| 2026-06-11 | kr2 K3s control-plane 8h hang — Patroni failover 후 read-only DB로 kine 기동 wedge |
|
|
K3s 점검 중 발견. incus-kr2 control-plane의 k3s.service가 2026-06-10 22:55부터 약 8시간 activating 상태로 멈춰 kr3 컨텍스트 API(100.119.109.41:6443) connection refused.
원인 체인
- 2026-06-10 22:55경 Patroni failover 발생 (leader → postgres-2 / 10.100.3.185, incus-kr1). 전환 윈도우 동안 3개 Postgres 노드가 모두 read-only.
- 마침 그 시점에 kr2 k3s가 (재)기동 중이었고, kine(pgx)이 설정된 노드 IP 3개(10.100.2.5 / 10.100.3.185 / 10.100.1.83)에 직접 연결 시도 → 전부
ValidateConnect failed: read only connection. - k3s가
Configuring pgx database connection pooling로그 직후 프로세스 hang (PID 3580986, STAT=Ssl). 8시간 동안 추가 로그 0, SIGTERM 무시(systemddeactivating에서 대기). - Patroni는 이후 정상 회복(leader 선출 완료)됐지만 kr2 k3s는 자가복구 못 하고 wedge 유지.
영향
- 클러스터는 kr1 control-plane으로 계속 서빙(
/healthzok)되어 외부 영향 제한적. kr2만 API/스케줄 제외. - 동반:
apisix/apisix-etcd-1(kr1) 같은 22:55 이벤트로 etcd raftcommitTopanic → CrashLoopBackOff. etcd quorum 2/3(hp1/hp2) 유지로 APISIX는 동작. → 씬(syn) 도메인, 별도 remediation 필요.
복구
ssh kaffa@100.119.109.41 # incus-kr2
sudo kill -9 3580986 # hang된 k3s PID 강제 종료 (SIGTERM 무시함)
sudo systemctl start k3s # 재기동 → 정상 leader(postgres-2)에 연결, 합류
- 복구 후 4노드 전부 Ready (kr1/kr2 control-plane, hp1/hp2 worker, v1.34.7+k3s1).
확정 근본 원인 (2026-06-11 정밀 분석)
- 22:55:08 Patroni가 잠깐 all-read-only (DCS/etcd-nas 순간 블립으로 failsafe 추정. 현재 etcd-nas DCS·Patroni 모두 정상). postgres-2 patroni 로그에 명시적 failover 라인은 없음 → 클린 failover가 아니라 일시적 전원 read-only 윈도우.
- 실행 중이던 kr2 k3s가 read-only로 leader-election lease 갱신 실패 →
leaderelection lost→ controller-manager 종료 → k3s.service exit code=1. - systemd가 재시작(Restart=always) → 아직 read-only 윈도우 → kine 기동이
Configuring pgx pool에서 hang. - k3s.service
Type=notify+TimeoutStartSec=0(무한) 이라, 기동 중 READY 전송 전 hang하면 systemd가 영원히 대기(activating 8h). Restart=always는 프로세스가 안 죽으니 무용.
적용한 조치 (2026-06-11)
- 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는 변경하지 않음 (아래 주의 참조).
- 즉시 복구: hang PID SIGKILL +
systemctl start k3s→ 4노드 Ready. - 동반 손상
apisix-etcd-1(kr1) 멤버:etcdctl member remove+ 데이터 wipe + 파드 재기동으로 fresh 재합류(새 idd2504d737a8e493f). etcd 3/3 healthy 복구.
⚠️ 주의 — datastore를 HAProxy로 바꾸지 말 것
당초 2026-04-08-patroni-failover-incident 교훈("HAProxy 경유")을 떠올렸으나, ../infra/data/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분) 최소화 완료.