IT/Kubernets

distroless 컨테이너, kubectl debug 없으면 진짜 답 없다

gfrog 2026. 8. 27. 09:13

오늘 알게 된 건데, 이거 모르는 분 꽤 많더라. 아니 정확히는 알긴 아는데 실제로 프로덕션에서 써본 적 없는 분들. 나도 얼마 전까지 그러다.

distroless 이미지 쓰는 서비스에서 이슈가 났다. 컨테이너 내부에서 curl 한 번만 때려보고 싶은데 kubectl exec -it pod -- sh 하면 당연히 sh: no such file or directory. 그렇다고 이미지를 alpine 기반으로 다시 말아 재배포? 프로덕션에서 그건 좀. 그럴 때 kubectl debug가 답이다.

기본 사용법

kubectl debug -it my-app-pod \
  --image=busybox:1.36 \
  --target=app \
  -- sh

--target=app이 핵심이다. 대상 컨테이너의 프로세스 네임스페이스를 공유해서 ps aux로 앱 프로세스가 보이고, /proc/<pid>/ 를 통해 파일 디스크립터, 네트워크 소켓, 환경변수까지 다 뜯어볼 수 있다. 앱 컨테이너에 아무것도 설치하지 않고도.

여기서 하나 짚고 넘어가면, --target을 안 붙이면 별개 네임스페이스로 뜨기 때문에 그냥 같은 파드 안에서 사이드카 하나 붙는 수준밖에 안 된다. 프로세스가 안 보인다. 이거 처음에 몰라서 삽질 좀 했다.

조금 더 실무적으로

디버깅용으로 나는 요즘 이 이미지를 쓴다.

kubectl debug -it my-app-pod \
  --image=nicolaka/netshoot:latest \
  --target=app \
  --profile=netadmin

nicolaka/netshoot은 tcpdump, dig, curl, iproute2, mtr, ss 다 들어있는 네트워크 디버깅 만능 이미지다. 그리고 --profile=netadmin이 1.30에서 stable로 넘어왔는데, NET_ADMIN, NET_RAW capability를 자동으로 붙여준다. 이거 없으면 tcpdump가 권한 없다고 뻗는다.

프로파일은 몇 가지가 있는데 자주 쓰는 건 이 정도.

  • legacy: 아무것도 안 붙는 기본값
  • general: SYS_PTRACE 붙여줌. strace 뜰 때 필요
  • netadmin: 네트워크 디버깅용
  • sysadmin: 거의 다 붙여줌. 위험하니 정말 필요할 때만

노드 디버깅에도 쓸 수 있다

이것도 실무에서 은근 자주 쓰는데, 노드 자체가 이상할 때.

kubectl debug node/ip-10-0-1-42.ap-northeast-2.compute.internal \
  -it --image=nicolaka/netshoot

호스트의 파일시스템이 /host 아래 마운트돼서 뜬다. 노드에 SSH 뚫려있지 않은 EKS 노드에서 /var/log/containers/ 뒤져볼 때 편하다. 특히 최근에 EKS AMI가 Bottlerocket으로 바뀐 클러스터에서는 SSH가 아예 없기 때문에 이 방법이 사실상 유일한 옵션이다.

주의할 점 하나

kubectl debug로 붙인 ephemeral container는 파드가 재시작되면 사라진다. 그래서 파드가 CrashLoopBackOff 상태로 계속 죽고 있다면 debug 컨테이너도 같이 죽어서 아무것도 못 본다. 이럴 때는 --copy-to=my-app-debug --set-image='*=busybox' 옵션으로 파드를 통째로 복사해서 이미지를 바꿔 띄우는 방법이 있다. 원본은 안 건드리고.

kubectl debug my-app-pod \
  --copy-to=my-app-debug \
  --container=app \
  --image=busybox:1.36 \
  -it -- sh

복사본이니까 서비스 셀렉터에 매칭되면 트래픽이 들어올 수 있는데, label만 살짝 바꿔서 뜨게 하려면 --copy-to=my-app-debug --set-labels='app=debug'로 뜨거나, 애초에 --copy-to가 라벨을 복사하지만 앞에 붙일 수도 있으니 상황 봐서 조정하면 된다.

마무리

정리하면 프로덕션에서 distroless 이미지 디버깅할 때 순서는 대충 이렇다.

  1. 우선 kubectl debug -it --target=app --profile=netadmin --image=nicolaka/netshoot 로 붙어본다
  2. 프로세스가 이미 죽었거나 CrashLoop이면 --copy-to로 복제 파드를 띄운다
  3. 노드 레벨이면 kubectl debug node/<name>로 호스트 파일시스템에 접근

이거 하나만 익혀두면 distroless 쓴다고 겁먹을 이유가 없다. 오히려 shell 없는 이미지가 보안상으로도 낫고, 디버깅은 필요할 때만 필요한 도구가 붙어서 뜨니까 훨씬 깔끔하다.

혹시 다른 디버깅 이미지 쓰시는 분 있으면 뭐 쓰시는지 궁금하다. 최근에 팀 내부에서도 netshoot 말고 자체 이미지 하나 말자는 얘기가 나오는데, 아직 결론은 못 냈다.

#kubernetes #k8s #debugging #distroless #devops #실무