kubectl debug가 필요한 이유
프로덕션 컨테이너는 보안을 위해 distroless, scratch 이미지를 사용합니다. 쉘도 없고, curl도 없고, tcpdump도 없습니다. 문제가 발생하면 로그만으로는 한계가 있습니다. kubectl debug는 실행 중인 Pod에 디버그 컨테이너를 주입하거나, 복제본을 만들어 안전하게 트러블슈팅할 수 있는 Kubernetes 네이티브 도구입니다.
Ephemeral Container: 실행 중 Pod에 주입
가장 기본적인 사용법은 실행 중인 Pod에 임시 디버그 컨테이너를 추가하는 것입니다.
# 기본: busybox 셸 주입
kubectl debug -it pod/api-server-7d8f9 --image=busybox -- sh
# 네트워크 디버깅: nicolaka/netshoot (curl, dig, tcpdump, iperf 포함)
kubectl debug -it pod/api-server-7d8f9
--image=nicolaka/netshoot
--target=api-container
-- bash
# 특정 네임스페이스
kubectl debug -it pod/payment-6f4a2 -n production
--image=busybox:1.36 -- sh
- –target: 디버그 컨테이너가 대상 컨테이너의 프로세스 네임스페이스를 공유.
ps aux로 대상 프로세스를 볼 수 있음 - -it: 인터랙티브 TTY 모드
- Ephemeral Container는 Pod spec에 추가되지만, Pod 재시작 없이 주입됨
# 디버그 컨테이너에서 할 수 있는 것들
# 1. 프로세스 확인 (--target 옵션 사용 시)
ps aux
# 2. 네트워크 연결 테스트
curl -v http://user-service.default.svc:3000/health
dig +short redis-master.default.svc.cluster.local
nslookup kubernetes.default
# 3. 패킷 캡처
tcpdump -i eth0 -n port 3000 -w /tmp/capture.pcap
# 4. 파일시스템 확인 (프로세스 네임스페이스 공유 시)
ls /proc/1/root/app/
Pod 복제 디버깅: –copy-to
프로덕션 Pod을 건드리지 않고 복제본을 만들어 디버깅합니다. 가장 안전한 방법입니다.
# Pod 복제 + 디버그 컨테이너 추가
kubectl debug pod/api-server-7d8f9 -it
--copy-to=api-debug
--image=nicolaka/netshoot
--share-processes
-- bash
# 복제 + 컨테이너 이미지 교체 (디버그 도구가 포함된 이미지로)
kubectl debug pod/api-server-7d8f9 -it
--copy-to=api-debug
--set-image=api-container=api-server:debug
-- bash
# 복제 + 커맨드 변경 (크래시 루프 디버깅)
kubectl debug pod/api-server-7d8f9 -it
--copy-to=api-debug
--container=api-container
--set-image=api-container=api-server:latest
-- sh -c "sleep 3600"
- –share-processes: 복제된 Pod 내 모든 컨테이너가 프로세스 네임스페이스 공유
- –set-image: 특정 컨테이너의 이미지를 디버그 버전으로 교체
- 크래시 루프 Pod은
sleep으로 커맨드를 바꿔 컨테이너를 살려놓고 진입
노드 디버깅: 호스트 접근
노드 레벨 문제(디스크, 네트워크, kubelet)를 디버깅할 때 사용합니다.
# 노드에 디버그 Pod 생성 (호스트 파일시스템 마운트)
kubectl debug node/worker-node-1 -it
--image=ubuntu:22.04
-- bash
# 노드 디버그 Pod 내부에서
# 호스트 파일시스템은 /host에 마운트됨
chroot /host
# kubelet 로그 확인
journalctl -u kubelet --since "30min ago"
# 디스크 상태
df -h
du -sh /var/lib/kubelet/pods/*
# 네트워크 상태
iptables -t nat -L -n | head -50
ss -tlnp
# 컨테이너 런타임 상태
crictl ps
crictl logs <container-id>
노드 디버깅 Pod은 hostPID, hostNetwork, 호스트 볼륨 마운트가 자동 설정됩니다. RBAC 권한이 필요하므로 클러스터 관리자 권한이 있어야 합니다.
디버깅 시나리오별 명령어
CrashLoopBackOff 디버깅
# 1. 최근 크래시 로그 확인
kubectl logs pod/api-server --previous
# 2. Pod 복제 후 커맨드를 sleep으로 변경
kubectl debug pod/api-server -it
--copy-to=crash-debug
--container=api
--set-image=api=api-server:latest
-- sh -c "sleep infinity"
# 3. 별도 터미널에서 접속
kubectl exec -it crash-debug -c api -- sh
# 4. 수동으로 앱 실행하여 에러 확인
cd /app && node dist/main.js
# → 에러 메시지 직접 확인
DNS 문제 디버깅
kubectl debug -it pod/api-server
--image=nicolaka/netshoot -- bash
# DNS 조회 테스트
dig +short mysql-primary.database.svc.cluster.local
nslookup kubernetes.default.svc.cluster.local
# DNS 서버 확인
cat /etc/resolv.conf
# CoreDNS Pod 상태
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system -l k8s-app=kube-dns
네트워크 연결 문제 디버깅
kubectl debug -it pod/frontend
--image=nicolaka/netshoot
--target=frontend
-- bash
# TCP 연결 테스트
curl -v --connect-timeout 5 http://api-service:3000/health
# 포트 스캔
nmap -p 3000,5432,6379 api-service.default.svc
# 실시간 패킷 확인
tcpdump -i eth0 host api-service -n
# MTU 문제 확인
ping -M do -s 1472 api-service
메모리·리소스 문제 디버깅
kubectl debug -it pod/api-server
--image=ubuntu:22.04
--target=api
-- bash
# 프로세스 메모리 확인
cat /proc/1/status | grep -i vm
cat /sys/fs/cgroup/memory.current
cat /sys/fs/cgroup/memory.max
# OOMKill 이력
kubectl describe pod api-server | grep -A5 "Last State"
kubectl get events --field-selector reason=OOMKilling
디버그 프로필: 보안 설정 제어
Kubernetes 1.28+에서 --profile 옵션으로 디버그 컨테이너의 보안 수준을 제어합니다.
# general: 기본 프로필 (제한적 권한)
kubectl debug -it pod/api --image=busybox --profile=general -- sh
# baseline: PSA baseline 수준
kubectl debug -it pod/api --image=busybox --profile=baseline -- sh
# restricted: PSA restricted 수준 (가장 제한적)
kubectl debug -it pod/api --image=busybox --profile=restricted -- sh
# netadmin: NET_ADMIN 권한 추가 (tcpdump, iptables 사용 가능)
kubectl debug -it pod/api --image=nicolaka/netshoot
--profile=netadmin -- bash
# sysadmin: 모든 권한 + hostPID (노드 수준 디버깅)
kubectl debug -it pod/api --image=ubuntu
--profile=sysadmin -- bash
| 프로필 | 권한 | 용도 |
|---|---|---|
general |
기본 | 파일 확인, 환경변수 조회 |
baseline |
PSA baseline | 일반적인 앱 디버깅 |
netadmin |
NET_ADMIN | tcpdump, iptables, 네트워크 디버깅 |
sysadmin |
privileged | 노드·커널 레벨 디버깅 |
정리 및 운영 팁
- 디버그 Pod은 작업 완료 후 반드시 삭제:
kubectl delete pod api-debug - Ephemeral Container는 Pod 삭제 시 자동 정리됨
- 프로덕션에서는
--copy-to로 복제본 디버깅을 우선 사용 - 디버그용 이미지를 내부 레지스트리에 미리 캐시해두면 시작 속도 향상
- RBAC으로
kubectl debug권한을 제한하여 프로덕션 접근 통제
관련 글
- K8s Ephemeral Container 디버깅 — 임시 컨테이너의 내부 동작과 제약사항
- K8s Pod Probe 헬스체크 전략 — Liveness·Readiness·Startup Probe 설정과 트러블슈팅