This page contains information related to upcoming products, features, and functionality. It is important to note that the information presented is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. The development, release, and timing of any products, features, or functionality may be subject to change or delay and remain at the sole discretion of GitLab Inc.
Status Authors Coach DRIs Owning Stage Created
proposed -

이 문서는 진행 중인 작업이며 Cells 설계의 매우 초기 상태를 나타냅니다. 중요한 측면들이 문서화되지 않은 채로 남아 있지만, 우리는 나중에 이를 추가할 것으로 예상합니다. Cells를 위한 하나의 가능한 아키텍처이며, 구현할 접근 방식을 결정하기 전에 대안과 대조할 계획입니다. 이 문서는 Cells 설계를 구현하지 않기로 결정한 경우에도 이 설계를 선택하지 않은 이유를 문서화하기 위해 유지될 것입니다.

Cells: Git Access

이 문서에서는 Cells 아키텍처가 모든 Git 액세스(HTTPS 및 SSH) 패턴에 미치는 영향을 설명하며, 이러한 기능이 Cells와 원활하게 작동하도록 변경되어야 하는 방법을 설명합니다.

1. 정의

Git 액세스는 애플리케이션 전반에서 이루어집니다. 이는 시스템(깃 리포지터리 읽기) 또는 사용자(웹 IDE를 통한 새 파일 작성, 명령줄을 통한 git clone 또는 git push)에 의해 수행될 수 있습니다. Cells 아키텍처는 모든 Git 리포지터리가 Cell 내부에 로컬로 정의된다는 것을 의미하며, 그러므로 어떤 리포지터리도 다른 Cell과 공유되지 않을 것입니다.

Cells 아키텍처는 모든 Git 작업이 데이터를 보유하는 Cell에 의해서만 처리될 수 있도록 요구합니다. 즉, 웹 인터페이스, API 또는 GraphQL을 통한 모든 작업은 올바른 Cell로 라우팅되어야 합니다. 즉, git clone 또는 git push 작업은 반드시 Cell의 문맥 내에서만 수행될 수 있음을 의미합니다.

2. 데이터 흐름

GitLab에서는 현재 깃 리포지터리에 대해 다양한 작업이 수행됩니다. 이는 현재 동작하는 방식을 더 잘 나타내기 위해 데이터 흐름을 설명합니다.

현재 Git 액세스는 여러 프로젝트에 대한 범위가 지정된 몇 가지 엔드포인트에 대한 변경을 요구하는 것으로 보입니다. 다양한 유형의 리포지터리가 있는 것으로 보입니다:

  • 프로젝트: 그룹에 할당됨
  • 위키: 프로젝트에 할당된 추가적인 리포지터리
  • 디자인: 위키와 유사하게, 프로젝트에 할당된 추가적인 리포지터리
  • 스니펫: 리포지터리를 보유하기 위한 가상 프로젝트를 생성하며, 아마도 사용자에게 연결됨

2.1. HTTPS를 통한 Git Clone

git clone을 HTTPS를 통해 실행

sequenceDiagram User ->> Workhorse: GET /gitlab-org/gitlab.git/info/refs?service=git-upload-pack Workhorse ->> Rails: GET /gitlab-org/gitlab.git/info/refs?service=git-upload-pack Rails ->> Workhorse: 200 OK Workhorse ->> Gitaly: RPC InfoRefsUploadPack Gitaly ->> User: Response User ->> Workhorse: POST /gitlab-org/gitlab.git/git-upload-pack Workhorse ->> Gitaly: RPC PostUploadPackWithSidechannel Gitaly ->> User: Response

2.2. SSH를 통한 Git Clone

git clone을 SSH를 통해 실행

sequenceDiagram User ->> Git SSHD: ssh git@gitlab.com Git SSHD ->> Rails: GET /api/v4/internal/authorized_keys Rails ->> Git SSHD: 200 OK (수락된 SSH 키 디렉터리) Git SSHD ->> User: SSH 수락 User ->> Git SSHD: SSH를 통한 git clone Git SSHD ->> Rails: POST /api/v4/internal/allowed?project=/gitlab-org/gitlab.git&service=git-upload-pack Rails ->> Git SSHD: 200 OK Git SSHD ->> Gitaly: RPC SSHUploadPackWithSidechannel Gitaly ->> User: 응답

2.3. HTTPS를 통한 Git Push

git push를 HTTPS를 통해 실행

sequenceDiagram User ->> Workhorse: GET /gitlab-org/gitlab.git/info/refs?service=git-receive-pack Workhorse ->> Rails: GET /gitlab-org/gitlab.git/info/refs?service=git-receive-pack Rails ->> Workhorse: 200 OK Workhorse ->> Gitaly: RPC PostReceivePack Gitaly ->> Rails: POST /api/v4/internal/allowed?gl_repository=project-111&service=git-receive-pack Gitaly ->> Rails: POST /api/v4/internal/pre_receive?gl_repository=project-111 Gitaly ->> Rails: POST /api/v4/internal/post_receive?gl_repository=project-111 Gitaly ->> User: Response

2.4. SSH를 통한 Git Push

git clone을 SSH를 통해 실행

sequenceDiagram User ->> Git SSHD: ssh git@gitlab.com Git SSHD ->> Rails: GET /api/v4/internal/authorized_keys Rails ->> Git SSHD: 200 OK (수락된 SSH 키 디렉터리) Git SSHD ->> User: SSH 수락 User ->> Git SSHD: SSH를 통한 git clone Git SSHD ->> Rails: POST /api/v4/internal/allowed?project=/gitlab-org/gitlab.git&service=git-receive-pack Rails ->> Git SSHD: 200 OK Git SSHD ->> Gitaly: RPC ReceivePack Gitaly ->> Rails: POST /api/v4/internal/allowed?gl_repository=project-111 Gitaly ->> Rails: POST /api/v4/internal/pre_receive?gl_repository=project-111 Gitaly ->> Rails: POST /api/v4/internal/post_receive?gl_repository=project-111 Gitaly ->> User: Response

2.5. 웹을 통한 커밋 생성

리포지터리에 CHANGELOG 추가 실행:

sequenceDiagram Web ->> Puma: POST /gitlab-org/gitlab/-/create/main Puma ->> Gitaly: RPC TreeEntry Gitaly ->> Rails: POST /api/v4/internal/allowed?gl_repository=project-111 Gitaly ->> Rails: POST /api/v4/internal/pre_receive?gl_repository=project-111 Gitaly ->> Rails: POST /api/v4/internal/post_receive?gl_repository=project-111 Gitaly ->> Puma: 응답 Puma ->> Web: CHANGELOG 확인

3. 제안

Cells 무상태 라우터 제안에 따르면, 애매한 경로(라우팅할 수 없는)는 라우팅 가능하게 만들어야 합니다. 적어도 다음 경로 중 하나는 라우팅 가능한 엔터티(프로젝트, 그룹 또는 조직)를 소개하기 위해 업데이트해야 할 것입니다.

변경:

  • /api/v4/internal/allowed => /api/v4/internal/projects/<gl_repository>/allowed
  • /api/v4/internal/pre_receive => /api/v4/internal/projects/<gl_repository>/pre_receive
  • /api/v4/internal/post_receive => /api/v4/internal/projects/<gl_repository>/post_receive
  • /api/v4/internal/lfs_authenticate => /api/v4/internal/projects/<gl_repository>/lfs_authenticate

여기서:

  • gl_repositoryproject-1111일 수 있습니다 (Gitlab::GlRepository)
  • 경우에 따라 gl_repository는 GitLab Shell에 의해 실행되는 리포지터리의 전체 경로일 수 있습니다 (/gitlab-org/gitlab.git)

4. 평가

Cell이 자체 리포지터리에만 접근할 수 있는 경우, Git 리포지터리를 지원하는 것이 복잡해 보이지 않습니다. 주요한 복잡함은 스니펫의 지원이지만, 아마도 이는 사용자의 개인 네임스페이스를 지원하는 방법과 비슷한 범주에 속할 것입니다.

4.1. 장점

  1. HTTPS/SSH 및 후크를 지원하는 데 사용되는 API는 명확하게 정의되어 있으며 쉽게 라우팅 가능할 수 있습니다.

4.2. 단점

  1. 리포지터리 객체의 공유는 주어진 Cell 및 Gitaly 노드로 제한됩니다.
  2. Cell 간의 포크는 아마 지원할 수 없을 것으로 예상됩니다 (이것이 서로 다른 Gitaly 노드 간에 어떻게 작동하는지 확인: 오늘의 동작 방식 찾기).

5. 포킹 및 객체 풀

Cells 아키텍처에서 다룰 필요가 있는 가장 큰 문제 중 하나는 포킹을 어떻게 다룰 지입니다. 현재 Gitaly는 포크 리포지터리의 중복을 제공하기 위해 객체 풀을 활용합니다. 만약 포크가 원본 리포지터리가 아닌 다른 리포지터리 노드에 생성되면, 우리는 사실상 리포지터리의 두 완전한 사본을 사용하게 되어 저장 공간의 비효율성을 유발하며 성능을 향상시키기 위해 객체 풀을 활용할 수 없게 됩니다.

한 Cell의 리포지터리 노드는 다른 Cell의 리포지터리 노드와 통신할 수 없으므로, Cell 간 포킹은 불가능할 것입니다. 따라서 포크된 리포지터리가 원본 부모 리포지터리와 동일한 Cell (및 동일한 Gitaly 노드)에 위치하도록 보장해야 합니다. 이렇게 하면 Gitaly가 여전히 리포지터리 및 성능 효율성을 제공하기 위해 객체 풀을 활용할 수 있게 될 것입니다.

5.1. 현재 작업 방식

단일 Gitaly 리포지터리 노드

현재, 단일 Gitaly 리포지터리 노드로 지원되는 GitLab 인스턴스의 경우, 포킹은 잘 작동합니다. 모든 포크는 같은 리포지터리 노드에 있어야 하므로, 따라서 객체 중복 제거 (및 객체 풀)가 모두 예상대로 작동합니다.

분할된 Gitaly 리포지터리

분할된 Gitaly 리포지터리는 여러 Gitaly 리포지터리 노드가 단일 인스턴스에 연결되고, 노드 간의 우선 순위 가중치에 따라 리포지터리가 할당되는 경우입니다.

Gitaly가 크로스-스토리지 검색을 수행하는 방법을 알고 있기 때문에 분할된 리포지터리 간에 포킹하는 것은 문제없이 작동합니다.

Gitaly 클러스터

Gitaly 클러스터의 경우, 최근에 이 문제를 해결했습니다. 부모 리포지터리와 같은 리포지터리 노드에 객체 풀이 생성되지 않는 문제를 해결했습니다. 이를 통해 효율 적인 측면에서 포킹이 제대로 작동하고 (객체 풀을 공유 할 수 있음) 객체 중복 제거 측면에서도 제대로 작동합니다 (Git가 저장 공간을 적절하게 중복 처리할 수 있음).