이미지 마운트

이미지 마운트

볼륨(Volumes), 바인드 마운트(bind mounts), tmpfs 마운트는 모두 컨테이너에 데이터를 읽고 쓸 수 있는 공간을 제공해요. 그런데 이미지 마운트는 조금 달라요. 디렉터리나 메모리 기반 파일시스템을 마운트하는 대신, 다른 이미지의 내용물을 컨테이너 안에 마운트하는 방식이거든요. 이 기능을 사용하면 컨테이너가 자신의 파일시스템과 별개로 두 번째 이미지의 파일들을 읽을 수 있어요. 물론 마운트된 이미지는 읽기 전용이고, 컨테이너가 그 안에 쓸 수는 없어요.

출처: 공식문서

본문

참고: 이미지 마운트를 사용하려면 containerd 이미지 스토어가 필요해요.

이미지 마운트는 언제 사용하나요?

이미지 마운트는 이런 상황에서 아주 유용해요.

  • 최소화되거나 하드닝된 이미지를 디버깅할 때
    셸이나 공통 유틸리티가 없는 이미지에 busybox 같은 도구가 풍부한 이미지를 마운트해서 실행할 수 있어요. 원래 이미지는 전혀 변경하지 않아요. 실제 예시는 Debug with Docker Hardened Images 문서에서 확인할 수 있어요.

  • 읽기 전용 자산을 공유할 때
    데이터셋, 모델, 정적 콘텐츠 같은 것들을 이미지로 배포하고, 다른 이미지로 실행되는 컨테이너에서 그대로 소비하고 싶을 때 좋아요.

  • 애플리케이션 이미지를 작게 유지하고 싶을 때
    선택적인 도구를 별도의 이미지로 패키징해 두고, 필요할 때만 마운트해서 사용하면 메인 이미지 크기를 줄일 수 있어요.

기존 데이터 위에 마운트하기

컨테이너 안에 이미 파일이나 디렉터리가 있는 경로에 이미지를 마운트하면, 기존 파일들은 마운트에 의해 가려져요. 리눅스 호스트에서 /mnt에 파일을 저장해 둔 다음 USB 드라이브를 /mnt에 마운트하는 것과 비슷하다고 생각하면 돼요. USB 드라이브를 마운트 해제하기 전까지는 /mnt의 기존 내용이 보이지 않잖아요.

컨테이너에서는 마운트를 해제해서 가려진 파일을 다시 드러나게 하는 간단한 방법이 없어요. 그럴 때는 마운트 없이 컨테이너를 새로 만드는 게 가장 좋은 해결책이에요.

고려 사항 및 제약 조건

  • 이미지 마운트는 항상 읽기 전용이에요. 컨테이너가 마운트된 이미지를 수정할 수 없고, 변경 사항이 어디에도 저장되지 않아요.
  • 소스 이미지는 데몬의 이미지 스토어에 이미 존재해야 해요. Docker가 마운트를 만들 때 자동으로 이미지를 pull 하지 않아요. 이미지가 없으면 명령이 실패해요.
$ docker run --mount type=image,source=busybox:musl,destination=/dbg alpine
docker: Error response from daemon: No such image: busybox:musl

이런 경우 docker pull로 이미지를 먼저 받아온 다음 마운트를 만들어야 해요.

  • 이미지 마운트는 containerd 이미지 스토어가 필요해요. 데몬이 클래식 스토리지 드라이버를 사용할 때는 사용할 수 없어요.
  • 이미지 마운트는 --mount 플래그로만 만들 수 있어요. --volume (-v)에 해당하는 옵션은 없어요.
  • 마운트된 이미지에서 실행 파일을 실행하려면 컨테이너에 호환되는 런타임이 필요해요. 동적 링크 바이너리는 컨테이너가 일치하는 동적 링커와 공유 라이브러리를 제공해야만 실행돼요. 예를 들어 glibc 기반 바이너리는 Alpine 같은 musl 기반 이미지에서 실행되지 않아요. 정적 링크 바이너리이거나 이미지에서 데이터만 마운트하면 이 제약을 피할 수 있어요.

구문

docker run 명령으로 이미지를 마운트하려면 --mount 플래그에 type=image를 사용하면 돼요.

$ docker run --mount type=image,src=<image-reference>,dst=<container-path>

--mount 플래그는 여러 개의 키-값 쌍으로 구성돼요. 각 쌍은 쉼표로 구분하고, <key>=<value> 형태를 가져요. 키의 순서는 중요하지 않아요.

$ docker run --mount type=image,src=<image-reference>,dst=<container-path>[,<key>=<value>...]

--mount 옵션

--mount type=image에서 사용할 수 있는 옵션은 다음과 같아요.

옵션 설명
source, src 마운트할 이미지의 참조예요. 예를 들어 busybox 또는 busybox:musl처럼 사용해요. 이미지는 로컬에 존재해야 해요.
destination, dst, target 컨테이너에서 이미지가 마운트되는 경로예요. 절대 경로여야 해요.
image-subpath 소스 이미지의 루트 대신 마운트할 이미지 내부 경로예요. 이미지의 하위 경로 마운트하기를 참고하세요.

예시:

$ docker run --mount type=image,src=busybox,dst=/dbg,image-subpath=bin

컨테이너에서 이미지 마운트 사용하기

다음 예시는 Alpine 컨테이너를 실행하면서 busybox:musl 이미지를 /dbg에 마운트해요. Docker가 마운트를 만들 때 이미지를 자동으로 pull 하지 않으므로, 먼저 소스 이미지를 받아와야 해요. 이 예시에서는 musl 기반 BusyBox 이미지를 사용해서 Alpine 컨테이너와 바이너리가 호환되도록 했어요.

$ docker pull busybox:musl
$ docker run -d \
 -it \
 --name imgtest \
 --mount type=image,source=busybox:musl,destination=/dbg \
 alpine:latest

이제 컨테이너는 Alpine 이미지를 실행하면서도 /dbg에서 BusyBox 도구들을 읽을 수 있어요.

$ docker exec imgtest /dbg/bin/echo "hello from busybox"
hello from busybox

마운트가 정말 image 타입인지 확인하려면 docker inspect 출력의 Mounts 섹션을 보면 돼요.

$ docker inspect imgtest --format '{{ json .Mounts }}'
[{"Type":"image","Name":"busybox:musl","Source":"/var/lib/docker/rootfs/overlayfs/...","Destination":"/dbg","Mode":"","RW":false,"Propagation":"rprivate"}]

이 출력을 보면 마운트 타입이 image이고, 소스가 busybox:musl 이미지이며, 읽기 전용("RW":false)이라는 걸 알 수 있어요.

컨테이너를 중지하고 제거하려면 이렇게 해요.

$ docker container rm -fv imgtest

이미지의 하위 경로 마운트하기

image-subpath 옵션을 사용하면 소스 이미지의 루트 대신 특정 디렉터리만 마운트할 수 있어요. 예를 들어 busybox 이미지의 bin 디렉터리만 /tools에 마운트하려면 이렇게 해요.

$ docker run -d \
 -it \
 --name imgtest \
 --mount type=image,source=busybox,destination=/tools,image-subpath=bin \
 alpine:latest

이러면 컨테이너는 이미지의 bin 디렉터리 내용을 /tools에서 볼 수 있어요.

Docker Compose에서 이미지 마운트 사용하기

Docker Compose 서비스에서 이미지 마운트를 사용하려면 volumes 아래에 type: image로 지정하면 돼요.

services:
 app:
 image: alpine:latest
 volumes:
 - type: image
 source: busybox
 target: /dbg

이미지의 하위 경로를 마운트하려면 image 아래 subpath 옵션을 사용해요.

services:
 app:
 image: alpine:latest
 volumes:
 - type: image
 source: busybox
 target: /tools
 image:
 subpath: bin

image.subpath 옵션은 Docker Compose 버전 2.35.0 이상에서 사용할 수 있어요. Compose에서 image 타입 마운트에 대한 자세한 내용은 Compose reference on the volume attribute를 참고하세요.

더 알아보기 (Learn more)