먼저, Overlay2란

Linux와 Docker의 Overlay

Linux Kernal - OverlayFS
------------------------
- 커널에 내장된 파일시스템 드라이버.
- "mount -t overlay" 시스템 콜로 lowerdir, uppderdir, merged를 마운트하는 "실제 엔진"

Docker - overlay2 스토리지 드라이버
----------------------------------
- 커널 OverlayFS를 "호출해서 쓰는 Go 코드"
- 레이어 디렉토리 관리, 캐시 판단 등의 관리 로직
- 별도 파일시스템이 아님

=> Docker를 설치해도 overlay2가 2개가 되는 게 아니라, 커널의 OverlayFS 위에 "관리 계층"이 
	 얹어지는 것

레이어 디렉토리 구조

/var/lib/docker/overlay2/<해시>/ 
├── diff/ ← 이 레이어의 파일 내용 (변경분) 
├── link ← 짧은 심볼릭 링크 ID 
├── lower ← 하위 레이어 참조 
├── work/ ← OverlayFS 내부 작업용 
└── merged/ ← 컨테이너 실행 시에만 생김

- "diff/"가 핵심
- 이미지 레이어의 "diff/"는 "lowerdir(읽기 전용)"으로 쓰이고,
  컨테이너 레이어의 "diff/"는 "upperdir(쓰기 가능)"으로 마운트 됨.

빌드 과정

Dockerfile 명령어 하나당 일어나는 일

1. 이전 레이어들을 "lowerdir"로 깔고, 빈 upperdir(diff/)로 임시 컨테이너 생성

2. merged/ 안에서 명령어 실행 -> 변경사항이 "upperdir"에 기록

3. 실행 완료 -> upperdir 내용을 "새 디렉토리에 읽기 전용 레이어로 커밋"

4. 임시 컨테이너 삭제(upperdir, merged 마운트 해제)

5. 다음 명령어는 이 새 레이어를 lowerdir에 추가하고 1번부터 반복

핵심
----
upperdir은 임시로만 존재. 커밋 순간 새로운 독립 디렉토리가 변환되고 원래 upperdir은 사라짐.
upperdir에 계속 쌓이는 게 아니라 "매번 새 디렉토리가 생기는 것"

저장소 변화

COPY build.gradle ./     <- 캐시 히트
RUN gradle dependencies  <- 캐시 히트
COPY src/ ./src/         <- 캐시 미스
RUN gradle build         <- 자동으로 캐시 미스(부모가 바뀌어서)

변화

/var/lib/overlay2/
 |- a1.../diff/    <- build.gradle   (기존 것 재사용)
 |- f3.../diff/    <- gradle deps    (기존 것 재사용)
 |- d7.../diff/    <- 이전 src/      <- dangling(댕글링, 어떤 이미지도 참조 안된 레이어)
 |- b1.../diff/    <- 이전 app.jar   <- dangling
 |- x8.../diff/    <- 새 src/        <- new
 |- y2.../diff/    <- 새 app.jar     <- new

아래 레이어도 변경되는 이유

"레이어 해시 = 부모 해시 + 명령어 + 입력"

그래서 체인처럼 엮여 있음
------------------------
FROM openjdk:17     → 해시: a1  = hash(없음 + "FROM openjdk:17")
COPY build.gradle   → 해시: f3  = hash(a1 + "COPY build.gradle" + 파일내용)
RUN gradle deps     → 해시: c9  = hash(f3 + "RUN gradle deps" + 없음)
COPY src/           → 해시: d7  = hash(c9 + "COPY src/" + 소스내용v1)
RUN gradle build    → 해시: b1  = hash(d7 + "RUN gradle build" + 없음)

캐시와 누적

캐시 히트 vs 미스

캐시 히트
---------
동일한 부모 레이어 + 동일한 명령어 + 동일한 입력 -> 기존 레이어 재사용

캐시 미스
---------
하나라도 바뀌면 그 시점부터 "이후 모든 레이어가 새로 생성."