Status | Authors | Coach | DRIs | Owning Stage | Created |
---|---|---|---|---|---|
proposed | - |
이 문서는 작업 중인 문서로 Cells 디자인의 매우 초기 상태를 나타냅니다. 중요한 측면들이 문서화되지 않았지만, 우리는 나중에 이를 추가할 것으로 예상합니다. 이것은 Cells의 한 가지 가능한 아키텍처이며, 우리는 구현할 접근 방법을 결정하기 전에 대안과 대조할 것을 계획하고 있습니다. 이 문서는 이 접근 방법을 선택하지 않았을 경우를 대비하여 선택한 이유를 문서화하기 위해 유지될 것입니다.
Cells: 컨테이너 레지스트리
GitLab 컨테이너 레지스트리는 GitLab에 Docker 컨테이너 이미지를 저장할 수 있는 기능입니다.
1. 정의
GitLab 컨테이너 레지스트리는 PostgreSQL, Redis 및 객체 저장 의존성의 사용을 요구하는 복잡한 서비스입니다. 현재 컨테이너 레지스트리 메타데이터를 도입하여 컨테이너 레지스트리의 데이터 저장 및 이미지 유지 정책을 최적화하기 위한 작업이 진행 중입니다.
GitLab 컨테이너 레지스트리는 저장된 데이터의 컨테이너로 제공되지만, 자체적으로 docker login
을 인증하지는 않습니다. docker login
은 사용자 자격 증명(개인 접근 토큰) 또는 CI 빌드 자격 증명(임시 ci_builds.token
)으로 실행됩니다.
컨테이너 레지스트리는 데이터 중복을 사용합니다. 이는 여러 프로젝트 간에 공유되는 동일한 블롭(이미지 레이어)이 한 번만 저장된다는 것을 의미합니다. 각 레이어는 sha256
로 해싱됩니다.
docker login
은 GitLab에서 서명되지만 레지스트리 서비스에서 유효성을 검사하는 JWT 시간 제한 인증 토큰을 요청합니다. JWT 토큰은 모든 인가된 스코프(컨테이너 레지스트리 이미지
)와 작업 유형(push
또는 pull
)을 저장합니다. 하나의 JWT 인증 토큰에는 여러 인가된 스코프가 있을 수 있습니다. 이를 통해 컨테이너 레지스트리와 클라이언트는 다른 스코프에서 기존 블롭을 마운트할 수 있습니다. GitLab는 인가된 스코프로만 응답합니다. 그런 다음 주어진 작업이 수행될 수 있는지 레지스트리가 유효성을 검사합니다.
GitLab.com 페이지는 항상 프로젝트에 대해 범위가 지정됩니다. 각 프로젝트는 여러 컨테이너 레지스트리 이미지를 첨부할 수 있습니다.
현재 GitLab.com에서는 실제 레지스트리 서비스가 https://registry.gitlab.com
을 통해 제공됩니다.
주요 식별 가능한 문제점은 다음과 같습니다:
- GitLab.com에서 처리되는 인증 요청(
https://gitlab.com/jwt/auth
). - 외부 서비스에서 실행되며 자체 데이터 저장소를 사용하는
https://registry.gitlab.com
. - 데이터 중복. 레지스트리가 셀에서 실행되는 Cells 아키텍처는 데이터 저장의 효율성을 줄일 수 있습니다.
2. 데이터 흐름
2.1. docker login
으로 전송된 인증 요청
curl \
--user "username:password" \
"https://gitlab/jwt/auth?client_id=docker&offline_token=true&service=container_registry&scope=repository:gitlab-org/gitlab-build-images:push,pull"
결과는 인코딩되고 서명된 JWT 토큰입니다. 두 번째 base64로 인코딩된 문자열(구분 기호는 .
로 나뉨)은 인가된 스코프가 포함된 JSON을 포함합니다.
{"auth_type":"none","access":[{"type":"repository","name":"gitlab-org/gitlab-build-images","actions":["pull"]}],"jti":"61ca2459-091c-4496-a3cf-01bac51d4dc8","aud":"container_registry","iss":"omnibus-gitlab-issuer","iat":1669309469,"nbf":166}
2.2. Docker 클라이언트가 태그를 가져오는 중
curl \
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
-H "Authorization: Bearer token" \
https://registry.gitlab.com/v2/gitlab-org/gitlab-build-images/tags/list
curl \
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
-H "Authorization: Bearer token" \
https://registry.gitlab.com/v2/gitlab-org/gitlab-build-images/manifests/danger-ruby-2.6.6
2.3. Docker 클라이언트가 블롭과 매니페스트를 가져오는 중
curl \
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
-H "Authorization: Bearer token" \
https://registry.gitlab.com/v2/gitlab-org/gitlab-build-images/blobs/sha256:a3f2e1afa377d20897e08a85cae089393daa0ec019feab3851d592248674b416
3. 제안
3.1. 컨테이너 레지스트리를 Cells 아키텍처에 별도로 나누기
규모가 크고 일반적으로 엄청난 확장 가능한 수평 아키텍처로 인해 GitLab 컨테이너 레지스트리가 Cell이 아닌 Cluster에서 실행되어 독립적으로 확장되어야 하는지를 평가해야 합니다. 이것은 더 쉬울 수 있지만 동일한 데이터 격리 수준을 제공하지는 않을 것입니다.
3.2. Cell 내에서 컨테이너 레지스트리 실행
컨테이너 레지스트리는 /jwt/auth
를 제외하고는 Router(스코프를 디코딩하기 위해)에서 처리되어야 할 가능성이 높아 보입니다. 실제 데이터는 적어도 GitLab.com의 경우 레지스트리를 통해 전달되지 않고 객체 저장소/CDN에서 직접 제공됩니다.
그 설계는 URL에 컨테이너 레지스트리 이미지를 인코딩하여 쉽게 라우팅할 수 있습니다. 컨테이너 레지스트리 앞에 무상태 Router 서비스를 다시 사용하여 매니페스트 및 블롭을 리디렉션하는 것으로 보입니다.
유일한 단점은 각 Cell에 독립적인 레지스트리를 관리하는 복잡성이 증가하지만, 이것이 원하는 접근 방법일 수 있습니다.
4. 평가
GitLab 컨테이너 레지스트리를 Cell에서 실행하는 데 이론적인 문제가 없어 보입니다. 서비스를 쉽게 라우팅해서 잘 작동할 수 있을 것으로 보입니다. 실제 복잡성은 인프라 측면에서 복잡한 서비스를 관리하는 데 있습니다.