Docker overlay2 스토리지|이미지 레이어가 합쳐지는 방식

Docker의 overlay2는 OverlayFS를 기반으로 이미지의 읽기 전용 레이어(lowerdir)와 컨테이너 쓰기 레이어(upperdir)를 합쳐 하나의 통합된 마운트(merged) 뷰로 보여줍니다. 컨테이너 내부에서 발생한 쓰기 작업은 기본적으로 원본 이미지에 남지 않으며, 컨테이너 삭제 시 쓰기 레이어도 함께 영구적으로 삭제됩니다. 이 글은 Docker 시리즈의 세 번째로, 공식 스토리지 드라이버 문서를 기준으로 컨테이너 레이어가 디스크에서 어떻게 통합되는지를 살펴봅니다.

스토리지 드라이버와 이미지 레이어는 어떤 관계인가?

한 줄 답: 스토리지 드라이버는 이미지를 구성하는 여러 겹의 읽기 전용 레이어를 관리하고, 컨테이너 생성 시 새로운 쓰기 레이어를 추가하여 통합된 파일시스템 뷰를 제공합니다.

Docker 이미지는 단일 파일이 아니라 여러 겹의 읽기 전용 레이어(stacked read-only layers)가 순서대로 쌓인 구조입니다. Dockerfile의 각 명령어(예: FROM, RUN, COPY)는 이미지 빌드 시점에 독립적인 레이어를 만들어 냅니다. 이 레이어들은 변경 불가능(immutable)하며, 이미지를 공유하는 여러 컨테이너가 동일한 레이어를 참조할 수 있습니다.

스토리지 드라이버는 이러한 레이어 구조를 추상화하여 컨테이너 런타임에 단일 파일시스템처럼 보이게 하는 역할을 담당합니다. 공식 문서에 따르면 컨테이너가 생성될 때 스토리지 드라이버는 읽기 전용 이미지 레이어 위에 새로운 쓰기 가능 레이어(new writable layer, 이하 쓰기 레이어 또는 upper)를 추가합니다. 컨테이너가 보는 파일시스템은 이 쓰기 레이어와 이미지 레이어 전체가 통합된 뷰입니다.

Linux 커널이 지원하는 OverlayFS를 활용하는 Docker overlay2는 현재 공식 문서에서 Linux 호스트에 널리 사용되는 스토리지 드라이버입니다. overlay2는 이미지 레이어들을 lowerdir로, 컨테이너 쓰기 레이어를 upperdir로 구성하여 merged 마운트 포인트를 통해 컨테이너에 통합 뷰를 제공합니다. 각 용어의 의미는 다음 섹션에서 자세히 다룹니다.

스토리지 드라이버가 레이어를 올바르게 관리하기 때문에, 2편에서 살펴본 docker load로 복원된 이미지이든 docker pull로 내려받은 이미지이든, 컨테이너 생성 과정은 동일한 경로를 따릅니다.

overlay2의 lowerdir·upperdir·merged·workdir은 각각 무엇인가?

한 줄 답: lowerdir은 읽기 전용 이미지 레이어, upperdir은 컨테이너 전용 쓰기 레이어, merged는 컨테이너가 실제로 보는 통합 뷰, workdir은 OverlayFS 내부 작업을 위한 디렉터리입니다.

OverlayFS는 여러 디렉터리를 겹쳐서(overlay) 하나의 통합된 파일시스템 뷰를 제공하는 Linux 커널 파일시스템입니다. overlay2에서는 다음 네 가지 구성 요소가 사용됩니다.

구성 요소역할읽기/쓰기
lowerdir이미지를 구성하는 읽기 전용 레이어들. 여러 개의 레이어를 쌓을 수 있으며(다중 lower 지원), 컨테이너 내에서 수정할 수 없습니다.읽기 전용
upperdir컨테이너 생성 시 새로 만들어지는 쓰기 레이어. 컨테이너 내부에서 발생하는 모든 파일 변경(생성·수정·삭제)이 이 레이어에 기록됩니다.읽기·쓰기
mergedlowerdir과 upperdir을 합쳐 컨테이너가 바라보는 통합 파일시스템 뷰. 컨테이너의 루트 파일시스템(/)에 해당합니다.통합 뷰
workdirOverlayFS가 copy-up 등 내부 작업을 처리하기 위해 요구하는 임시 작업 디렉터리. 컨테이너 사용자에게는 직접 노출되지 않습니다.내부 전용

컨테이너 관점에서 merged는 하나의 완전한 파일시스템처럼 보입니다. upperdir에 동일한 경로의 파일이 존재하면 lowerdir의 파일보다 우선합니다. upperdir에 없는 파일은 lowerdir에서 투명하게 읽혀 옵니다.

이미지 레이어가 여러 겹일 때, 각 레이어는 lowerdir에 순서대로 나열됩니다. overlay2는 다중 lower 레이어를 지원하므로, 여러 단계로 빌드된 이미지라도 하나의 OverlayFS 마운트로 표현할 수 있습니다.

참고: Docker Engine 29 이상에서는 containerd image store(snapshotter)가 기본으로 사용될 수 있습니다. 이 경우 레이어 스택의 개념은 동일하지만, 실제 경로나 관리 명령이 다를 수 있습니다. 이 글의 설명은 공식 문서의 classic overlay2 기준을 따릅니다.

copy-on-write는 파일을 수정할 때 무엇을 하나?

한 줄 답: lowerdir(이미지 레이어)에만 존재하는 파일을 수정하면 OverlayFS가 먼저 그 파일을 upperdir로 복사(copy-up)한 뒤 수정하며, 파일 삭제는 whiteout 파일로 lowerdir의 파일을 가리는 방식으로 처리합니다.

copy-on-write(CoW)는 읽기 전용 레이어를 보호하면서 쓰기를 가능하게 하는 핵심 메커니즘입니다. overlay2에서 CoW는 다음과 같이 동작합니다.

파일 수정: copy-up

컨테이너가 lowerdir에만 존재하는 파일을 처음으로 수정하려고 할 때, OverlayFS는 다음 과정을 수행합니다.

  1. lowerdir에서 해당 파일 전체를 upperdir로 복사합니다(copy-up).
  2. 이후 수정은 upperdir에 복사된 파일에 대해 이루어집니다.
  3. lowerdir의 원본 파일은 변경되지 않고 그대로 유지됩니다.

copy-up은 파일 크기에 비례한 초기 비용이 발생하지만, 이후 같은 파일에 대한 반복 쓰기는 upperdir에서만 이루어집니다. 공식 문서는 이 초기 복사 비용이 write-heavy 워크로드에서 성능에 영향을 줄 수 있음을 언급합니다.

파일 삭제: whiteout

컨테이너가 lowerdir에 있는 파일을 삭제하면, OverlayFS는 lowerdir의 원본 파일을 실제로 지우지 않습니다. 대신 upperdir에 whiteout이라는 특수 파일(또는 디렉터리의 경우 opaque 속성)을 생성하여, merged 뷰에서 해당 경로의 파일이 보이지 않도록 가립니다. 이 방식으로 읽기 전용 이미지 레이어의 불변성이 유지됩니다.

새 파일 생성

컨테이너가 새 파일을 생성하면, 해당 파일은 copy-up 없이 곧바로 upperdir에 생성됩니다.

여러 컨테이너가 같은 이미지를 쓰면 디스크는 어떻게 공유되나?

한 줄 답: 동일한 이미지 기반의 여러 컨테이너는 공통 이미지 레이어(lowerdir)를 호스트에서 공유하고, 각 컨테이너는 자신만의 얇은 upperdir만 별도로 생성합니다.

overlay2의 레이어 공유 방식은 디스크 공간과 이미지 pull 비용을 크게 줄여줍니다. 예를 들어 동일한 기반 이미지를 사용하는 컨테이너 10개를 실행한다고 가정합니다.

  • 이미지 레이어(lowerdir): 기반 이미지의 모든 레이어는 호스트에 단 한 벌만 저장됩니다. 10개의 컨테이너가 이 레이어들을 동시에 참조하더라도, 디스크에는 이미지 데이터의 복사본이 추가로 생성되지 않습니다.
  • 컨테이너 쓰기 레이어(upperdir): 각 컨테이너는 자신만의 upperdir을 생성합니다. 컨테이너가 아무것도 쓰지 않았다면 upperdir은 거의 비어 있으며, 실제로 수정된 파일의 copy-up 결과만 upperdir에 누적됩니다.

공식 스토리지 드라이버 문서에 따르면, 이 레이어 공유 덕분에 동일한 베이스 이미지로 여러 컨테이너를 운영할 때 디스크 사용량이 컨테이너 수에 비례하여 증가하지 않습니다. 이미지 pull 시에도 이미 로컬에 존재하는 레이어는 다시 내려받지 않으므로, 네트워크 비용 역시 절감됩니다.

이 공유 구조는 lowerdir가 읽기 전용이기 때문에 가능합니다. 어떤 컨테이너도 lowerdir를 직접 수정할 수 없으므로, 모든 컨테이너가 동일한 lowerdir을 안전하게 참조할 수 있습니다.

쓰기 많은 데이터를 overlay 쓰기 레이어에 두면 왜 문제인가?

한 줄 답: 컨테이너 삭제 시 upperdir(쓰기 레이어)도 함께 영구 삭제되며, write-heavy 워크로드를 쓰기 레이어에 두면 copy-up 비용으로 인해 성능이 저하될 수 있습니다. 영속 데이터와 I/O가 많은 데이터는 volume 또는 bind mount를 사용해야 합니다.

컨테이너 삭제 시 쓰기 레이어는 사라집니다

컨테이너를 docker rm으로 삭제하면, 해당 컨테이너의 upperdir과 그 안에 누적된 모든 쓰기 데이터도 함께 삭제됩니다. 이미지 레이어(lowerdir)는 영향을 받지 않습니다. 즉, 컨테이너 실행 중에 쓰기 레이어에 저장한 데이터는 컨테이너가 삭제되는 순간 복구 불가능하게 사라집니다. 이것은 overlay2의 설계 의도이며, 이미지 레이어의 불변성을 보장하기 위한 구조입니다.

write-heavy 워크로드의 성능 문제

공식 Docker 스토리지 드라이버 문서는 write-heavy 워크로드를 컨테이너의 쓰기 레이어에 두지 말 것을 권고합니다. 그 이유는 다음과 같습니다.

  • copy-up 비용: 처음 수정하는 파일은 lowerdir에서 upperdir로 전체 복사(copy-up)가 선행됩니다. 파일이 클수록 이 비용이 커집니다.
  • 레이어 탐색 오버헤드: 파일 조회 시 OverlayFS는 upperdir과 여러 lowerdir을 순서대로 탐색합니다. 레이어가 많을수록 탐색 경로가 길어집니다.

영속 데이터는 volume 또는 bind mount를 사용해야 합니다

데이터베이스 파일, 로그, 캐시처럼 영속성이 필요하거나 I/O가 잦은 데이터는 컨테이너의 쓰기 레이어 대신 Docker volume 또는 bind mount를 사용해야 합니다. volume과 bind mount는 컨테이너 파일시스템(overlay)을 거치지 않고 호스트 파일시스템에 직접 읽고 씁니다. 컨테이너가 삭제되어도 volume의 데이터는 유지됩니다.

volume과 bind mount의 구체적인 사용법과 레이어 캐시 활용 전략은 이 시리즈의 4편에서 다룹니다. 이 편에서는 “overlay 쓰기 레이어는 임시 레이어이므로 영속 데이터는 반드시 외부 마운트로 분리해야 한다”는 원칙만 기억해 두시기 바랍니다.

FAQ

한 줄 답: overlay2 스토리지 드라이버와 관련하여 자주 묻는 질문을 정리합니다.

질문답변
현재 사용 중인 스토리지 드라이버는 어떻게 확인하나요?docker info 명령어를 실행하면 Storage Driver 항목에서 현재 사용 중인 드라이버(예: overlay2)를 확인할 수 있습니다.
스토리지 드라이버를 변경하면 어떤 점을 주의해야 하나요?드라이버를 변경하면 기존 드라이버로 관리되던 로컬 이미지와 컨테이너에 접근할 수 없게 될 수 있습니다. 드라이버 변경 전에 필요한 이미지를 docker save로 백업해 두는 것이 권장됩니다(2편 참조). 변경 절차는 공식 문서 및 호스트 환경에 따라 다르므로 사전에 확인이 필요합니다.
Engine 29 이상에서는 overlay2 경로가 다를 수 있나요?Docker Engine 29 이상에서 containerd image store(snapshotter)를 사용하는 경우, 이미지와 레이어 관리 경로·명령이 classic overlay2와 다를 수 있습니다. 레이어를 스택으로 쌓는 개념은 동일하지만, 실제 경로와 운영 방식은 환경에 따라 달라질 수 있으므로 docker info로 현재 환경을 먼저 확인하시기 바랍니다.
컨테이너 안에서 쓴 파일은 이미지에 반영되나요?아닙니다. 컨테이너의 쓰기는 upperdir(쓰기 레이어)에만 기록되며, 이미지 레이어(lowerdir)는 변경되지 않습니다. 변경 사항을 이미지에 반영하려면 docker commit을 사용하거나 Dockerfile로 새 이미지를 빌드해야 합니다.
overlay2 외에 다른 스토리지 드라이버도 있나요?공식 문서에는 overlay2 외에도 btrfs, zfs, devicemapper(레거시), vfs 등의 드라이버가 언급됩니다. 그러나 Linux 호스트에서는 overlay2가 권장되는 기본 선택입니다. 드라이버 선택은 호스트 파일시스템과 커널 버전에 따라 달라집니다.

출처

한 줄 답: 본문 사실은 2026-09-14 기준으로 확인한 Docker 공식 스토리지 드라이버 문서를 사용합니다.

이 글은 Docker 공식 스토리지 드라이버 문서를 기준으로 한 일반 안내이며, Docker Engine 버전·containerd image store 사용 여부·호스트 파일시스템에 따라 실제 경로와 관리 명령은 달라질 수 있습니다.