K8s Ephemeral Container 디버깅

Ephemeral Container란?

Kubernetes 1.25에서 GA(정식 릴리스)된 Ephemeral Container는 이미 실행 중인 Pod에 임시 디버그 컨테이너를 주입하는 기능이다. Distroless 이미지나 최소 이미지로 빌드된 프로덕션 Pod에는 sh, curl, strace 같은 디버깅 도구가 없다. Ephemeral Container는 이 문제를 Pod 재시작 없이 해결한다.

기존 디버깅의 한계

Ephemeral Container 이전에는 두 가지 방법밖에 없었다.

  • kubectl exec — 컨테이너 이미지에 셸이 없으면 실패
  • Pod 재배포 — 디버그 사이드카를 추가해 재시작하면 재현 상태가 사라짐

Ephemeral Container는 pod.spec.ephemeralContainers 필드를 통해 런타임에 컨테이너를 추가하므로 기존 프로세스에 전혀 영향을 주지 않는다.

기본 사용법: kubectl debug

# 실행 중인 Pod에 busybox 디버그 컨테이너 주입
kubectl debug -it my-pod --image=busybox:1.36 --target=app-container

# nicolaka/netshoot으로 네트워크 디버깅
kubectl debug -it my-pod --image=nicolaka/netshoot --target=app-container

--target 플래그는 해당 컨테이너의 프로세스 네임스페이스를 공유한다. 이를 통해 Ephemeral Container에서 대상 컨테이너의 프로세스를 ps로 확인하고 /proc 파일시스템에 접근할 수 있다.

프로세스 네임스페이스 공유 심화

shareProcessNamespace: true가 Pod 스펙에 설정되어 있으면 --target 없이도 모든 컨테이너의 프로세스가 보인다. 하지만 프로덕션 환경에서는 보안상 이를 비활성화하는 경우가 많으므로, --target을 명시하는 것이 안전하다.

# --target으로 PID 네임스페이스 공유 후 strace 사용
kubectl debug -it my-pod --image=ubuntu:22.04 --target=app-container -- bash

# Ephemeral Container 내부에서
apt update && apt install -y strace
strace -p 1  # 대상 컨테이너의 PID 1 추적

Node-Level 디버깅: 호스트 접근

Ephemeral Container의 또 다른 강력한 패턴은 노드 디버깅이다.

# 노드에 디버그 Pod 생성 (호스트 파일시스템 /host에 마운트)
kubectl debug node/worker-01 -it --image=ubuntu:22.04

# 호스트 파일시스템 접근
chroot /host
journalctl -u kubelet --since "10 min ago"
crictl ps

이 방식은 SSH 없이 노드의 kubelet 로그, 컨테이너 런타임 상태, 네트워크 설정을 점검할 수 있어 보안 정책이 엄격한 환경에서 유용하다.

실전 디버깅 시나리오 5가지

1. Distroless 앱 메모리 덤프

kubectl debug -it my-java-pod --image=eclipse-temurin:21-jdk --target=app -- bash
# jmap으로 힙 덤프
jmap -dump:format=b,file=/tmp/heap.hprof 1
# kubectl cp로 로컬에 복사
kubectl cp my-java-pod:/tmp/heap.hprof ./heap.hprof -c debugger

2. 네트워크 연결 문제 진단

kubectl debug -it my-pod --image=nicolaka/netshoot --target=app -- bash
# DNS 확인
nslookup my-service.default.svc.cluster.local
# TCP 연결 테스트
curl -v telnet://db-service:5432
# 패킷 캡처
tcpdump -i eth0 -w /tmp/capture.pcap port 443

3. 파일시스템 점검 (읽기 전용 컨테이너)

kubectl debug -it my-pod --image=busybox --target=app -- sh
# /proc/1/root로 대상 컨테이너의 파일시스템 접근
ls /proc/1/root/app/config/
cat /proc/1/root/app/config/application.yaml

4. Go 프로파일링 (pprof)

kubectl debug -it my-go-pod --image=golang:1.22 --target=app -- bash
# 대상 컨테이너가 :6060/debug/pprof를 노출한 경우
go tool pprof http://localhost:6060/debug/pprof/goroutine

5. CrashLoopBackOff 분석

# Pod 복제본을 entrypoint 변경하여 생성
kubectl debug my-crash-pod -it --copy-to=debug-pod --container=app 
  --image=my-app:latest -- sh

# 원래 entrypoint를 수동 실행하며 에러 확인
/app/start.sh

보안 제어: RBAC과 SecurityContext

Ephemeral Container는 강력한 만큼 RBAC으로 접근을 제한해야 한다.

# Ephemeral Container 사용을 허용하는 ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: ephemeral-debug
rules:
- apiGroups: [""]
  resources: ["pods/ephemeralcontainers"]
  verbs: ["patch"]
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get"]

프로덕션에서는 SRE/DevOps 팀에만 이 권한을 부여하고, ValidatingAdmissionPolicy로 허용 이미지를 화이트리스트로 관리하는 것이 권장된다.

Ephemeral Container vs kubectl debug –copy-to

비교 항목 Ephemeral Container –copy-to (Pod 복제)
원본 Pod 영향 없음 (주입만) 없음 (복제본 생성)
장애 상태 보존 ✅ 실시간 상태 접근 ❌ 새 Pod이므로 상태 리셋
네트워크 컨텍스트 동일 Pod IP 새 Pod IP 할당
주요 용도 라이브 디버깅 CrashLoop 분석, entrypoint 변경

운영 팁과 주의사항

  • Ephemeral Container는 삭제 불가 — 한번 추가되면 Pod이 종료될 때까지 pod.spec.ephemeralContainers에 기록이 남는다. 민감 이미지를 사용했다면 감사 로그를 확인하라.
  • 리소스 제한 설정 — Ephemeral Container에도 resources.limits를 설정할 수 있다. 프로덕션 Pod의 리소스를 잡아먹지 않도록 반드시 제한을 건다.
  • 볼륨 마운트 불가 — Ephemeral Container는 기존 Pod의 볼륨을 마운트할 수 없다. 파일시스템 접근은 /proc/<PID>/root를 통해야 한다.
  • 감사 로그 활성화ServiceAccount 토큰 보안과 함께 Audit Policy에서 pods/ephemeralcontainers 리소스를 RequestResponse 수준으로 기록하라.

커스텀 디버그 이미지 만들기

매번 apt install하는 대신 팀 전용 디버그 이미지를 미리 빌드해두면 효율적이다.

# Dockerfile.debug
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y --no-install-recommends 
    curl wget dnsutils netcat-openbsd tcpdump strace 
    htop jq vim-tiny procps iproute2 
 && rm -rf /var/lib/apt/lists/*
CMD ["sleep", "infinity"]
docker build -t registry.internal/debug-toolkit:latest -f Dockerfile.debug .
docker push registry.internal/debug-toolkit:latest

# 사용
kubectl debug -it my-pod --image=registry.internal/debug-toolkit:latest --target=app

정리

Ephemeral Container는 프로덕션 Kubernetes 환경에서 라이브 디버깅의 표준 도구다. Distroless 이미지 채택이 늘면서 그 중요성은 더 커지고 있다. 핵심은 세 가지다.

  1. --target으로 프로세스 네임스페이스를 공유해 PID 1에 접근
  2. RBAC과 Admission Policy로 프로덕션 사용을 통제
  3. 팀 전용 디버그 이미지를 사전 빌드하여 시간 절약

Pod 재시작 없이, SSH 없이, 장애 상태를 그대로 보존하면서 디버깅하는 것 — 이것이 Ephemeral Container의 핵심 가치다.

위로 스크롤
WordPress Appliance - Powered by TurnKey Linux