Status | Authors | Coach | DRIs | Owning Stage | Created |
---|---|---|---|---|---|
proposed | - |
이 문서는 작업 중인 문서로 매우 초기 상태의 Cells 설계를 대표합니다. 중요한 측면들이 문서화되지 않았지만, 향후 추가할 예정입니다. 이는 Cells의 하나의 가능한 아키텍처이며, 이를 구현할 접근 방법을 결정하기 전에 대안과 대조할 계획입니다. 이 접근 방법을 선택하지 않기로 결정해도, 선택한 이유를 문서화하기 위해 이 문서를 유지할 것입니다.
Cells: CI 러너
GitLab은 GitLab Runner를 통해 CI 작업을 실행하며, 이러한 Runner는 많은 경우에 고객들이 자사 인프라에서 관리합니다. CI 파이프라인의 일부로 생성된 모든 CI 작업은 프로젝트의 맥락에서 실행됩니다. 이는 GitLab 러너를 어떻게 관리할지에 대한 도전 과제를 제기합니다.
1. 정의
3가지 유형의 러너가 있습니다:
- 인스턴스 전역: 특정 태그 (선택 기준)로 전역적으로 등록된 러너
- 그룹 러너: 특정 최상위 그룹 또는 해당 그룹 내의 프로젝트에서 작업을 실행하는 러너
- 프로젝트 러너: 하나의 프로젝트 또는 여러 프로젝트에서 작업을 실행하는 러너: 일부 러너는 서로 다른 최상위 그룹 내의 프로젝트에서 프로젝트를 할당받을 수 있습니다.
이는 ci_runners
가 모든 유형의 러너를 설명하는 테이블인 기존 데이터 구조와 함께, ci_runners
를 Cells 환경에서 어떻게 관리해야 하는지에 대한 도전 과제를 제기합니다.
2. 데이터 흐름
GitLab 러너는 전역 범위의 엔드포인트를 사용하여 다음을 수행합니다:
-
https://gitlab.com/api/v4/runners
를 통해 등록 토큰 (registration token
)을 사용하여 새 러너를 등록합니다. (제거 대상) - 사용자의 맥락에서 새 러너를 생성합니다 (
runner token
):https://gitlab.com/api/v4/user/runners
- 인증된
https://gitlab.com/api/v4/jobs/request
엔드포인트를 통해 작업을 요청합니다 (runner token
) -
https://gitlab.com/api/v4/jobs/:job_id
를 통해 작업 상태를 업로드합니다 (build token
) -
https://gitlab.com/api/v4/jobs/:job_id/trace
를 통해 트레이스를 업로드합니다 (build token
) -
https://gitlab.com/api/v4/jobs/:job_id/artifacts
를 통해 아티팩트를 다운로드하고 업로드합니다 (build token
)
현재 3가지 유형의 인증 토큰이 사용됩니다:
- 러너 등록 토큰 (제거 대상)
- 특정 구성 (태그, 잠금 등) 시스템 내에서 등록된 러너를 나타내는 러너 토큰
- 특정 작업을 업데이트하거나 아티팩트를 업로드하고, 종속된 아티팩트를 다운로드하고, 컨테이너 레지스트리 이미지를 다운로드하고 업로드할 수 있는 일회성 토큰을 나타내는 빌드 토큰
이러한 엔드포인트 각각은 헤더를 통해 (트레이스의 경우 JOB-TOKEN
) 또는 본문 매개변수를 통해 (token
: 다른 모든 엔드포인트) 인증 토큰을 수신합니다.
CI 파이프라인은 특정 Cell의 맥락에서 만들어질 것이므로, 특정 Cell에 의해 처리되어야 하는 빌드 피킹이 필요할 것입니다. 이는 다음과 같은 솔루션에 따라 빌드 피킹이 처리되어야 할 것을 요구합니다:
- 처음에 올바른 Cell로 라우트되어야 함
- 두 단계로 처리해야 함: 글로벌 풀에서 빌드를 요청하고, Cell별 URL을 사용하여 특정 Cell에서 빌드를 클레임해야 함
3. 제안
3.1. 인증 토큰
CI 러너들의 경로가 라우팅 가능하지는 않지만, 다음 두 가지 가능한 솔루션으로 라우트 가능하게 만들 수 있습니다:
-
https://gitlab.com/api/v4/jobs/request
은 롱 폴링 메커니즘과 티켓팅 메커니즘을 사용합니다 (X-GitLab-Last-Update
헤더에 기반). 러너가 처음 시작되면 GitLab에 요청을 보내어 GitLab이 러너가 선택할 빌드를 응답합니다. 이 값은 완전히 GitLab에서 제어됩니다. 이를 통해 GitLab은cell
식별자를 인코딩할 수 있는 JWT 또는 다른 수단을 사용하여 쉽게 디코딩할 수 있는 토큰을 인코딩할 수 있습니다. - 통신의 대부분 (체적 측면)은
build token
을 사용하므로, 러너가 나중에 특정 작업에 대한 업데이트를 제한적으로 수행하기 위해 사용하는 토큰을 GitLab이 단독 소유하고 있으므로 변경 가능한 대상입니다.build token
을 저장하는 대신 정의된 스코프가 있는JWT
토큰을 사용하는 것이 더 바람직하다는 이전 토론이 있었습니다. 이러한 토큰은 Router가 모든 요청을 라우팅할 수 있도록 러너 토큰을 디코딩하는 훨씬 강력한 방법을 제공할 수 있습니다.
3.2. 요청 본문
- 가장 많이 사용되는 엔드포인트들은 요청 본문에 인증 토큰을 전달합니다. Router가 요청을 프록시할 필요없이 이러한 정보에 쉽게 액세스하기 위해 HTTP 헤더를 사용하는 것이 바람직할 수 있습니다.
3.3. 인스턴스 전역은 Cell 로컬
모든 러너가 항상 특정 Cell에 대해 로컬로 등록되고 있는 설계를 선택할 수 있습니다:
- 각 Cell은 자체 인스턴스 전역 러너 세트를 자체 속도로 업데이트합니다.
- 프로젝트 러너는 동일한 조직의 프로젝트에만 연결될 수 있으므로 강력한 격리가 생성됩니다.
- 이 모델에서
ci_runners
테이블은 Cell에 로컬입니다. - 이 모델에서 상기 엔드포인트를 어떤 방식으로든 Cell에 대해 범위가 지정되었거나 라우팅 가능하게 만들어야 합니다. 이를 위해 접두어를 붙이거나 추가적인 Cell 매개변수를 추가하거나 러너 토큰을 디코딩하고 Cell에 매칭할 수 있는 훨씬 강력한 방법을 제공할 수 있을 것입니다.
- 라우팅 가능한 토큰이 사용된다면, 데이터베이스에 저장된 암호화된 무작위 값을 사용하는 것 대신 JWT 토큰을 사용하는 것이 더 바람직합니다.
- 등록된 러너를 표시하는 관리자 영역은 특정 Cell에 대해 범위가 있어야 합니다.
이 모델은 강력한 격리 보장으로 인해 바람직할 수 있습니다. 이 모델은 각 Cell이 별도로 관리되기 때문에 유지 관리 부담이 크게 증가합니다. 이 모델은 각 Cell마다 별도로 관리되기 때문에 유지 관리 부담이 크게 증가할 수 있으며, Projects가 Cells 간에 일관된 러너 경험을 갖도록 조정이 필요할 수 있습니다.
3.4. 인스턴스 전체는 클러스터 전체입니다.
모든 러너가 셀 로컬인 제안과는 달리, 러너를 전역적이거나 단순히 인스턴스 전체 러너로 간주할 수 있습니다.
그러나, 이를 위해서는 시스템을 상당히 전면적으로 개편해야 하며, 다음 측면을 변경해야 합니다:
-
ci_runners
테이블은 아마도ci_instance_runners
로 분해해야 할 것입니다. - 모든 인터페이스는 올바른 테이블을 사용하도록 채택해야 합니다.
- 빌드 대기열은 각 셀이 모든 보류중인 및 실행 중인 빌드를 알고 있지만, 실제 빌드 요청은 데이터를 포함하는 셀에 대해 진행될 수 있도록 두 단계로 재작업되어야 합니다.
-
ci_pending_builds
및ci_running_builds
이클러스터 전체
테이블로 만들어져야 하므로 CI 큐잉과 관련된 시스템에서 핫스팟 생성 가능성이 높아질 것으로 예상됩니다.
이 모델은 엔지니어링적인 관점에서 구현이 복잡합니다. 일부 데이터는 셀 간에 공유됩니다. 다른 셀에 있는 조직의 경험에 영향을 줄 수 있는 시스템의 핫스팟/확장성 문제를 초래합니다.
3.5. GitLab CI 데몬
탐색할 수 있는 다른 잠재적인 해결책은, 전용 서비스를 갖고 빌드 대기열을 관리하고 해당 서비스가 자체 데이터베이스를 소유하며 병목 혹은 셀 기반의 서비스 모델로 작동하는 것입니다. 이전에 CI/CD 데몬에 대한 토론이 있었습니다.
서비스가 샤딩될 경우:
- 모델에 따라, 러너가 클러스터 전체인지 셀 로컬인지에 따라 이 서비스는 모든 셀에서 데이터를 가져와야 할 것입니다.
- 샤딩된 서비스를 사용하면 해당 서비스와
ci_pending_builds/ci_running_builds
를 포함한 데이터베이스를 공유하는 모델을 채택할 수 있습니다. - 샤딩된 서비스를 사용하면 각 셀이 러너가 잡아야 하는 빌드를 CI/CD 데몬으로 푸시하는 푸시 모델을 고려해볼 수 있습니다.
- 샤딩된 서비스는 특정 빌드를 처리하기 위해 지정된 셀로 처리 요청을 라우팅할 수 있는 방법을 갖고 있을 것입니다.
서비스가 셀 기반일 경우:
- 모든 라우터 가능한 엔드포인트의 기대는 여전히 유효합니다.
CI 데몬의 일반적인 사용은 명시된 문제에 크게 도움이 되지 않습니다. 그러나 이는 효율적인 처리와 결합 모델과 관련하여 몇 가지 이점을 제공합니다: 푸시 모델과 GitLab 러너와의 상태있는 통신 제공의 길을 열어줍니다 (예: gRPC 또는 웹소켓).
4. 평가
모든 옵션을 고려할 때, 가장 유망한 솔루션으로 보이는 것은 다음과 같습니다:
- 인스턴스 전체는 셀 로컬입니다
- 엔드포인트를 더 정교하게 만들어 경로나 더 나은 토큰을 통해 라우터 가능한 식별자를 갖도록 개선합니다.
다른 잠재적 이점은 ci_builds.token
을 없애고 대신 CI 러너에서 허용되는 더 넓은 범위의 스코프를 더 잘 쉽게 인코딩할 수 있는 JWT 토큰
을 사용할 수 있다는 것입니다.