2026-05-22 20:02 JST kr1 k3s.service가 activating 상태로 12시간 매달려 노드 NotReady → instance-manager 9d Terminating → 4 볼륨 degraded + apisix-etcd-0 raft 손상까지 연쇄. systemctl restart 한 번으로 4분 안에 회복. 재발 방지 룰 정리.
7.1 KiB
date, topic, areas, tags
| date | topic | areas | tags | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2026-05-23 | kr1 k3s.service 12시간 stuck — apisix-etcd raft 손상, cf-bouncer down, Longhorn degraded까지 연쇄 |
|
|
2026-05-23 / kr1 k3s 12시간 stuck — 다단 연쇄
배경
2026-05-22 20:02 JST 어떤 트리거로 kr1의 k3s.service가 재시작 시도 → kine connect 단계에서 process가 stuck → 12시간 동안 Active: activating (start) 상태. 이 한 사건이 다음 세 가지로 연쇄 폭발:
- apisix-etcd-0 raft 로그 손상 (kr1 위의 instance-manager가 Terminating으로 매달리면서 etcd replica write가 끊김) — 2026-05-22 23:00경 발견, 별도 복구
- Cloudflare bouncer 동기화 정지 — 사실은 2026-05-02부터 별건이었지만 이번 점검 중 함께 노출
- Longhorn 4개 볼륨 degraded + 1개 unknown — kr1의 instance-manager 9일째 Terminating으로 매달림
체감상 별건처럼 보였던 세 인시던트가 사실 같은 뿌리(kr1 NotReady)였다.
증상
kubectl get node incus-kr1→ NotReady, conditionNodeStatusUnknown"Kubelet stopped posting node status"systemctl status k3s.serviceon kr1 →Active: activating (start) since Fri 2026-05-22 20:02:20 JST; 12h ago, Main process alive but never reaching ready- kr1 호스트 자체는 살아 있음 (uptime 20d, ssh/Tailscale 정상, load 0.3, 디스크 23% / 메모리 8/62GB)
- journal 반복 에러:
k3s[*]: time="..." level=error msg="Failed to ping database connection:
failed to connect to user=kine database=kine:
10.100.2.5:5432: ValidateConnect failed: read only connection
10.100.3.185:5432: ValidateConnect failed: read only connection
10.100.1.83:5432: ValidateConnect failed: read only connection"
- 9일째 Terminating으로 매달린 pod 다수 (
instance-manager-d1d06d9c...,longhorn-ui,vmalert,rabbitmq-server-0,searxng)
진단 — 가설 → 검증
가설 1: Patroni Leader 부재 (k3s 로그 그대로)
검증: patronictl list from 임의 patroni node → postgres-2 (kr1 컨테이너, 10.100.3.185) = Leader, TL 18, lag 0. 다른 두 노드 streaming healthy. Patroni는 완전 정상. k3s 로그의 "read only connection" 메시지는 pgx 드라이버의 target_session_attrs=read-write 검증 실패 일반화 메시지로, 진짜 원인은 process 자체가 stuck이라 connection state가 stale.
가설 2: Tailscale 네트워크 단절
검증: kr1 호스트에서 세 postgres 컨테이너 IP(10.100.2.5/10.100.3.185/10.100.1.83) 모두 ping ok, TCP 5432 도달 ok, Tailscale status 정상. 네트워크는 정상.
가설 3: postgres-2 데이터 손상 (dmesg sdo I/O error)
검증: postgres-2 컨테이너 root device는 incus default pool (nvme0n1p2 위). sdo는 별도 디바이스 — Longhorn iSCSI 가상 디바이스가 한때 mount되었다 detach된 흔적. postgres 데이터는 안전. dmesg의 comm: postgres는 죽은 K8s pod의 stale mount에서 나온 거였음.
가설 4: kr1 호스트 디스크 손상
검증: smartctl -H /dev/nvme0n1 → PASSED. 호스트 디스크 정상.
결론: k3s process가 첫 시작 시점에 stuck했고 systemd가 그 상태로 12시간 retry. 새 process fork만 하면 풀림.
복구 절차 (≈ 4분)
# 1. kr1에서 k3s.service 재시작
ssh incus-kr1 'sudo systemctl restart k3s.service'
# stop-sigterm phase에 90초 정도 걸리고 (containerd-shim cleanup), 새 process가 fresh connect → active
# 2. kr1 Ready 확인
kubectl get node incus-kr1 # → Ready
# 3. 9d 매달린 Terminating pod 5개 force delete
kubectl delete pod -n longhorn-system instance-manager-d1d06d9c2833120691e8806c13559fc3 --force --grace-period=0
kubectl delete pod -n longhorn-system longhorn-ui-765d5c5b6c-68wd4 --force --grace-period=0
kubectl delete pod -n monitoring vmalert-vm-stack-victoria-metrics-k8s-stack-759d7b8595-qbb5x --force --grace-period=0
kubectl delete pod -n mq rabbitmq-server-0 --force --grace-period=0
kubectl delete pod -n searxng searxng-67c6c9d46d-75qgn --force --grace-period=0
# 4. Longhorn은 자동 회복 (kr1 노드가 Ready로 돌아오면 instance-manager 자동 재생성, degraded 볼륨은 hp1/hp2의 정상 replica로부터 자동 rebuild)
검증
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
incus-hp1 Ready <none> 36d v1.34.7+k3s1
incus-hp2 Ready <none> 59d v1.34.7+k3s1
incus-kr1 Ready control-plane 59d v1.34.7+k3s1
incus-kr2 Ready control-plane 60d v1.34.7+k3s1
$ Longhorn 볼륨 robustness
26 healthy, 0 degraded # 4 → 2 → 0 degraded, ≈ 4분
Patroni stable, ArgoCD controller 1/1, K8s 전체 비정상 pod 0.
함께 처리한 별건 (같은 점검 흐름에서 드러남)
| 별건 | 상태 | 진짜 원인 |
|---|---|---|
apisix-etcd-0 raft 손상 (2026-05-22 23:00) |
복구 완료 (별도 procedure: member remove → PVC wipe → re-add) | kr1 instance-manager가 Terminating으로 매달리면서 etcd replica write 끊김 |
cs-cloudflare-bouncer 5/2부터 down |
발견만, 미복구 (fall-mvp.com zone이 CF에서 삭제됨, config 정리 필요) |
kr1 사건과 무관, 별건 |
| Longhorn 4 볼륨 degraded + 1 unknown | k3s restart 후 자동 회복 (4분) | kr1 노드가 NotReady라 그 위 replica 사라진 결과 |
교훈
Active: activating12시간은 디버깅 우선순위 최상위. 단순 stop+start로 풀리는 경우가 압도적이고, 그 사이 노드의 모든 pod가 stale로 변해 다른 시스템에 cascading damage를 줄 수 있음.- K3s/Longhorn은 그 위에 올라간 워크로드(여기서는 etcd, ArgoCD, Patroni 등)와 결합도가 매우 높음. 노드 1개의 stuck process가 분산 시스템 전체의 정합성을 깨뜨릴 수 있다.
- kr1 k3s가 처음에 왜 멈췄는지는 미확인. Patroni가 일시적으로 leader가 없던 시점에 kine connect 실패 → graceful retry 못하고 process 자체가 stuck 상태로 진입한 가설이 가장 가능성 높음. 재현 못 함.
- 재발 방지: kr1 NotReady 알림을 받으면 (1) systemctl status k3s.service의 ActiveState 확인 → (2)
activating이면 즉시 restart, 다른 가설 점검 전 먼저. activating이 5분 넘으면 100% 비정상. - Patroni leader가 stuck 노드 위에 있을 때의 위험: postgres-2(kr1)가 leader인 상태에서 kr1이 NotReady가 되면 k3s kine이 leader에 connect는 되지만 process 자체가 stuck. Patroni가 leader를 다른 노드로 옮기지 못해서(컨테이너 자체는 정상이라 demote 트리거 없음) 결국 stuck 노드의 process 재시작이 유일한 해결.
참조
- ../infra/compute/hosts/incus-kr1
- ../infra/data/postgresql-ha
- ../infra/platform/longhorn
- 2026-04-04-usb-25g-hang — 다른 패턴이지만 kr1 관련
- 2026-05-20-kr2-multus-shim-etxtbsy — 비슷하게 K3s 재시작 후 회복 못 한 케이스 (다른 원인)