컨테이너 용어 사전
보안alpine · distroless · scratch · slim

베이스 이미지

작을수록 취약점도 적다. 다만 alpine의 musl, distroless의 디버깅 제약을 함께 본다.

  • full (debian · ubuntu) — 수백 MB. 도구가 다 있다. 디버깅이 쉽다
  • slim — 불필요한 패키지를 뺀 것. 대부분 여기서 시작한다
  • alpine — 약 5~8MB. musl libc · busybox
  • distroless — 셸도 패키지 매니저도 없다. 런타임만
  • scratch — 아무것도 없다. 정적 바이너리 전용

작은 것이 왜 중요한가

  • 배포가 빨라진다 — 노드마다 pull 해야 한다

    • 오토스케일링에서 파드가 뜨는 시간에 직접 들어간다
  • 취약점이 준다 — 안 쓰는 패키지도 CVE 를 갖는다

  • 공격 표면이 준다 — 셸·컴파일러가 있으면 침투 후 할 수 있는 일이 많다

  • 크기 줄이기와 보안 강화는 대부분 같은 작업이다

alpine 은 만능이 아니다

  • 장점 매우 작다

  • 주의

    • musl libc 를 쓴다 — glibc 로 빌드한 바이너리가 안 돈다
      • 증상: "not found" 인데 파일은 있다 (동적 링커를 못 찾는 것)
    • DNS 해석 동작이 glibc 와 미묘하게 다르다
    • 언어 런타임에 따라 성능 차이가 보고된 사례가 있다
      • (musl 의 메모리 할당자 특성)
  • '작다' 만 보고 고르지 않는다. 런타임과의 궁합을 확인한다

  • 자바처럼 JRE 를 얹는 경우는 slim 계열이 무난하다

distroless·scratch 의 트레이드오프

  • 얻는 것 — 셸·패키지 매니저가 없다 → 침투해도 할 수 있는 것이 거의 없다

    • 이미지가 작다. 스캔 결과가 깨끗하다
  • 잃는 것 — docker exec 로 들어갈 수 없다

    • curl·ps 같은 진단 도구가 없다

대응 — 네임스페이스를 공유하는 임시 컨테이너로 디버깅한다

  • docker run --rm -it --pid=container:web --network=container:web \
    • nicolaka/netshoot sh
  • kubectl debug -it pod/web --image=nicolaka/netshoot --target=web

디버깅 경로를 먼저 갖춘 뒤에 옮기는 것이 순서다

크기를 줄이는 순서

  • 멀티스테이지 — 가장 효과가 크다. 빌드 도구를 통째로 뺀다
  • 베이스 교체 — full → slim → alpine/distroless
  • 레이어 정리 — 설치와 정리를 같은 RUN 에
  • .dockerignore — 빌드 컨텍스트에서 불필요한 것 제외
  • 언어별 기법 — 자바 jlink · Go 정적 빌드 · Node 프로덕션 의존만
RUN apt-get update \
 && apt-get install -y --no-install-recommends curl ca-certificates \
 && rm -rf /var/lib/apt/lists/*

--no-install-recommends 만으로도 수십~수백 MB 가 준다 apt 인덱스를 안 지우면 이미지에 그대로 남는다 다음 레이어에서 지우면 소용없다 (삭제는 표식일 뿐)

업데이트 전략

베이스 이미지는 '한 번 고르고 끝' 이 아니다 새 CVE 가 나오면 베이스를 올려 다시 빌드해야 한다

  • FROM 태그를 마이너 버전까지만 고정한다 (node:22-alpine)
    • 패치는 자동으로 따라온다
  • 주기적으로 --pull 로 다시 빌드한다 (주 1회 정도)
  • 재빌드 후 스캔 결과를 비교한다

태그를 다이제스트로 완전히 고정하면 재현성은 최고지만 보안 패치를 놓친다 → 자동 갱신 도구(Renovate 류)와 함께 쓴다

조직 표준 베이스

팀마다 다른 베이스를 쓰면

  • 노드마다 레이어가 중복 저장된다
  • 취약점 대응을 곳곳에서 따로 한다
  • 보안 설정(비루트 사용자 · CA 인증서 · 타임존)이 제각각이다

내부 베이스 이미지를 하나 만들어 두면 이 셋이 한 번에 정리된다

  • FROM company/java-base:21 그 위에 애플리케이션만 얹는다

면접 함정

  • "alpine이 항상 정답" → musl 궁합과 런타임 특성을 확인해야 한다.
  • "distroless가 무조건 안전하고 좋다" → 디버깅 경로가 없으면 장애 대응이 막힌다.

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 이미지 크기와 보안 — 같은 문제의 두 얼굴