여러 레이어를 겹쳐서 하나의 파일시스템으로 보이게 하는 기술. 리눅스에서는 보통 OverlayFS 가 담당한다.
┌─────────────────────┐ ← 컨테이너 쓰기 레이어 (읽기·쓰기)
├─────────────────────┤
│ 레이어 3 /app │ ← 이미지 레이어 (읽기 전용)
├─────────────────────┤
│ 레이어 2 curl │
├─────────────────────┤
│ 레이어 1 alpine │
└─────────────────────┘
↓ 겹쳐 보면
하나의 파일시스템
읽기와 쓰기가 다르게 동작한다
-
읽기 — 위에서부터 찾아 처음 발견한 것을 준다
-
쓰기 — 읽기 전용 레이어의 파일을 고치려 하면
- 그 파일을 쓰기 레이어로 '통째로 복사한 뒤' 고친다 (copy-up)
copy-up 이 만드는 성능 문제
-
1GB 짜리 파일의 1바이트만 고쳐도 1GB 가 복사된다
-
영향받는 워크로드
- 데이터베이스 파일을 컨테이너 안에 두는 경우
- 큰 로그 파일을 안에서 계속 쓰는 경우
- 빌드 산출물을 컨테이너 안에서 반복 수정
-
그런 데이터는 볼륨에 둔다 (union 을 거치지 않고 직접 쓴다)
-
"컨테이너에서 DB 가 느리다" 의 주요 원인이다
삭제도 특이하다
- 읽기 전용 레이어의 파일을 지우면 실제로 지울 수가 없다
- 쓰기 레이어에 '이 파일은 없는 것으로 하라' 는 표식을 만든다 (whiteout)
디렉터리를 통째로 지우면 opaque 디렉터리 표식이 생긴다
결과적으로 지울수록 레이어가 커진다
무엇이 바뀌었는지 보기
$ docker diff web
C /var/log
A /var/log/nginx/access.log
C /etc/nginx/nginx.conf
-
A 추가됨(Added) C 변경됨(Changed) D 삭제됨(Deleted)
-
이미지 대비 컨테이너에서 무엇이 바뀌었는지 보여 준다
-
컨테이너가 어디에 쓰는지 파악할 때 (읽기 전용 루트 도입 전 조사)
-
예상 못 한 쓰기를 찾을 때
스토리지 드라이버
-
overlay2 — 현재 리눅스의 기본. OverlayFS 기반
-
btrfs · zfs — 해당 파일시스템의 스냅숏 기능을 쓴다
-
devicemapper — 블록 수준. 예전 RHEL 계열에서 쓰였다 (지금은 권장되지 않는다)
-
확인 — docker info | grep -i storage
드라이버에 따라 성능 특성과 레이어 수 제한이 다르다 overlay2 는 레이어가 지나치게 많으면(수십 개) 성능이 떨어진다
- RUN 을 무의미하게 쪼개지 않는 이유 중 하나다
쓰기가 많은 워크로드의 선택
- 컨테이너 안 경로 — union 을 거친다. copy-up 발생
- 볼륨 — 호스트 파일시스템에 직접. 빠르다
- tmpfs — 메모리. 가장 빠르지만 휘발성
판단
· DB 데이터 · 업로드 파일 → 볼륨 (필수)
· 임시 파일 · 캐시 → tmpfs 또는 볼륨
· 애플리케이션 코드 → 이미지 레이어 (읽기만)
면접 함정
- ❌ "컨테이너 안 파일 쓰기는 볼륨과 성능이 같다" → copy-up과 union 계층 때문에 느리다.
- ❌ "쓰기 레이어도 이미지에 포함된다" → 컨테이너를 지우면 사라진다.
commit하지 않는 한 남지 않는다.