kubectl debug로 Kubernetes Pod 트러블슈팅 완전 정복
운영 환경에서 Pod가 CrashLoopBackOff에 빠지거나, 네트워크 연결이 안 되거나, 파일시스템 상태를 확인해야 할 때가 있습니다. 문제는 대부분의 프로덕션 컨테이너 이미지에는 curl, dig, netstat 같은 디버깅 도구가 없다는 것입니다.
distroless 이미지나 최소화된 Alpine 기반 이미지를 사용하면 보안과 이미지 크기 면에서 이점이 있지만, 장애 상황에서 원인을 파악하기가 까다로워집니다. kubectl debug는 이런 상황을 위해 만들어진 도구입니다.
이 글에서는 kubectl debug의 세 가지 모드를 실전 예제와 함께 살펴보겠습니다.
Ephemeral Container로 실행 중인 Pod 디버깅
가장 많이 쓰이는 패턴입니다. 실행 중인 Pod에 임시 컨테이너(Ephemeral Container)를 붙여서 디버깅 도구가 포함된 셸을 얻습니다.
# 실행 중인 Pod에 디버그 컨테이너 붙이기
kubectl debug -it my-app-pod-7f8b9c --image=nicolaka/netshoot --target=my-app -- bash
# 네트워크 연결 확인
curl -v http://backend-svc:8080/health
# DNS 확인
dig backend-svc.default.svc.cluster.local
# TCP 연결 상태 확인
ss -tnp
--target 플래그는 디버그 컨테이너가 대상 컨테이너의 프로세스 네임스페이스를 공유하도록 합니다. 이를 통해 ps aux로 대상 컨테이너의 프로세스를 직접 확인할 수 있습니다.
# 대상 컨테이너의 프로세스 목록 확인
ps aux
# 특정 프로세스의 환경변수 확인
cat /proc/1/environ | tr '\0' '\n'
# 파일 디스크립터 확인 (연결 누수 탐지)
ls -la /proc/1/fd | wc -l
Pod 복제 후 디버깅
CrashLoopBackOff 상태라서 컨테이너가 바로 종료되는 경우, 실행 중인 Pod에 붙는 것이 불가능합니다. 이때 Pod를 복제하면서 커맨드를 변경해 셸로 진입할 수 있습니다.
# Pod 복제 + 엔트리포인트를 셸로 변경
kubectl debug my-app-pod-7f8b9c -it --copy-to=debug-pod --container=my-app -- sh
# 원래 이미지 대신 디버깅 도구가 있는 이미지로 교체
kubectl debug my-app-pod-7f8b9c -it --copy-to=debug-pod \
--set-image=my-app=ubuntu:22.04 -- bash
복제된 Pod는 원본 Pod의 모든 설정(환경변수, 볼륨 마운트, 리소스 제한 등)을 그대로 가져옵니다. 환경변수나 시크릿 마운트 문제를 확인하기에 적합합니다.
# 환경변수 확인
env | grep DB_
# 마운트된 시크릿/컨피그맵 확인
ls -la /etc/config/
cat /etc/config/application.yaml
노드 디버깅
Pod가 아니라 노드 자체에 문제가 의심될 때 사용합니다. 노드의 파일시스템에 접근하여 kubelet 로그, 디스크 상태, 네트워크 설정 등을 확인할 수 있습니다.
# 노드에 디버그 Pod 생성
kubectl debug node/worker-node-01 -it --image=ubuntu:22.04
# 호스트 파일시스템은 /host에 마운트됨
chroot /host
# kubelet 로그 확인
journalctl -u kubelet --since "30 minutes ago" --no-pager | tail -50
# 디스크 사용량 확인
df -h
# iptables 규칙 확인
iptables -t nat -L KUBE-SERVICES | head -20
주의사항 및 베스트 프랙티스
RBAC 설정을 반드시 제한하세요. kubectl debug는 강력한 도구이므로 프로덕션 클러스터에서는 특정 Role에만 허용해야 합니다.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: debugger
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["pods/ephemeralcontainers"]
verbs: ["patch"]
디버그 Pod 정리를 잊지 마세요. --copy-to로 생성한 Pod는 자동 삭제되지 않습니다. 작업 후 반드시 삭제하세요.
# 디버그 Pod 정리
kubectl delete pod debug-pod
디버깅 이미지를 표준화하세요. 팀 전용 디버깅 이미지를 만들어 내부 레지스트리에 올려두면 일관된 도구 세트로 빠르게 대응할 수 있습니다. nicolaka/netshoot은 네트워크 디버깅에 좋고, busybox는 가볍지만 도구가 제한적입니다.
마무리
kubectl debug의 세 가지 모드를 정리하면 다음과 같습니다. 실행 중인 Pod에는 Ephemeral Container를, 크래시 상태의 Pod에는 복제 모드를, 노드 문제에는 노드 디버깅을 사용합니다. distroless 이미지를 쓰더라도 운영 중 트러블슈팅에 지장이 없도록, 이 세 가지 패턴을 팀 런북에 추가해두는 것을 권장합니다.
추가 리소스: