도커의 파일시스템
도커(Docker)은 컨테이너 기술을 제공하는 플랫폼으로, 핵심적인 특징 중 하나가 바로 레이어(layer) 개념과 유니온 파일시스템(Union Filesystem)을 활용한 독특한 파일시스템 구조임.
도커 파일시스템 구조를 정확히 이해하면 도커 이미지가 어떻게 구성되는지, 컨테이너 내부에서 파일 변경이 어떻게 처리되는지, 다양한 스토리지 드라이버는 어떤 방식으로 동작하는지 등을 심도 있게 파악할 수 있음.
도커 이미지와 레이어
도커 이미지는 여러 개의 읽기 전용 레이어(읽기 전용 파일시스템)를 유니온 파일시스템으로 합쳐서 하나의 논리적인 파일시스템을 구성한 형태임.
도커 이미지는 전통적인 VM 이미지를 생각했을 때와 달리 매우 가볍고, 변경점만을 새로운 레이어로 관리함으로써 이미지를 효율적으로 재사용할 수 있음.
1. 베이스 이미지(Base Image)
예: Ubuntu, Debian, Alpine 등 배포판 이미지를 기반으로 할 수 있음.
가장 아래 레이어에 위치하며, 도커 파일시스템의 기초가 됨.
2. 추가 레이어(Intermediate Layers)
RUN, COPY, ADD 등의 Dockerfile 명령이 실행될 때마다 새로운 읽기 전용 레이어가 생성됨.
각 레이어에는 해당 명령의 결과로 바뀐 파일(혹은 새로 추가된 파일)이 저장됨.
레이어는 항상 불변(Immutable)임.
한 번 만들어진 레이어를 나중에 변경하지 않음.
3. 최상위 레이어(Top Layer, Read-Write Layer)
컨테이너가 실행될 때, 읽기-쓰기 레이어(Thin writable layer)가 추가됨.
컨테이너에서 파일을 수정 또는 삭제하면 이 읽기-쓰기 레이어에 변경 내용이 반영됨.
컨테이너가 종료되면 기본적으로 이 레이어는 사라지며, 컨테이너가 삭제되면 더 이상 해당 변경 내용은 유지되지 않음.
이 레이어를 Copy-on-Write(CoW)라고도 부르는데, 하위 레이어에서 필요한 파일을 수정할 때 읽기 전용 레이어의 데이터를 복사한 뒤(write) 수정(copy)하는 방식임.
유니온 파일시스템 작동방식
유니온 파일시스템(Union FS)은 여러 파일시스템(또는 여러 디렉터리)을 겹쳐서 하나의 일관된 파일시스템 뷰를 제공하는 기술임.
도커 컨테이너 내부에서 ls / 등을 했을 때, 실제로는 여러 레이어가 합쳐져서 나타나는 것임.
Lower Layers: 읽기 전용 레이어들 (Image Layers)
Upper Layer: 컨테이너 실행 시 추가되는 읽기/쓰기 레이어
파일을 읽을 때는 상위 레이어부터 탐색하여 파일이 존재하면 즉시 반환하고, 없으면 다음 하위 레이어를 조회함.
파일을 쓸 때는 최상위(쓰기 가능한) 레이어에만 변경점이 반영됨.
Copy-on-Write
Copy-on-Write는 도커가 파일의 변경을 효율적으로 처리하기 위해 사용하는 기법임.
1. 처음 읽는 파일
이미 이미지 레이어에 존재하는 파일은 그대로 사용함.
변경되지 않은 파일은 굳이 복사되지 않음.
2. 파일 수정 혹은 삭제 시
변경 지점에서 상위(쓰기 가능한) 레이어에만 실제 변경분이 반영됨.
이때, 읽기 전용 레이어에 있는 파일을 수정해야 하는 경우에만, 그 파일을 복사하여 쓰기 레이어로 가져옴.
그 뒤에 쓰기 레이어에서 파일을 수정함.
3. 장점
전체 레이어를 복사할 필요 없이, 필요한 파일만 수정본을 생성하므로 스토리지 사용을 최소화할 수 있음.
여러 컨테이너가 동일한 읽기 전용 레이어를 공유해도 문제없으며, 서로 독립적인 쓰기 레이어만 관리하면 됨.
도커 스토리지 드라이버
도커 엔진은 실제로 레이어를 합쳐서 컨테이너 파일시스템을 구성하기 위해 스토리지 드라이버를 사용함.
도커가 지원하는 주요 스토리지 드라이버는 다음과 같음.
1. Overlay2 (AUFS의 대안으로 많이 사용됨)
리눅스 커널 3.18 이상에서 지원하는 OverlayFS를 사용하는 드라이버임.
도커 17.06 이후 기본 드라이버임(리눅스 배포판에서 가장 일반적으로 사용).
AUFS처럼 유니온 마운트를 구현하지만, 커널 모듈에서 직접 지원하므로 더 단순하고 효율적이라는 장점이 있음.
2. AUFS(Another Union File System)
과거에 도커에서 많이 사용되었으나, 최신 배포판에서 커널 지원 문제 등으로 이제는 Overlay2 사용이 권장됨.
여러 디렉터리를 하나의 디렉터리로 합쳐 보여주는 유니온 파일시스템임.
3. devicemapper
LVM(Logical Volume Manager)의 Device Mapper 기능을 활용하여 AUFS/OverlayFS와 다른 방식으로 CoW 기능을 구현함.
블록 레벨에서 복사를 하므로, 파일 레벨이 아닌 블록 레벨 단위로 Copy-on-Write가 발생함.
설정이 복잡하고, 관리 오버헤드가 크다는 단점이 있어 현재는 일반적으로 권장되지 않음.
4. Btrfs
Btrfs 자체의 스냅샷/CoW 기능을 활용하여 레이어를 관리함.
Btrfs가 기본 파일시스템으로 설정된 시스템에서 사용 가능하지만, 아직은 Overlay2보다 폭넓게 쓰이지는 않음.
5. ZFS
ZFS 역시 스냅샷 기능을 지원하므로, 도커 스토리지 드라이버로 사용이 가능함.
다만, 운영 환경에서의 범용적 사용은 Overlay2 등에 비해 적은 편임.
각 스토리지 드라이버마다 특화된 최적화 포인트와 설정 방식이 다름.
예를 들어 Overlay2는 파일 단위 CoW, devicemapper는 블록 단위 CoW, Btrfs/ZFS는 스냅샷/서브볼륨 등을 활용하는 식으로 차이가 있음.
컨테이너 실행 시 파일시스템 구조
도커 컨테이너를 실행하면 다음과 같은 구조가 형성됨.
+---------------------+
| Writable Layer | (컨테이너 실행 시 생성되는 읽기/쓰기 레이어)
+---------------------+
^
|
+---------------------+ <- 상위 레이어(이미지)
| Read Only Layer |
+---------------------+
^
|
+---------------------+ <- 중간 레이어(이미지)
| Read Only Layer |
+---------------------+
^
|
+---------------------+ <- 베이스 이미지(이미지)
| Read Only Layer |
+---------------------+
( => 유니온 마운트로 하나로 합쳐진 뷰 )
1. 이미지 레이어들의 Union
베이스 이미지부터 최상위 이미지 레이어까지 전부 읽기 전용으로 마운트됨.
2. 컨테이너 전용 쓰기 레이어
실행 시, 해당 컨테이너만의 읽기/쓰기 레이어가 생성되고, 그 위에 Mount되어 통합된 파일시스템 뷰를 제공함.
도커 파일시스템 운영 시 고려 사항
1. 이미지 캐싱과 레이어 재사용
도커는 레이어 단위로 이미지를 캐싱하기 때문에, Dockerfile에서 이전에 사용한 레이어가 있으면 재빌드 시 해당 레이어는 다시 다운받거나 생성하지 않고 재사용함.
레이어가 쌓일수록 디스크 사용량이 증가할 수 있으므로, 불필요한 레이어 생성을 최소화하도록 Dockerfile을 최적화(RUN 명령 통합 등)하는 것이 좋음.
2. 스토리지 드라이버 별 설정 및 최적화
시스템 환경(커널 버전, 파일시스템 등)에 따라 최적의 스토리지 드라이버를 선택해야 함.
Overlay2가 가장 범용적으로 쓰이지만, 특정한 요구사항(devicemapper를 통한 블록 디바이스 관리, btrfs로의 스냅샷 활용 등)이 있다면 다른 드라이버를 고려할 수 있음.
3. 파일 시스템 동작 모니터링
/var/lib/docker/<storage-driver>/ 디렉터리에 실제 레이어 및 컨테이너 파일 구조가 존재하므로, 디스크 사용량 모니터링이 필요함.
로그가 많이 쌓이는 컨테이너 등은 적절히 로그 로테이션을 하거나 외부 스토리지(예: volume)를 활용하여 컨테이너 내부 레이어 폭증을 방지해야 함.
4. 도커 볼륨(Volume)과의 차이
컨테이너 파일시스템(이미지 레이어 + 읽기/쓰기 레이어)과 별개로, 애플리케이션 데이터 저장 등에 사용되는 도커 볼륨은 호스트 파일시스템이나 네트워크 스토리지에 마운트하는 형태임.
컨테이너와 분리되어 독립적으로 라이프사이클을 관리할 수 있기 때문에, 지속성(Persistence)이 필요한 데이터에는 볼륨을 사용함.
정리
도커의 파일시스템은 유니온 파일시스템과 레이어라는 핵심 아이디어를 통해 매우 효율적으로 동작함.
이미지를 여러 레이어로 분할하여 재사용하고, Copy-on-Write 방식으로 최소한의 스토리지 사용만으로도 컨테이너를 빠르게 생성할 수 있음.
이러한 구조를 이해하면 도커 이미지 빌드 시 최적화 방안을 쉽게 파악할 수 있고, 실제 운영 환경에서 컨테이너가 파일을 어떻게 처리하는지 명확히 알 수 있음.
도커 파일시스템 이해의 핵심은 다음과 같음.
1. 이미지 레이어는 읽기 전용이며, 컨테이너 실행 시 생성되는 읽기/쓰기 레이어가 최상위에 추가됨.
2. Copy-on-Write(CoW) 방식으로 파일이 변경될 때만 상위 레이어에 복사되어 수정됨.
3. 스토리지 드라이버(Overlay2, AUFS, devicemapper, Btrfs, ZFS 등)는 각각 다른 방식으로 이 레이어 구조와 CoW를 구현하지만, 최종적으로 컨테이너에는 통합된 하나의 파일시스템이 제공됨.
이해한 내용을 바탕으로 Dockerfile 최적화, 이미지 관리 전략, 컨테이너 실행 시 디스크 모니터링 등에 적극 활용할 수 있을 것임.
'Operating System > Docker' 카테고리의 다른 글
[Docker] 도커 볼륨 구조 (1) | 2025.01.24 |
---|---|
[Docker] 컨테이너 실시간 모니터링 방법 (2) | 2025.01.24 |
[Docker] 도커 컨테이너 자원과 로컬의 자원 (0) | 2025.01.24 |
[Docker] Dockerfile 작성하는 방법 (0) | 2025.01.24 |
[Docker] 도커와 도커의 네트워크 (0) | 2024.06.08 |