2025. 12. 30. 20:59ㆍDocker
🧱 Docker Layer
0️⃣ 한 문장 정의
도커 레이어란
도커 이미지와 컨테이너 파일시스템을 구성하는
불변(Immutable)한 변경 기록 단위이며,
Union File System으로 겹쳐서 하나의 파일시스템처럼 보이게 만든 구조입니다.
1️⃣ 왜 도커는 “레이어” 구조를 쓰는가?
도커의 목표는 단순합니다.
✔ 빠른 빌드
✔ 이미지 재사용
✔ 저장 공간 절약
✔ 배포 속도 향상
이를 위해 “파일 전체 복사” 대신
“변경 사항만 쌓는 방식”을 선택했습니다.
📌 이때의 “변경 사항” 하나하나가 레이어입니다.
2️⃣ 이미지 레이어 vs 컨테이너 레이어
🔹 Docker Image = 읽기 전용 레이어들의 집합
[ Layer 1 ] FROM ubuntu:22.04
[ Layer 2 ] RUN apt-get update
[ Layer 3 ] RUN apt-get install -y curl
[ Layer 4 ] COPY app.jar /app/app.jar
- 모든 레이어는 Read-Only
- 여러 이미지가 같은 레이어를 공유 가능
🔹 Docker Container = 이미지 + 쓰기 레이어
컨테이너를 실행하면:
[ Writable Layer ] ← 컨테이너 전용 (Read-Write)
[ Layer 4 ]
[ Layer 3 ]
[ Layer 2 ]
[ Layer 1 ]
- 맨 위에 하나의 Writable Layer가 추가됨
- 파일 생성/수정/삭제는 여기만 기록
📌 이미지 레이어는 절대 수정되지 않습니다
3️⃣ Dockerfile 싱글 라인 = 레이어 하나?
🔹 기본 원칙
Dockerfile의 각 명령은 “레이어를 생성할 수 있다”
하지만 ⚠️ 모든 명령이 레이어를 만드는 것은 아닙니다.
🔹 레이어를 만드는 명령
| 명령 | 레이어 생성 |
|---|---|
| FROM | ✅ |
| RUN | ✅ |
| COPY | ✅ |
| ADD | ✅ |
🔹 레이어를 만들지 않는 명령
| 명령 | 레이어 생성 |
|---|---|
| CMD | ❌ |
| ENTRYPOINT | ❌ |
| ENV | ❌ (메타데이터 변경) |
| WORKDIR | ❌ |
| EXPOSE | ❌ |
📌 CMD / ENTRYPOINT는 실행 정보이지 파일시스템 변경이 아님
4️⃣ 레이어는 “차이(diff)”만 저장한다
예제
RUN apt-get update
RUN apt-get install -y curl
이때 저장되는 것은:
- 전체 파일시스템 ❌
- 이전 레이어 대비 변경된 파일만 ✅
Layer N:
+ /var/lib/apt/lists/xxx
+ /usr/bin/curl
5️⃣ 삭제해도 용량이 줄지 않는 이유 (중요!)
❌ 잘못된 기대
RUN apt-get install -y curl
RUN rm -rf /var/lib/apt/lists/*
❌ 결과
- 이미지 용량 안 줄어듦
이유
- 삭제는 다음 레이어에서 “삭제 기록”만 남김
- 이전 레이어의 파일은 이미 존재
Layer 1: + apt lists (50MB)
Layer 2: - apt lists (삭제 마킹)
📌 레이어는 쌓이지, 덮어쓰지 않는다
✅ 올바른 방법 (한 레이어에서 처리)
RUN apt-get update \
&& apt-get install -y curl \
&& rm -rf /var/lib/apt/lists/*
✔ 설치 + 삭제가 같은 레이어
✔ 불필요한 파일이 아예 기록되지 않음
6️⃣ Docker 빌드 캐시와 레이어의 관계 (아주 중요)
🔹 Docker는 이렇게 판단합니다
“이 레이어,
이전에 같은 명령 + 같은 입력으로 만든 적 있네?”
→ 있으면 재사용 (cache hit)
→ 없으면 새로 생성 (cache miss)
🔹 Dockerfile 예제
COPY . .
RUN npm install
❌ 이 순서의 문제점
- 소스 하나만 바뀌어도
npm install캐시 무효
✅ 캐시 최적화 구조
COPY package.json package-lock.json ./
RUN npm install
COPY . .
✔ 의존성 변경 없으면 npm install 재사용
✔ 빌드 속도 극적 개선
7️⃣ 레이어 공유의 위력 (디스크 절약)
예
- 10개의 컨테이너
- 모두
ubuntu:22.04기반
ubuntu base layer (shared)
↑
10개의 이미지가 동일 레이어 참조
✔ 디스크에 1번만 저장
✔ 컨테이너 수 늘어도 용량 거의 증가 없음
8️⃣ 컨테이너에서 파일 수정하면 무슨 일이 일어날까?
Copy-on-Write (COW)
- 이미지 레이어의
/etc/config.yml읽음 → OK - 수정 시도 →
- 해당 파일이 Writable Layer로 복사
- 수정은 컨테이너 레이어에서만 발생
📌 다른 컨테이너, 원본 이미지에는 전혀 영향 없음
9️⃣ 컨테이너 삭제하면 무슨 일이?
docker rm mycontainer
- ❌ 이미지 레이어: 그대로
- ❌ 다른 컨테이너: 영향 없음
- ✅ Writable Layer만 삭제
그래서:
❗ 컨테이너 내부에 만든 파일은
컨테이너 삭제 시 100% 사라짐
👉 영속 데이터는 Volume / Bind Mount 필수
🔟 실무에서 레이어를 이렇게 생각하시면 됩니다
🧠 사고 공식
Docker Image
= 설치 기록의 타임라인
= 변경 이력의 스택
좋은 Dockerfile의 조건
- 레이어 수 최소화
- 캐시 잘 타게 구조화
- 불필요한 파일 같은 레이어에서 제거
- 자주 변하는 것 → 아래
- 거의 안 변하는 것 → 위
🎯 최종 핵심 요약
| 개념 | 핵심 |
|---|---|
| 레이어 | 변경 기록 단위 |
| 이미지 | Read-Only 레이어 스택 |
| 컨테이너 | 이미지 + Writable Layer |
| 삭제 | 이전 레이어는 제거 안 됨 |
| 캐시 | 명령 + 입력 기준 |
| 용량 | 레이어 공유로 절약 |
'Docker' 카테고리의 다른 글
| overlay2 (1) | 2025.12.30 |
|---|---|
| 도커 이미지 레이어는 diff만 저장한다. (0) | 2025.12.30 |
| COPY --from=build (0) | 2025.12.30 |
| Multi-Stage Build (0) | 2025.12.30 |
| CMD vs ENTRYPOINT (0) | 2025.12.30 |