Docker Layer

2025. 12. 30. 20:59Docker

🧱 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)

  1. 이미지 레이어의 /etc/config.yml 읽음 → OK
  2. 수정 시도 →
  3. 해당 파일이 Writable Layer로 복사
  4. 수정은 컨테이너 레이어에서만 발생

📌 다른 컨테이너, 원본 이미지에는 전혀 영향 없음

 

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