--- date: 2026-05-04 topic: incus-kr2 AMD-Vi (IOMMU) Completion-Wait timeout 호스트 부분 hang areas: - infra/compute/hosts/incus-kr2.md - infra/compute/infra-hosts.md tags: [history, incident, kr2, amd, iommu, freeze] --- ## 배경 incus-kr2가 약 2주 간격으로 호스트 freeze 재발. 이전 두 사건([[2026-04-04-usb-25g-hang]] USB autosuspend, 2026-04-19 OOM)은 각각 `usbcore.autosuspend=-1`과 `kubelet system-reserved=8Gi`로 막은 상태였으나 또 다른 원인으로 hang. Tapo 스마트플러그를 kr2에 연결하여 강제 리부팅 가능하도록 사전 대비된 상태. ## 인시던트 **시각**: 2026-05-04 12:36 KST (호스트 시계 PDT로 잘못 설정되어 있어 `May 03 20:36` 기록 — KST 12:36) **복구**: 2026-05-04 12:50 KST 사용자가 Tapo로 강제 리부팅 **다운타임**: 약 2시간 13분 (10:37 NotReady → 12:50 reboot) **영향**: leewell.com 포함 inbest 7 컨테이너 응답 일부만 동작 (LXC 커널 namespace로 nginx는 살아 외부에 nginx 404 반환), K3s 워크로드 일부 Terminating (argocd redis, db pgpool, external-secrets, longhorn csi) ## 증상 vs 가설 부정 매트릭스 | 가설 | 증거 | 결론 | |------|------|------| | NIC (USB r8152 autosuspend) | carrier=1, 다른 노드에서 wget 응답 정상, 평소 트래픽 14~70 B/s | ❌ | | NFS hard mount D-state | `procs_blocked=0` 8:43 KST까지 | ❌ | | OOM | MemoryPressure=False, MemAvailable 23 GiB | ❌ | | 디스크 hardware | SMART Critical=0, Errors=0, Percentage Used 1% | ❌ | | **AMD IOMMU Completion-Wait** | dmesg `AMD-Vi: Completion-Wait loop timed out` (12:36, 12:46 x2) → 그 직후 hang | ✅ | ## 진단 핵심 - ICMP/메모리 매핑된 프로세스(node-exporter, nginx)는 응답 유지 - containerd, incus 데몬, sshd 새 세션 fork만 동시에 hang - kubelet 마지막 이벤트: `failed to read podLogsDirectory "/var/log/pods": readdirent: input/output error` (91회 반복) - node-exporter의 `up=1`은 끊긴 적 없음 — 헤임달 1차 진단 "kr2 호스트 자체 다운 2일 2시간"은 시간대/로그 해석 오류, 실제는 당일 약 2시간 13분 - 이 패턴은 IOMMU가 stall되어 DMA 통하는 디바이스(NVMe, USB 컨트롤러)가 응답 못 하지만 커널 자체와 메모리 매핑된 프로세스는 동작하는 부분 hang의 전형 ## 직접 검증 데이터 (메트릭) **freeze 직전 (08:31~08:44 KST 호스트 시계 기준 — 실제 KST는 +9h가 아니라 호스트 시계가 PDT라서 변환 필요. K3s NotReady transition 기준 10:37:43 KST)**: - load1 = 2.22 (정상) - MemAvailable = 23.13 GiB - `procs_blocked` = 0 - `nvme0n1` io_time fraction = 2%, write 34 IOPS - NVMe 온도 41~42 °C → 점진적 자원 고갈 흔적 0. "갑자기 정지" 패턴 = 펌웨어/IOMMU level hang. ## 재부팅 후 검증 ``` [ 0.641598] iommu: Default domain type: Passthrough (set via kernel command line) ``` 이전 부팅에서 부팅 후 24분 만에 첫 Completion-Wait timeout 발생, 이후 누적되며 hang. `iommu=pt` 적용 부팅 후 동일 시점 검증 필요. ## 조치 GRUB cmdline에 `iommu=pt` 추가: ```bash sudo cp /etc/default/grub /etc/default/grub.bak.20260504-iommu sudo sed -i -E 's/^(GRUB_CMDLINE_LINUX_DEFAULT="[^"]*)(")/\1 iommu=pt\2/' /etc/default/grub sudo update-grub sudo systemctl reboot ``` **적용 후 cmdline**: ``` ro usbcore.autosuspend=-1 quiet iommu=pt ``` 부수 조치: - 호스트 시간대 `America/Los_Angeles` → `Asia/Seoul` 수정 (`timedatectl set-timezone Asia/Seoul`). 이 잘못된 timezone이 헤임달 1차 진단의 "2일 2시간" 오판 원인. ## 교훈 - AMD Ryzen 미니 PC 베어메탈은 IOMMU passthrough 기본 적용 권장. 직전 부팅 24분 만에 첫 timeout이 떴다는 건 시간 문제로 hang 보장된 상태. - IOMMU hang은 OOM/디스크/NIC와 다르게 메트릭에 점진적 흔적 안 남고 갑자기 정지. `node_procs_blocked` 0으로 끝나도 안전 신호 아님. - `dmesg | grep AMD-Vi` 가 새 호스트 도입 시 표준 점검 항목. - 호스트 timezone 통일 — 한국 인프라는 `Asia/Seoul`로 강제. 잘못된 timezone은 인시던트 분석 시 시간대 변환 오류로 잘못된 결론 유도. - **헤임달 1차 진단 "kr2 호스트 자체 다운"은 표면 ssh/incus refused만 보고 결론. 메트릭 시계열·외부 응답까지 교차 검증 안 함.** 다음에 비슷한 진단 시 헤임달이 node-exporter `up`, 외부 nginx 응답 등을 같이 보도록 운영 규칙 보강 검토. ## 관련 문서 - [[amd-vi-iommu]] — AMD-Vi 부분 hang 메커니즘 정본 (왜 일부 프로세스만 죽는가, `iommu=pt`가 왜 해결하는가) - [[infra/compute/hosts/incus-kr2|incus-kr2]] - [[2026-04-04-usb-25g-hang]] — 직전 freeze (USB) - [[infra/compute/infra-hosts]]