Skip to content

필사 모드: containerd 이미지 관리: OCI 이미지와 스냅샷

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

containerd 이미지 관리: OCI 이미지와 스냅샷

containerd의 이미지 관리 서브시스템은 OCI 이미지 스펙을 기반으로 이미지를 저장, 배포, 언패킹하는 핵심 기능을 담당합니다. 이 글에서는 Content Store, Snapshotter, 이미지 Pull 플로우, 가비지 컬렉션의 내부 동작을 분석합니다.

1. OCI 이미지 스펙

1.1 이미지 구조

OCI 이미지는 세 가지 핵심 구성 요소로 이루어집니다:

OCI 이미지 구조:

1. Image Index (Fat Manifest)

- 여러 플랫폼(linux/amd64, linux/arm64 등)을 지원

- 각 플랫폼별 Manifest를 가리킴

2. Image Manifest

- Config 객체의 다이제스트

- 레이어 목록 (순서 보장)

- 미디어 타입 정보

3. Image Config

- 환경 변수, 엔트리포인트, CMD

- 레이어 diff ID 목록

- 생성 히스토리

1.2 콘텐츠 주소 지정

콘텐츠 주소 지정(Content Addressable Storage):

모든 객체는 SHA256 다이제스트로 식별:

sha256:abc123... -> Image Index JSON

sha256:def456... -> Image Manifest JSON

sha256:789ghi... -> Image Config JSON

sha256:jkl012... -> Layer tar.gz

장점:

- 중복 제거: 동일 레이어는 한 번만 저장

- 무결성 검증: 다이제스트로 데이터 검증

- 캐싱: 다이제스트 기반 캐시 룩업

2. Content Store

2.1 개요

Content Store는 containerd의 콘텐츠 주소 저장소로, 이미지의 모든 바이너리 데이터를 관리합니다.

Content Store 디렉토리 구조:

/var/lib/containerd/io.containerd.content.v1.content/

blobs/

sha256/

abc123... (Image Index)

def456... (Image Manifest)

789ghi... (Image Config)

jkl012... (Layer 1 tar.gz)

mno345... (Layer 2 tar.gz)

ingest/

(임시 다운로드 데이터)

2.2 Content Store API

Content Store 주요 연산:

Info(digest) -> 콘텐츠 메타데이터 조회 (크기, 생성시간)

ReaderAt(digest) -> 콘텐츠 읽기 (io.ReaderAt 인터페이스)

Writer(ref) -> 콘텐츠 쓰기 (원자적 커밋)

Delete(digest) -> 콘텐츠 삭제

ListStatuses() -> 진행 중인 쓰기 작업 조회

Abort(ref) -> 진행 중인 쓰기 작업 취소

2.3 Ingest 프로세스

콘텐츠 쓰기 (Ingest) 프로세스:

1. Writer 생성 (참조 키 할당)

|

v

2. ingest/ 디렉토리에 임시 파일 생성

|

v

3. 데이터 스트리밍 쓰기

(레지스트리에서 레이어 다운로드 등)

|

v

4. 다이제스트 검증

(기대 다이제스트와 실제 데이터 해시 비교)

|

v

5. 원자적 커밋

(ingest/ -> blobs/sha256/ 으로 이동)

|

v

6. 실패 시 ingest/ 에서 정리

3. Snapshotter

3.1 Snapshotter 개요

Snapshotter는 이미지 레이어를 파일시스템 스냅샷으로 관리하는 플러그인입니다. 컨테이너가 사용할 루트 파일시스템을 준비합니다.

Snapshotter 역할:

이미지 레이어 (tar.gz)

|

v

Snapshotter가 각 레이어를 스냅샷으로 변환

|

v

스냅샷을 쌓아서 통합 파일시스템 구성

|

v

컨테이너에 마운트 포인트 제공

3.2 스냅샷 타입

스냅샷 종류:

1. Committed (커밋됨)

- 읽기 전용 스냅샷

- 이미지 레이어에 대응

- 여러 컨테이너가 공유 가능

2. Active (활성)

- 읽기/쓰기 스냅샷

- 컨테이너의 쓰기 가능 레이어

- 하나의 컨테이너에 할당

3.3 overlayfs Snapshotter

가장 널리 사용되는 Snapshotter입니다:

overlayfs 동작:

레이어 1 (base): /snapshots/1/fs (lowerdir)

레이어 2 (app): /snapshots/2/fs (lowerdir)

쓰기 레이어: /snapshots/3/fs (upperdir)

작업 디렉토리: /snapshots/3/work (workdir)

마운트:

mount -t overlay overlay \

-o lowerdir=/snapshots/2/fs:/snapshots/1/fs,\

upperdir=/snapshots/3/fs,\

workdir=/snapshots/3/work \

/container/rootfs

장점:

- Copy-on-Write: 변경 시에만 복사

- 빠른 컨테이너 시작

- 레이어 공유로 디스크 절약

3.4 native Snapshotter

native Snapshotter:

- 각 스냅샷을 독립 디렉토리에 저장

- 부모 스냅샷을 완전히 복사 (hardlink 사용)

- overlayfs를 지원하지 않는 환경에서 사용

- 디스크 사용량이 큼

- 간단하고 이식성이 높음

3.5 devmapper Snapshotter

devmapper Snapshotter:

- Linux device mapper의 thin provisioning 사용

- 블록 레벨 Copy-on-Write

- 고성능 워크로드에 적합

- Firecracker microVM과 함께 사용

- 설정이 복잡함 (thin-pool 사전 구성 필요)

사용 사례:

- AWS Fargate (Firecracker)

- 고성능 컨테이너 환경

- 블록 스토리지 기반 인프라

3.6 Snapshotter API

Snapshotter 주요 연산:

Stat(key) -> 스냅샷 정보 조회

Prepare(key, parent) -> Active 스냅샷 생성 (쓰기 가능)

View(key, parent) -> Committed 스냅샷의 읽기 전용 뷰

Commit(name, key) -> Active 스냅샷을 Committed로 변환

Mounts(key) -> 스냅샷의 마운트 정보 반환

Remove(key) -> 스냅샷 삭제

4. 이미지 Pull 플로우

4.1 전체 플로우

이미지 Pull 전체 과정:

1. 이미지 참조 해석

docker.io/library/nginx:latest

|

v

2. Image Index/Manifest 다운로드

- 레지스트리에서 매니페스트 가져오기

- 플랫폼에 맞는 매니페스트 선택

|

v

3. Config 다운로드

- 이미지 설정 JSON 다운로드

- Content Store에 저장

|

v

4. 레이어 다운로드 (병렬)

- 각 레이어를 Content Store에 저장

- 이미 존재하는 레이어는 건너뜀

|

v

5. 레이어 언패킹

- Content Store에서 레이어 읽기

- Snapshotter로 스냅샷 생성

|

v

6. 이미지 메타데이터 등록

- BoltDB에 이미지 레코드 생성

- 태그와 다이제스트 매핑

4.2 레이어 다운로드 상세

레이어 다운로드:

1. 매니페스트에서 레이어 다이제스트 목록 추출

2. Content Store에 이미 존재하는지 확인

3. 없는 레이어만 레지스트리에서 다운로드

4. Transfer Service가 다운로드 관리:

- 동시 다운로드 제한 (기본 3개)

- 진행 상황 추적

- 재시도 로직

5. 각 레이어는 gzip 압축 상태로 Content Store에 저장

4.3 레이어 언패킹

레이어 언패킹 (Unpack):

1. Content Store에서 레이어 blob 읽기

2. gzip 해제

3. tar 아카이브 추출

4. Snapshotter에 스냅샷 생성:

a. 첫 번째 레이어: 부모 없이 Prepare

b. 레이어 내용을 스냅샷에 적용 (Apply)

c. Commit으로 읽기 전용으로 변환

d. 다음 레이어: 이전 스냅샷을 부모로 Prepare

5. 최종 스냅샷 체인 완성

스냅샷 체인:

Layer 1 (committed) <- Layer 2 (committed) <- Layer 3 (committed)

5. 이미지 메타데이터

5.1 이미지 레코드

이미지 메타데이터 (BoltDB):

이미지 레코드:

- Name: "docker.io/library/nginx:latest"

- Target:

MediaType: "application/vnd.oci.image.index.v1+json"

Digest: "sha256:abc123..."

Size: 1234

- Labels:

"containerd.io/gc.ref.content.0": "sha256:def456..."

"containerd.io/gc.ref.content.1": "sha256:789ghi..."

- CreatedAt: 2026-03-20T00:00:00Z

- UpdatedAt: 2026-03-20T00:00:00Z

5.2 이미지 조회

ctr로 이미지 목록 조회

ctr -n k8s.io images list

이미지 상세 정보

ctr -n k8s.io images check

이미지 콘텐츠 확인

ctr -n k8s.io content get sha256:abc123... | jq .

6. 가비지 컬렉션

6.1 GC 메커니즘

가비지 컬렉션 동작:

1. 루트 객체 식별:

- 이미지 레코드

- 컨테이너 레코드

- Lease 레코드

2. 참조 추적 (Mark):

- 이미지 -> Manifest -> Config + Layers

- 컨테이너 -> 스냅샷 체인

- Lease -> 보호 중인 리소스

3. 미참조 객체 삭제 (Sweep):

- Content Store의 미참조 blob 삭제

- Snapshotter의 미참조 스냅샷 삭제

- 메타데이터의 고아 레코드 정리

6.2 GC 레이블

GC 참조 레이블:

containerd는 GC 참조를 레이블로 관리합니다:

이미지 레이블:

"containerd.io/gc.ref.content.0": "sha256:..." (매니페스트 참조)

"containerd.io/gc.ref.content.1": "sha256:..." (레이어 참조)

콘텐츠 레이블:

"containerd.io/gc.ref.content.config": "sha256:..." (config 참조)

"containerd.io/gc.ref.content.l.0": "sha256:..." (레이어 참조)

스냅샷 레이블:

"containerd.io/gc.ref.snapshot.overlayfs": "sha256:..." (스냅샷 참조)

6.3 Lease

Lease (임대):

- 진행 중인 작업의 리소스를 GC로부터 보호

- 이미지 Pull 중 다운로드된 레이어 보호

- 컨테이너 생성 중 스냅샷 보호

- TTL 기반 자동 만료

- 작업 완료 후 명시적 삭제 가능

예시:

이미지 Pull 시작 -> Lease 생성

레이어 다운로드 -> Lease가 콘텐츠 보호

이미지 등록 완료 -> Lease 삭제 (이미지 레코드가 참조)

6.4 GC 스케줄링

GC 트리거:

1. 주기적 실행:

- containerd 설정의 gc_schedule (기본값 없음)

- 설정 시 cron 표현식으로 주기 지정

2. 이벤트 기반:

- 이미지 삭제 시

- 컨테이너 삭제 시

- API를 통한 명시적 호출

3. ctr을 통한 수동 실행:

ctr -n k8s.io content prune

7. 정리

containerd의 이미지 관리는 Content Store의 콘텐츠 주소 저장, Snapshotter의 레이어 관리, 그리고 GC의 리소스 정리라는 세 축으로 구성됩니다. overlayfs Snapshotter의 Copy-on-Write 메커니즘은 빠른 컨테이너 시작과 효율적인 디스크 사용을 가능하게 하며, Lease 기반 GC 보호는 이미지 작업의 안전성을 보장합니다. 다음 글에서는 containerd의 컨테이너 생명주기 관리를 분석합니다.

현재 단락 (1/231)

containerd의 이미지 관리 서브시스템은 OCI 이미지 스펙을 기반으로 이미지를 저장, 배포, 언패킹하는 핵심 기능을 담당합니다. 이 글에서는 Content Store, Sn...

작성 글자: 0원문 글자: 5,020작성 단락: 0/231