Status | Authors | Coach | DRIs | Owning Stage | Created |
---|---|---|---|---|---|
proposed | - |
이 문서는 작업 중인 문서로, Cells 디자인의 매우 초기 상태를 대표합니다. 중요한 측면들이 문서화되지 않았지만, 향후 추가할 예정입니다. 이는 Cells를 위한 한 가지 아키텍처이며, 우리는 구현할 접근 방법을 결정하기 전에 대안과 대조할 것을 의도하고 있습니다. 이 문서는 이러한 접근 방법을 선택하지 않는 결정을 내린 경우에도 그 이유를 문서화할 수 있도록 유지될 것입니다.
Cells: 컨테이너 레지스트리
GitLab 컨테이너 레지스트리는 Docker 컨테이너 이미지를 GitLab에 저장할 수 있게 해주는 기능입니다.
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
- 데이터 중복. 레지스트리가 Cell에서 실행되는 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"
결과는 인코딩되고 GitLab에서 서명된 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이 아닌 클러스터에서 실행하고 독립적으로 확장할지를 평가해야 합니다. 이것이 더 쉬울 수 있지만, 동일한 데이터 격리 수준을 제공하지는 않을 것입니다.
3.2. Cell 내에서 컨테이너 레지스트리 실행
/jwt/auth
를 디코드하기 위해 라우터에서 처리해야 할 것으로 보이는 것을 제외하고는 컨테이너 레지스트리는 Cell의 로컬 서비스로 실행될 수 있을 것으로 보입니다. 실제 데이터는 적어도 GitLab.com의 경우 레지스트리를 통해 전달되지 않고, 대신 각자 객체 리포지터리 또는 CDN에서 직접 제공됩니다.
그 설계는 URL에 컨테이너 리포지터리 이미지를 인코딩하여 경로를 통해 쉽게 라우팅할 수 있습니다. 컨테이너 레지스트리 앞에 같은 상태를 가진 라우터 서비스를 컨테이너 레지스트리를 위해 매니페스트 및 블록을 리디렉션하는 데 재사용할 수 있을 것으로 보입니다.
단점은 각각의 Cell에 독립된 레지스트리를 관리하는 복잡성이 늘어난다는 것뿐입니다. 그러나 이것은 원하는 접근 방법일 수 있습니다.
4. 평가
GitLab 컨테이너 레지스트리를 Cell에서 실행하는 데 이론적으로 문제가 있는 것으로 보이지는 않습니다. 서비스는 잘 작동하도록 쉽게 경로 지정할 수 있을 것으로 보입니다. 실제 복잡성은 인프라 측면의 복잡한 서비스를 관리하는 데 있습니다.