Distroless 컨테이너 이미지는 빠르고 안전하며 운영 환경에 최적화되어 있지만, 디버깅할 때는 악몽이 될 수 있습니다.
이 글에서는 Distroless 컨테이너 이미지가 왜 강력한지, 왜 디버깅이 어려운지, 그리고 Kubernetes에서 Ephemeral Container를 활용해 애플리케이션을 재시작하지 않고도 실시간으로 디버깅을 단순하게 만드는 방법을 다룹니다.
Distroless 이미지란 무엇인가?
Distroless 컨테이너는 Ubuntu나 Alpine 같은 리눅스 배포판을 포함하지 않는 Docker 이미지입니다. 오직 다음만 담고 있습니다:
- 애플리케이션
- 런타임 (예: Java, Node.js, Go)
빠진 것은 무엇일까요?
- 쉘(sh, bash) 없음
- 패키지 관리자(apt, apk) 없음
- 디버그 도구(curl, ping, ps 등) 없음
왜 Distroless 이미지를 사용할까?
Distroless 이미지는 보안, 성능, 단순성을 위해 설계되었으며, 운영 환경에서 권장되는 이유는 다음과 같습니다:
- 작은 Docker 이미지 크기로 인해 다운로드와 배포가 빨라지고, 네트워크 및 스토리지 비용을 절감해 클라우드 인프라 비용을 줄여줍니다.
- 불필요한 바이너리와 라이브러리를 최소화하여 공격 표면(Attack Surface)을 줄입니다.
- 쉘 접근 자체가 불가능하기 때문에 누군가 컨테이너 내부로 exec 진입하는 것을 원천 차단합니다.
디버깅의 딜레마
Distroless 컨테이너 이미지에서 Node.js 앱이 실행 중인데 500 오류를 쏟아내고 있다고 가정해봅시다. 문제를 디버깅하기 위해 다음과 같은 시도를 해봤습니다:-
kubectl exec -it my-production-application -- sh
하지만 다음과 같은 오류 메시지가 발생합니다:-
error: unable to upgrade connection: container not found or shell not available
왜일까요? 컨테이너 안에 셸이 없기 때문입니다! 따라서 ps, curl, netstat 같은 명령은 물론, 운영 환경의 오류를 디버깅하는 데 유용한 어떤 도구도 실행할 수 없습니다.
해결책: Kubernetes의 Ephemeral Containers
Kubernetes의 Ephemeral Container를 사용하면 애플리케이션을 중지하거나, 다시 빌드하거나, 재시작하지 않고도 실행 중인 Pod에 임시 디버그 컨테이너를 주입하여 애플리케이션 Pod의 오류를 디버깅할 수 있습니다.
단계별 진행 방법:-
- Distroless 컨테이너 이미지를 사용해 샘플 애플리케이션 Pod 생성하기
# app using distroless
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
containers:
- name: app
image: gcr.io/distroless/static
command: ["sleep", "3600"]
적용 명령어:
kubectl apply -f my-app.yaml
- 디버그 컨테이너 주입하기
kubectl debug -it my-app \
--target=app \
--image=busybox \
--name=debugger
이제 busybox 컨테이너 내부에 들어가게 되며, 이 컨테이너는 애플리케이션 Pod와 네트워크, 프로세스, IPC 네임스페이스를 공유합니다. 이를 통해 애플리케이션 문제를 디버깅할 수 있습니다.
- 디버깅 명령 실행 예시
ps # nginx 컨테이너 네임스페이스에서 실행 중인 프로세스 확인
ls / # 파일 시스템 탐색
cat /etc/hosts # 네트워킹 설정 확인
ping 8.8.8.8 # 외부 연결 테스트
wget <url> # 지원되는 경우 다운로드 테스트
이 모든 과정을 거쳐도 애플리케이션은 재시작 없이 계속 정상적으로 실행됩니다.
요약
Distroless 컨테이너는 운영 환경에서 사실상 표준이라 할 수 있습니다. 빠르고, 안전하며, 최소한의 구성으로 되어 있습니다. 하지만 문제가 발생했을 때는 셸이나 디버깅 도구가 없어 아무것도 보이지 않는 상황에 놓이게 됩니다. 이때 빛을 발하는 것이 바로 Ephemeral Container입니다.
- 애플리케이션 재시작 불필요
- 다운타임 없음
- Pod 내부를 완전히 들여다볼 수 있는 가시성 제공
따라서 다음번에 Distroless 컨테이너를 마주하게 된다면 굳이 이미지를 다시 빌드하지 말고, 단순히 Ephemeral Container를 사용해 디버깅하세요.
완전한 소스 코드는 제 GitHub 저장소에서 확인하실 수 있습니다. 언제든지 포크해서 더 많은 IaC(Infrastructure as Code)를 기여해 주셔도 좋습니다.

