심심한 개발자의 취미생활

docker 경량 컨테이너 베이스 비교 (alpine vs slim vs scratch)

컨테이너 이미지를 제작할때 베이스 이미지로 다양한 이미지를 사용한다. 그중 상황과 기능에 따라 이미지의 용량을 줄이기 위해 경량 이미지를 찾아 사용하는데 대표적으로 alpine, slim, scratch 버전의 이미지들을 많이 사용한다. 본 포스팅에서는 alpine, slim, scratch 이 세 이미지 버전에 대하여 어떤 상황에 사용해야 하는게 좋은지 장단점에 대하여 비교해 본다.

Alpine

  • Alpine 버전은 alpine linux 기반으로 제작된 이미지이다. Alpine linux 자체가 '작고', '보안이 뛰어나고', '간담함'을 목적으로 만들어진 배포판으로 타 리눅스 배포판 보다 훨씬 가볍고 깔끔한 것이 장점이기 때문에 Docker 컨테이너에 사용되는 예가 많다.

장점 / 단점

  • 장점

    • 이미지 크기가 매우 작아서 빌드/배포 속도가 빠름
    • 패키지 매니저(apk) 사용 가능
    • 경량 시스템의 특성상 보안 취약점이 적음
  • 단점

    • glibc가 아니라 musl 기반으로 일부 라이브러리 호환성 이슈가 있음
    • 디버깅 도구, 쉘 등이 부족하여 작업에 어려움이 있을수 있음

예시

FROM node:alpine
FROM python:3.11-alpine

Slim

  • Slim은 Debian 또는 Ubuntu 등 기본 이미지에서 불필요한 패키지를 제거한 경량 버전으로 기존 리눅스 배포판의 기존 기능을 최대한 유지한채 용량만 줄인 버전이다. 특수 목적이 아닌 일반 리눅스 배포판을 경량화 한 버전이기에 glibc 기반으로 라이브러리 호환성이 좋고 기본 디버깅 도구와 라이브러리 사용이 가능하다.

장점 / 단점

  • 장점

    • glibc 기반으로 라이브러리 호환성이 뛰어남
    • 기본 디버깅 도구, 라이브러리 사용 가능
    • Alpine 보다 호환성과 안정성 중시
  • 단점

    • 경량화 버전이긴 하나 경량화를 목적으로 만들어진 Alpine보다는 무거움
    • 완전한 최소 이미지는 아님

예시

FROM node:18-slim
FROM python:3.11-slim

Scratch

  • Scratch는 도커에서 제공하는 정말 아무것도 없는 빈(empty) 베이스 이미지이다. FROM scratch라고 명시하면 그 이후에는 아무것도 포함되지 않은 상태에서 이미지가 생성된다.

사용

  • Scratch는 아무런 기능이 없는 빈 이미지 이기에 장단점이라고 할만한 것 자체가 없는데 이러한 Scratch를 사용하는 이유는 극단적으로 작고 안전한 컨테이너 이미지를 생성하여 정적 바이너리 프로그램만을 실행하기 위한 컨테이너를 생성하기 위해 사용된다.

  • 장점 이자 단점

    • 극단적으로 적은 용량의 이미지 제작 가능
    • 실행 환경에 의존하지 않는 서비스 배포 가능
    • 쉘, 로그, 디버깅 툴이 없어 디버깅에 대한 분석이 어려움
    • 리눅스 베포판과 같이 기본적인 기능 조차 없어 동적 라이브러리가 필요한 경우 실행이 불가
    • apt, apk, yum 과 같은 패키지 설치 툴이 전혀 없음
    • 환경 변수나 기본 경로 역시 없어 필요시 직접 제작 생성해야 함

예시

FROM scratch

Alpine vs Slim vs Scratch

Alpine Slim Scratch
용량 매우 작음(약 5MB) 작은 편(20~40MB) 0MB
기본 유틸 최소 제공(apk, 쉘 등) 대부분 제공 없음
패키지 설치 apk apt 불가
디버깅 어려움 가능 불가
사용 예 경량 이미지가 필요한 경우 경량 + 호환성이 필요한 경우 정적 빌드 실행, 보안/최소 크기가 필요한 경우
Alpine 이미지 크기를 줄이고, 패키지 호환성이 큰 이슈가 아닐 경우
Slim 이미지 크기는 줄이되, glibc와의 호환성 등 안정성도 필요한 경우
Scratch Go, Rust 등 정적 링크된 바이너리를 최종적으로 실행할 경우