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