1P by neo 4달전 | favorite | 댓글 1개

S3를 컨테이너 레지스트리로 사용하기

  • 지난 4개월 동안 Outerbounds와 협력하여 커스텀 컨테이너 이미지 빌더를 개발해왔음
  • S3를 컨테이너 레지스트리로 사용할 수 있다는 사실을 발견했음
  • S3 버킷을 HTTP로 노출하고 특정 경로에 이미지를 업로드하면 docker pull 명령어로 이미지를 가져올 수 있음

데모

  • cowsay를 실행하는 컨테이너 이미지를 만들어 S3 버킷에 업로드했음
  • R2를 사용하여 무료 egress를 제공함
  • R2와 S3는 API 호환이 가능함
$ docker run --rm pub-40af5d7df1e0402d9a92b982a6599860.r2.dev/cowsay

왜 S3를 사용할까?

  • 전통적으로 DockerHub, GitHub Container Registry, ECR 등을 사용함
  • S3는 업로드 속도에서 큰 이점을 가짐
  • ECR과 S3의 업로드 속도를 비교한 결과, S3가 최대 8배 더 빠름

S3가 더 빠른 이유

  • S3는 단일 레이어의 청크를 병렬로 업로드할 수 있음
  • ECR은 OCI Distribution Spec을 준수하여 순차적으로 업로드해야 함
  • 병렬 업로드가 불가능한 ECR은 대역폭을 충분히 활용하지 못함

S3는 컨테이너 레지스트리가 아님

  • S3는 엄밀히 말해 컨테이너 레지스트리가 아님
  • docker pull 명령어는 HTTP 요청을 통해 파일을 다운로드함
  • S3 버킷을 적절히 구성하면 컨테이너 레지스트리로 사용할 수 있음

주의사항

  • 이 방법은 매우 실험적임
  • 기존 컨테이너 레지스트리의 기능을 제공하지 않음 (예: 보안 스캔, 접근 제어 등)
  • 추가 연구가 필요함

PS. 고래는?

  • Docker 로고를 참고하라는 농담임

GN⁺의 정리

  • 이 글은 S3를 컨테이너 레지스트리로 사용하는 방법을 설명함
  • S3의 빠른 업로드 속도를 활용할 수 있음
  • 기존 컨테이너 레지스트리의 기능을 제공하지 않으므로 주의가 필요함
  • 실험적이지만 흥미로운 접근 방식임
  • 비슷한 기능을 제공하는 다른 프로젝트로는 DockerHub, GitHub Container Registry, ECR 등이 있음
Hacker News 의견
  • OCI Distribution 스펙이 정적 파일을 지원하면 좋겠다는 의견이 있음

    • 단순한 HTTP 서버나 파일 프로토콜을 직접 사용할 수 있게 됨
    • 모든 메타데이터가 매니페스트에 이미 포함되어 있음
    • Content-Type: octet-stream이 잘 작동할 수 있음
  • OCI Distribution 스펙이 잘 설계되지 않았다는 의견이 있음

    • 레이어 푸시는 순차적으로 이루어져야 함
    • DockerHub와 GHCR에서 청크 업로드가 제대로 작동하지 않음
    • Content-Range 값 형식이 RFC7233 형식과 일치하지 않음
    • 태그 목록의 페이지네이션 표준화 기회를 놓쳤음
  • Cloudflare가 R2를 사용한 컨테이너 레지스트리 서버를 오픈소스화 했다는 정보가 있음

    • 사용해본 사람이 있는지 궁금해함
  • OCI 스펙에서 레이어 푸시가 순차적으로 이루어져야 하는 이유를 알고 싶다는 의견이 있음

    • 단일 레이어의 내용을 순차적으로 푸시해야 함
    • 여러 레이어를 병렬로 푸시하는 것은 가능함
  • Nexus를 사용하는 이유와 장단점에 대한 의견이 있음

    • 다양한 패키지와 레포지토리를 지원함
    • 설정과 리소스 사용이 번거로움
    • Docker pull 요청이 단순한 HEAD와 GET 요청으로 이루어져 있음
    • 더 간단한 컨테이너 레지스트리가 부족하다는 점에 놀람
  • CNCF의 Distribution이 Cloudfront 서명된 URL을 통해 S3에서 레지스트리를 백업하는 기능을 지원한다는 정보가 있음

  • S3와 R2의 비용에 대한 언급이 없어서 아쉽다는 의견이 있음

  • ECR이 이미지 레이어를 여러 부분으로 업로드하는 것을 지원한다는 정보가 있음

    • 관련 API:
      • InitiateLayerUpload API: 각 이미지 레이어 업로드 시작 시 호출
      • UploadLayerPart API: 각 레이어 청크 업로드 시 호출 (최대 20MB)
      • PutImage API: 레이어 업로드 후 이미지 매니페스트 푸시 시 호출
    • 레이어 청크를 base64 인코딩으로 업로드해야 하는 점이 이상함
  • Docker의 Registry에 대한 불만이 있음

  • 개인 컨테이너 레지스트리의 존재 이유를 이해하지 못하겠다는 의견이 있음

    • 단순히 이미지 파일을 생성하여 관리하는 것이 더 나을 수 있음