Files
obsidian/history/2026-05-20-kr2-multus-shim-etxtbsy.md
kaffa 5be51134c9 incus-hp1 storage-net 참여 사실 반영 + kr2 multus-shim ETXTBSY 인시던트 기록
- infra-hosts.md: hp1 행 갱신 (이전 "1GbE only" → 2.5G 192.168.205.227, MAC 20:e1:5d:6a:2b:2e, MTU 9000 JF OK), 2.5G 표 hp1 행 추가, NAS NIC 정보(USB cdc_ncm → r8152 RTL8157 chip rev 14 + MAC)로 정확화, 호스트 자원 표에 hp1 추가, SSH 정보 라인에 hp1 접근 한계 명시
- nas-storage.md: K3s 노드 표 3→4 노드로 갱신 (hp1 추가), nodeAffinity 설명 표현 갱신
- history/2026-05-20-kr2-multus-shim-etxtbsy.md: ETXTBSY 데드락 RCA 및 `rm /opt/cni/bin/multus-shim` 회피책 기록
2026-05-20 17:10:07 +09:00

4.5 KiB
Raw Permalink Blame History

date, topic, areas
date topic areas
2026-05-20 kr2 multus-shim ETXTBSY 데드락 — k3s 재시작 후 CNI 복구 불가
infra/compute/infra-hosts
infra/platform

2026-05-20 / kr2 multus-shim ETXTBSY 데드락

증상

/sc:test 와 무관, NAS NFS 점검 중 발견. kr2 노드는 K8s Ready 인데 노드 위 Pod 8개가 stuck:

  • Unknown: traefik, kube-multus-ds, kube-system/descheduler, vector, longhorn-manager / longhorn-csi-plugin / engine-image
  • ContainerCreating 장시간 (1629h): critical-backup, critical-snapshot, descheduler

kubelet 에러:

plugin type="multus-shim" name="multus-cni-network" failed (add):
CmdAdd (shim): timed out waiting for the condition

데드락 구조

  1. 2026-05-19 11:11:59 KST kr2 k3s.service 재시작 직후 kube-multus-ds Pod이 init 단계에서 깨끗하게 복구 안 됨.
  2. install-multus-binary initContainer 가 cp/host/opt/cni/bin/multus-shim 갱신 시도 → cp: cannot create regular file '/host/opt/cni/bin/multus-shim': Text file busy (ETXTBSY).
  3. ETXTBSY 원인: kubelet 이 stuck Pod sandbox 재생성 시도 → /opt/cni/bin/multus-shim 을 자식 프로세스로 spawn → multus daemon socket 부재로 RPC hang → shim 프로세스가 inode 잡은 채로 매달림.
  4. shim 누적 (관찰 시 8 → 14 → 매달림 지속). cp 는 영원히 fail. multus daemon 영원히 안 뜸. 완전한 데드락.
  5. pkill -9 multus-shim, fuser -k 모두 즉시 새 shim 이 spawn 되어 효과 없음. systemctl restart k3s 도 마찬가지 — 재시작 후 kubelet 이 sandbox cleanup retry 하면서 shim 다시 누적.

해결 키

sudo rm /opt/cni/bin/multus-shim

unlink(2) 는 매달린 프로세스의 fd 가 잡고 있는 inode 를 보존한 채 path 만 제거. 다음 install-multus-binary retry 의 cpfresh inode 로 새 파일 생성 → ETXTBSY 회피 → multus daemon 정상 기동 → 매달린 shim 들이 응답 받고 자연 종료.

복구 절차 (실제 수행)

# 1. stuck pod force delete (kubelet retry 루프 끊기)
kubectl delete pod --force --grace-period=0 -n kube-system descheduler-* traefik-*
kubectl delete pod --force --grace-period=0 -n logging vector-*
kubectl delete pod --force --grace-period=0 -n longhorn-system \
  critical-{backup,snapshot}-* engine-image-* longhorn-{csi-plugin,manager}-*

# 2. kr2 호스트에서 multus-shim 파일 unlink (핵심)
ssh kaffa@kr2 'sudo rm /opt/cni/bin/multus-shim'

# 3. multus DS pod 재생성 → backoff 카운터 리셋
kubectl delete pod -n kube-system kube-multus-ds-<crashing-pod> --force --grace-period=0

3분 내 모든 stuck Pod 정상화. 잔여 shim 0개 자동 정리. instance-manager 등 cascade로 띄워지는 Pod도 자동 복구.

검증

NAMESPACE         NAME                  READY   STATUS      RESTARTS  AGE
kube-system       kube-multus-ds-9lxxn  1/1     Running     0         29s
kube-system       traefik-kjts5         1/1     Running     0         3m10s
kube-system       descheduler-...       0/1     Completed   0         3m10s
logging           vector-rc6ph          1/1     Running     0         3m9s
longhorn-system   engine-image-...      1/1     Running     0         3m9s
longhorn-system   instance-manager-...  1/1     Running     0         43s
longhorn-system   longhorn-csi-plugin-* 3/3     Running     0         3m9s
longhorn-system   longhorn-manager-*    2/2     Running     0         3m9s
longhorn-system   critical-snapshot-*   0/1     Completed   0         3m8s

전 클러스터 비정상 Pod 0개. 4 노드 모두 Ready.

교훈

  • ETXTBSY 데드락 패턴: CNI plugin daemon이 정상 socket을 listen하지 않으면 kubelet retry가 shim을 누적 spawn → 바이너리 갱신 불가. 같은 패턴은 calico, cilium 등 다른 CNI 에서도 발생 가능.
  • rm 으로 unlink → fresh inode 가 표준 회피책. pkill / fuser -k / 데몬 재시작 모두 retry 루프 못 끊음.
  • 재발 방지: kr2 k3s 재시작 시 kube-multus-ds 가 다시 init 단계에서 깨질 수 있음. 재시작 직후 60초 안에 multus DS Pod 상태 확인하고 backoff 회수가 빠르게 늘면 즉시 위 절차 적용.
  • 발견 경위: NAS NFS 연결 점검 중 kubectl get pods -A 부수 확인에서 우연히 노출. NFS 점검과 인과 무관.

관련 문서