컨테이너 레지스트리의 작동 원리: 이미지 직접 Push/Pull하기
요약
컨테이너 레지스트리의 내부 동작 원리와 OCI Distribution Specification 기반의 API 구조를 설명합니다. 이미지의 Push/Pull 과정, 콘텐츠 주소 지정 방식의 Blob 저장소 활용, 그리고 멀티 플랫폼 이미지 구현 방식을 다룹니다.
핵심 포인트
- 레지스트리는 Digest를 주소로 사용하는 콘텐츠 주소 지정 방식의 Blob 저장소임
- 이미지 Push는 레이어 및 설정 Blob 업로드 후 Manifest를 생성하는 순서로 진행됨
- 이미지 Pull은 Manifest를 먼저 조회한 뒤 명시된 Digest로 Blob을 다운로드함
- 단순 태그 삭제만으로는 실제 Blob이 제거되지 않으므로 주의가 필요함
- 현대 Manifest는 LLM 가중치 등 다양한 아티팩트를 담는 범용 저장소로 활용됨
컨테이너 레지스트리는 겉보기엔 단순하지만, 잘못된 태그, 플랫폼 불일치, 레이어 누락, 실제 삭제 실패 같은 문제를 디버깅하려면 내부 동작 원리를 반드시 이해해야 함
- 레지스트리의 핵심은
콘텐츠 주소 지정 방식(content-addressable) blob 저장소로, 모든 레이어·설정 파일·아티팩트는 digest를 주소로 삼아 저장됨 - 이미지 push는 blob 업로드 후
manifest로 묶는 순서로 진행되고, pull은 manifest를 먼저 받아 blob을 순차적으로 내려받는 역순 구조임
이미지 삭제는 단순 언태그만으로는 완전 제거가 되지 않으며, 다른 manifest에서 공유 중인 레이어를 먼저 확인한 뒤 blob까지 직접 삭제해야 함
멀티 플랫폼 이미지는 기존 API 엔드포인트를 그대로 유지하면서 image index(manifest list)라는 추가 간접 계층 하나만 도입해 구현됨
Registry API 개요
- 현대 컨테이너 레지스트리 대부분은
OCI Distribution Specification을 구현하며, 이 스펙은 콘텐츠 배포를 표준화하는 API 프로토콜을 정의함 - Registry API는 실제로 간결하고 이해하기 쉬우며,
curl
만으로도 충분히 직접 조작 가능
Blob 업로드 및 다운로드
- 레지스트리는 본질적으로
콘텐츠 주소 지정 blob 저장소로, 파일을 로컬에서 해싱한 뒤 digest를 주소로 사용해 업로드함 - 가장 단순한 업로드 방식은
Monolithic PUT 방식으로,POST
로 세션을 초기화한 뒤 PUT
으로 blob을 전송하는 2단계 구조
- 대용량 파일에는
POST + PATCH + PUT
청크 업로드 방식이 더 효율적이나, 소형 blob의 경우 Monolithic PUT으로 충분
- 업로드 성공 시
HTTP/2 201 Created
응답과 함께 새 blob의 위치를 가리키는 Location
헤더가 반환됨
- 다운로드는 digest만 알면
GET /v2/<repo>/blobs/<digest>
로 바로 수행 가능
이미지 Push
- 이미지 push 절차: (1) 각
rootfs 레이어 blob 업로드 → (2) image configuration blob 업로드 → (3) 모든 digest를 하나의 JSON 문서로 묶는 manifest 파일 push - manifest는
PUT /v2/<repo>/manifests/<tag>
엔드포인트로 업로드하며, 이 시점에 태그가 생성됨
- 실제 클라이언트(예:
docker push
)는 blob 업로드를 병렬로 수행하나, 원리 이해를 위해 순차 처리도 가능
- 이미지 디렉터리 구성 예시:
config.json
, layer-1.tar.gz
, layer-2.tar.gz
, manifest.json
태그 목록 조회
GET /v2/<repo>/tags/list
엔드포인트로 특정 레포지터리의 모든 태그 목록 조회 가능
- 이 기능은
docker
CLI에서는 노출되지 않으며, curl
또는 crane
, regctl
같은 도구로만 접근 가능
crane
, regctl
은 동일 엔드포인트를 ls
명령으로 래핑한 것
이미지 Pull
- pull 절차는 push의 역순: (1)
GET /v2/<repo>/manifests/<tag>
로 manifest 조회 → (2) manifest에 명시된 digest로 모든 blob 다운로드
- 현대 manifest는 rootfs 레이어·이미지 설정 외에도
Helm 차트, SBOM, 출처 증명(provenance attestation), LLM 가중치 등 임의 아티팩트를 blob으로 참조하는 범용 저장소로도 활용됨
이미지 삭제
- 이미지 삭제는 단순하지 않으며,
태그 제거(언태그)만으로는 manifest 자체가 삭제되지 않음 - 완전 삭제 절차:
- (1)
DELETE /v2/<repo>/manifests/<tag>
로 태그 제거
- (2) manifest를 digest로 조회해 참조 중인 모든 blob 확인
- (3)
다른 manifest에서 공유 중이지 않은 blob만 선택적으로 삭제 - (4)
DELETE /v2/<repo>/blobs/<manifest-digest>
로 manifest blob 삭제
- 레지스트리는 콘텐츠 주소 지정 저장소이므로, 동일한 rootfs 레이어를 여러 이미지가 공유할 수 있으며, 삭제 시 해당 레이어를 참조하는
모든 이미지에 영향을 줌 - 대안으로 모든 태그를 제거한 뒤 레지스트리의
가비지 컬렉션(garbage collection) 설정에 의존하는 방법도 있으나, 공용 레지스트리에서는 항상 활성화되어 있지 않음
멀티 플랫폼 이미지
- 멀티 플랫폼 이미지는
레지스트리 API 구조 변경 없이 구현됨 — 엔드포인트 추가·수정 없이 기존 API를 그대로 활용 - 구성 방식:
- 각 단일 플랫폼 변형(amd64, arm64 등)을 개별 manifest와 함께
digest 기반으로 먼저 push - 이후
image index(manifest list) 라 불리는 상위 manifest를 태그와 함께 push
GET /v2/<repo>/manifests/<tag>
호출 시 단일 플랫폼 manifest 또는 image index 중 하나가 반환되며, 호출자는 반환된 문서의 content type으로 구분해야 함
- 결과적으로 멀티 플랫폼 지원은 기존 구조에
간접 계층 하나와 index 문서 업로드/다운로드 단계 하나만 추가한 것
레지스트리 API 보호
- OCI Distribution Spec은 인증 방식을 엄격히 정의하지 않으나, 대부분의 실제 레지스트리는
HTTP Basic 인증을 사용 - 자격증명이 평문으로 전송되는 것을 막기 위해 반드시
HTTPS 위에서 운영해야 함
댓글과 토론
AI 자동 생성 콘텐츠
본 콘텐츠는 RSS: GeekNews (한국어)의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기