CI/CD 개발 가이드라인
GitLab v19.2요약
CI/CD 파이프라인은 GitLab 개발 및 배포 프로세스의 핵심 구성 요소로, 코드 변경 사항의 빌드, 테스트, 배포와 같은 작업을 자동화합니다. 이 문서는 CI/CD 파이프라인을 안전하고 효과적으로 사용하는 기능을 개발하는 데 도움이 되는 가이드라인을 제공합니다.
CI/CD 파이프라인은 GitLab 개발 및 배포 프로세스의 핵심 구성 요소로, 코드 변경 사항의 빌드, 테스트, 배포와 같은 작업을 자동화합니다. 파이프라인과 상호작용하거나 파이프라인을 트리거하는 기능을 개발할 때는 이러한 작업이 시스템의 보안 및 운영 무결성에 미치는 광범위한 영향을 반드시 고려해야 합니다.
이 문서는 CI/CD 파이프라인을 안전하고 효과적으로 사용하는 기능을 개발하는 데 도움이 되는 가이드라인을 제공합니다. 파이프라인 실행의 영향을 이해하고, 인증 토큰을 책임감 있게 관리하며, 개발 초기부터 보안 고려 사항을 통합하는 것의 중요성을 강조합니다.
일반 가이드라인#
-
파이프라인을 쓰기 작업으로 인식: 파이프라인을 트리거하는 것은 시스템 상태를 변경하는 쓰기 작업입니다. 쓰기 작업은 배포를 시작하거나, 테스트를 실행하거나, 구성을 변경할 수 있습니다. 무단 변경이나 시스템 남용을 방지하기 위해 파이프라인 트리거를 다른 중요한 쓰기 작업과 동일한 수준으로 신중하게 다루세요.
-
파이프라인 실행은 명시적인 작업이어야 함: 사용자 컨텍스트에서 파이프라인을 생성하는 작업은 사용자가 해당 작업을 수행할 때 파이프라인(또는 단일 job)이 시작된다는 것을 명확히 알 수 있도록 설계되어야 합니다. 사용자는 파이프라인에서 실행되는 변경 사항이 실행되기 전에 이를 인지해야 합니다.
-
원격 실행 및 격리: CI/CD 파이프라인은 job이 광범위한 작업을 수행하는 스크립트를 실행할 수 있는 원격 실행 환경으로 기능합니다. job이 적절히 격리되어 있으며 민감한 데이터나 시스템이 의도치 않게 노출되지 않도록 보장하세요.
-
AppSec 및 Verify 팀과 협업: 설계 프로세스 초기 및 제안서 작성 시 Application Security (AppSec)와 Verify 팀원을 참여시키세요. 이들의 전문 지식은 잠재적인 보안 위험을 식별하고 기능 초기부터 보안 고려 사항이 통합되도록 도움을 줍니다. 또한 취약점 식별 및 보안 표준 준수에 관한 전문 지식을 활용하기 위해 코드 리뷰 프로세스에도 참여시키세요.
-
파이프라인 행위자 파악: 파이프라인을 트리거하는 기능을 구축할 때는 어떤 사용자가 파이프라인을 시작하는지 고려하는 것이 중요합니다. 이벤트의 행위자가 누구여야 하는지 결정해야 합니다. 사용자가 직접 파이프라인을 트리거하는 의도적인 파이프라인 실행(예: 리포지터리에 변경 사항을 푸시하거나 "Run pipeline" 버튼을 클릭하는 경우)인지, 아니면 GitLab 시스템이나 정책에 의해 시작된 파이프라인 실행인지 파악하세요. 파이프라인을 생성하는 사용자와 변경 사항의 작성자가 다른 시나리오는 피하세요. 사용자가 동일하지 않으면 변경 사항의 작성자가 파이프라인 사용자의 컨텍스트에서 코드를 실행할 수 있는 위험이 있습니다. 행위자를 파악하면 권한 관리 및 파이프라인이 올바른 실행 컨텍스트에서 실행되도록 보장하는 데 도움이 됩니다.
-
job 실행 사용자의 가변성: 특정 job을 실행하는 사용자가 파이프라인을 생성한 사용자와 다를 수 있습니다. 대부분의 경우 사용자는 동일하지만, 수동 job을 실행하거나 job을 재시도할 때와 같이 job의 사용자가 변경되는 시나리오도 있습니다. 이러한 가변성은 job의 실행 컨텍스트에서 권한 및 접근 수준에 영향을 줄 수 있습니다. CI/CD job 토큰(
CI_JOB_TOKEN)을 사용하는 기능을 개발할 때는 항상 이러한 가능성을 고려하세요. job 사용자가 변경되어야 하는지, 그리고 작업의 행위자가 누구인지 고려하세요. -
작업 범위 제한: CI/CD job 토큰으로 사용할 새로운 엔드포인트를 활성화할 때는 보안 강화를 위해 동일한 job, 파이프라인 또는 프로젝트로 작업을 제한하는 것을 강력히 고려하세요. 더 넓은 범위(프로젝트)보다 더 좁은 범위(job)를 강력히 선호하세요. 예를 들어, 파이프라인 데이터에 대한 접근을 허용하는 경우 프로젝트 간 또는 파이프라인 간 데이터 노출을 방지하기 위해 현재 파이프라인으로 제한하세요. 기능에 크로스 프로젝트 또는 크로스 파이프라인 접근이 정말로 필요한지 평가하세요. 범위를 제한하면 보안 위험이 줄어듭니다.
-
활동 모니터링 및 감사: 기능이 감사 가능하고 모니터링 가능하도록 보장하세요. 파이프라인 사용자, 작업을 시작하는 행위자, 이벤트 세부 정보를 포함하여 파이프라인을 트리거하는 이벤트의 상세 로그를 도입하세요.
기타 가이드#
다음은 CI/CD와 관련된 개발 가이드 목록입니다:
-
새로운 CI/CD 템플릿을 생성하는 경우, GitLab CI/CD 템플릿 개발 가이드를 참고하세요.
-
새로운 키워드를 추가하거나 CI 스키마를 변경하는 경우, 다음 가이드를 참고하세요:
-
린팅이나 파이프라인 생성과 같은 핵심 CI/CD 프로세스를 변경하는 경우, CI/CD 테스팅 가이드를 참고하세요.
CI/CD YAML syntax reference 페이지를 업데이트하는 방법은 CI/CD YAML reference 문서 가이드를 참고하세요.
메트릭#
이 섹션에서는 엔지니어가 개발, 변경 검증, 장애 조사 중에 활용할 수 있는 대시보드와 메트릭을 설명합니다.
-
모든 GitLab 팀용 대시보드를 사용할 수 있습니다. 관심 있는 기능 카테고리를 소유한 팀을 검색할 수 있습니다.
-
Pipeline Execution error budget 대시보드에는 파이프라인 생성 및 job 실행에 관한 유용한 메트릭이 포함되어 있습니다.
-
운영 로그도 Kibana에서 검색하고 집계할 수 있는 많은 유용한 정보를 제공합니다.
-
Pipeline creation 대시보드는 파이프라인 생성에 관련된 단계들의 유용한 분석을 제공합니다. 이 대시보드에는 생성에 시간이 오래 걸리거나 job이 많은 "느린 파이프라인"의 데이터만 포함됩니다. SQL "slow query log"와 유사합니다.
-
CI partitioning 대시보드에는 현재 파티션 번호, 파티션 크기, 배큐밍 및 기타 데이터베이스 메트릭에 대한 정보가 포함되어 있습니다.
CI/CD 사용 예시#
ci-sample-projects 그룹을 유지 관리하고 있으며, 여기에는 GitLab CI/CD의 다양한 사용 사례에 대한 .gitlab-ci.yml 예시를 보여주는 프로젝트들이 있습니다. 다양한 시나리오에 사용할 수 있는 특정 구문도 다루고 있습니다.
CI 아키텍처 개요#
다음은 CI 아키텍처의 단순화된 다이어그램입니다. 주요 구성 요소에 집중하기 위해 일부 세부 사항은 생략되었습니다.
[
](/19.2/development/cicd/img/ci_architecture_v13_0.png)
다이어그램 왼쪽에는 다양한 이벤트(사용자 또는 자동화에 의해 트리거됨)를 기반으로 파이프라인을 트리거할 수 있는 이벤트 목록이 있습니다:
-
git push는 파이프라인을 트리거하는 가장 일반적인 이벤트입니다. -
UI에서 "Run pipeline" 버튼을 선택하는 사용자.
-
MR이 Merge Train에 추가될 때.
-
프로젝트가 업스트림 프로젝트를 구독할 때.
-
Auto DevOps가 활성화될 때.
-
외부 풀 리퀘스트에서 GitHub 통합이 사용될 때.
-
업스트림 파이프라인에 다운스트림 파이프라인을 트리거하는 bridge job이 포함될 때.
이러한 이벤트를 트리거하면 CreatePipelineService가 호출됩니다.
이 서비스는 이벤트 데이터와 트리거하는 사용자를 입력으로 받아 파이프라인 생성을 시도합니다.
CreatePipelineService는 YAML Processor 컴포넌트에 크게 의존합니다.
이 컴포넌트는 YAML 블롭을 입력으로 받아 파이프라인의 추상 데이터 구조(Stage 및 모든 job 포함)를 반환하는 역할을 합니다. 이 컴포넌트는 처리하는 동안 YAML의 구조도 검증하며, 구문 또는 의미 오류가 있으면 반환합니다. YAML Processor 컴포넌트는 파이프라인 구조화에 사용할 수 있는 모든 키워드를 정의하는 곳입니다.
CreatePipelineService는 YAML Processor가 반환한 추상 데이터 구조를 받아 이를 영속 모델(파이프라인, Stage, job 등)로 변환합니다. 그 후 파이프라인은 처리될 준비가 됩니다. 파이프라인을 처리한다는 것은 다음 중 하나가 발생할 때까지 실행 순서(Stage 또는 needs)에 따라 job을 실행하는 것을 의미합니다:
-
예상된 모든 job이 실행 완료됨.
-
실패로 인해 파이프라인 실행이 중단됨.
파이프라인을 처리하는 컴포넌트는 ProcessPipelineService이며 다음을 처리합니다:
-
실행 준비가 된 job은
pending초기 상태로, 의존 job을 기다리는 job은created상태로 설정 -
최근에 완료된 의존 job을 기반으로 job을
pending으로 업데이트 -
파이프라인과 Stage를 job 집합의 전체 상태에 맞게 업데이트
다이어그램 오른쪽에는 GitLab 인스턴스에 연결된 러너 목록이 있습니다. 이는 인스턴스 러너, 그룹 러너 또는 프로젝트 러너일 수 있습니다.
러너와 Rails 서버 간의 통신은 Runner API Gateway로 그룹화된 API 엔드포인트 집합을 통해 이루어집니다.
러너를 등록, 삭제 및 확인할 수 있으며, 이는 데이터베이스에 읽기/쓰기 쿼리를 발생시킵니다. 러너가 연결된 후에는 실행할 다음 job을 지속적으로 요청합니다. 이때 RegisterJobService가 호출되어 다음 job을 선택하고 러너에 할당합니다. 이 시점에서 job은 running 상태로 전환되며, 상태 변경으로 인해 ProcessPipelineService가 다시 트리거됩니다.
자세한 내용은 Job 스케줄링을 참고하세요.
job이 실행되는 동안 러너는 로그와 저장되어야 할 아티팩트를 서버로 전송합니다. 또한 job은 실행을 위해 이전 job의 아티팩트에 의존할 수 있습니다. 이 경우 러너는 전용 API 엔드포인트를 사용하여 아티팩트를 다운로드합니다.
아티팩트는 오브젝트 스토리지에 저장되고, 메타데이터는 데이터베이스에 유지됩니다. 아티팩트의 중요한 예로는 머지 리퀘스트에서 파싱되어 렌더링되는 보고서(JUnit, SAST, DAST 등)가 있습니다.
모든 job 상태 전환이 자동으로 이루어지는 것은 아닙니다. 사용자는 수동 job을 실행하거나, 파이프라인을 취소하거나, 특정 실패한 job 또는 전체 파이프라인을 재시도할 수 있습니다. job 상태를 변경하는 모든 작업은 전체 파이프라인의 상태를 추적하는 역할을 하는 ProcessPipelineService를 트리거합니다.
특별한 유형의 job으로는 bridge job이 있으며, 이는 pending 상태로 전환될 때 서버 측에서 실행됩니다. 이 job은 멀티 프로젝트 또는 자식 파이프라인과 같은 다운스트림 파이프라인을 생성하는 역할을 합니다. 다운스트림 파이프라인이 트리거될 때마다 CreatePipelineService에서 워크플로 루프가 다시 시작됩니다.
CI Backend Architectural Walkthrough에서 아키텍처의 워크스루를 시청할 수 있습니다.
파이프라인 처리#
파이프라인이 생성되면 ProcessPipelineService가 Ci::InitialPipelineProcessWorker를 통해 자동으로 실행됩니다.
이 서비스는 job 상태가 변경될 때마다 PipelineProcessWorker를 통해서도 트리거됩니다.
이 서비스는 파이프라인의 모든 job을 다음 중 하나로 설정하여 완료 상태로 이동시키는 역할을 합니다:
-
요구 사항을 충족하고 실행 준비가 되어 러너가 선택할 수 있는 경우
pending상태 -
대기가 필요한 경우
created상태(단,processed는true로 표시됨)
job이 실행된 후에는 성공적으로 완료되거나 실패할 수 있습니다. 파이프라인 내 job의 각 상태 전환은 이 서비스를 다시 트리거하여 완료를 향해 전환될 다음 job을 찾습니다. 이 과정에서 ProcessPipelineService는 job, Stage 및 전체 파이프라인의 상태를 업데이트합니다. 추가 처리가 필요한 job이 있으면 서비스가 자체적으로 재스케줄링됩니다.
processed 플래그는 각 상태 전환 전에 false로 재설정되는 "처리 필요" 표시기 역할을 합니다. 이는 job 상태가 변경될 때마다 해당 변경 사항이 Stage 및 파이프라인 수준으로 전파되고, DAG의 이후 빌드 및 다음 빌드가 pending으로 표시될 수 있도록 보장합니다. 상태가 파이프라인 및 Stage 수준으로도 전파될 때까지 job은 processed로 표시되지 않습니다.
재시도 동작 및 자가 복구#
PipelineProcessWorker는 일시적인 오류 발생 시 파이프라인에 자가 복구 기능을 제공하는 지수적 백오프를 사용합니다.
데이터베이스 타임아웃, Redis 오류, 메모리 부족 조건과 같은 일시적인 문제로 처리가 실패하면 워커가 증가하는 지연 시간을 두고 재시도합니다.
워커는 멱등성을 가지며 job과 파이프라인이 need_processing?인지 확인하므로 여러 번 안전하게 실행할 수 있습니다. 이 재시도 메커니즘은 모든 job이 완료되었지만 처리 중 일시적인 오류로 인해 파이프라인이 완료로 표시되지 않은 경우 파이프라인을 수정할 수 있습니다.
Job 스케줄링#
파이프라인이 생성되면 모든 Stage의 모든 job이 초기 상태 created로 한 번에 생성됩니다. 이를 통해 파이프라인의 전체 내용을 시각화할 수 있습니다.
created 상태의 job은 아직 러너에게 보이지 않습니다. 러너에 job을 할당하려면 먼저 job이 pending 상태로 전환되어야 하며, 이는 다음 경우에 가능합니다:
-
job이 파이프라인의 첫 번째 Stage에서 생성된 경우.
-
job이 수동 시작을 필요로 하며 트리거된 경우.
-
이전 Stage의 모든 job이 성공적으로 완료된 경우. 이 경우 다음 Stage의 모든 job이
pending으로 전환됩니다. -
job이
needs:를 사용하여 의존성을 지정하고 모든 의존 job이 완료된 경우. -
job이
Ci::PipelineCreation::DropNotRunnableBuildsService에 의해 실행 불가 상태로 인해 제거되지 않은 경우.
러너가 연결되면 서버를 지속적으로 폴링하여 실행할 다음 pending job을 요청합니다.
러너가 GitLab과 상호작용하는 데 사용하는 API 엔드포인트는 [`lib/api/ci/runner.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/ci/runner.rb)에 정의되어 있습니다.
서버가 요청을 받으면 Ci::RegisterJobService 알고리즘을 기반으로 pending job을 선택한 다음 러너에 할당하고 전송합니다.
현재 Stage의 모든 job이 완료되면 서버는 다음 Stage의 모든 job의 상태를 pending으로 변경하여 "잠금 해제"합니다. 이제 러너가 새 job을 요청할 때 스케줄링 알고리즘이 이를 선택할 수 있으며, 모든 Stage가 완료될 때까지 이 과정이 계속됩니다.
러너와 GitLab 서버 간 통신#
러너가 등록 토큰을 사용하여 등록되면 서버는 실행할 수 있는 job의 유형을 알게 됩니다. 이는 다음에 따라 달라집니다:
- 등록된 러너 유형:
인스턴스 러너
-
그룹 러너
-
프로젝트 러너
-
연관된 태그.
러너는 POST /api/v4/jobs/request로 실행할 job을 요청하여 통신을 시작합니다. 폴링은 몇 초마다 발생하지만, job 큐가 변경되지 않으면 HTTP 헤더를 통한 캐싱을 활용하여 서버 측 작업 부하를 줄입니다.
이 API 엔드포인트는 Ci::RegisterJobService를 실행하며, 이 서비스는 다음을 수행합니다:
-
pendingjob 풀에서 실행할 다음 job을 선택 -
러너에 할당
-
API 응답을 통해 러너에 제공
Ci::RegisterJobService#
이 서비스는 3가지 최상위 쿼리를 사용하여 대부분의 job을 수집하며, 러너가 등록된 수준에 따라 선택됩니다:
- 인스턴스 러너용 job 선택 (인스턴스 전체)
실행 중인 빌드가 적은 프로젝트를 우선시하는 공정 스케줄링 알고리즘 사용
-
그룹 러너용 job 선택
-
프로젝트 러너용 job 선택
이 job 목록은 job 태그와 러너 태그를 매칭하여 추가로 필터링됩니다.
job에 태그가 포함되어 있으면 러너는 **모든** 태그와 일치하지 않는 경우 해당 job을 선택하지 않습니다.
러너는 job에 정의된 것보다 더 많은 태그를 가질 수 있지만, 그 반대는 불가능합니다.
마지막으로 러너가 태그된 job만 선택할 수 있는 경우, 태그가 없는 모든 job은 필터링됩니다.
이 시점에서 나머지 pending job을 순환하며 추가 정책에 따라 러너가 "선택할 수 있는" 첫 번째 job을 할당하려고 시도합니다. 예를 들어, protected로 표시된 러너는 보호된 브랜치(예: 운영 배포)에 대해 실행되는 job만 선택할 수 있습니다.
풀의 러너 수를 늘리면 동일한 job을 다른 러너에 할당하는 경우 발생할 수 있는 충돌 가능성도 높아집니다. 이를 방지하기 위해 충돌 오류를 적절히 처리하고 목록의 다음 job을 할당합니다.
중단된 빌드 제거#
빌드를 "중단됨"으로 표시하고 제거하는 방법은 두 가지입니다.
- 빌드가 생성될 때
Ci::PipelineCreation::DropNotRunnableBuildsService는 job을 실행 불가능하게 만드는 사전에 알려진 조건을 확인합니다:
빌드를 실행할 CI/CD Minutes가 충분하지 않으면 빌드는 즉시 ci_quota_exceeded로 제거됩니다.
-
향후
allowed_plans를 통해 빌드에 사용 가능한 러너가 요구하는 플랜에 프로젝트가 없으면 빌드는 즉시no_matching_runner로 제거됩니다. -
빌드를 선택할 수 있는 러너가 없는 경우, 1시간 후
Ci::StuckBuilds::DropPendingService에 의해 제거됩니다.
24시간 내에 러너가 job을 선택하지 않으면 해당 시간 이후 처리 큐에서 자동으로 제거됩니다.
-
pending 상태의 job이 중단된 경우, 즉 이를 처리할 수 있는 러너가 없는 경우 1시간 후 큐에서 제거됩니다.
-
두 경우 모두 job의 상태는 적절한 실패 이유와 함께
failed로 변경됩니다.
이러한 차이의 이유#
컴퓨트 분 할당량 메커니즘은 대부분의 경우 일정한 결정이기 때문에 job이 생성될 때 일찍 처리됩니다. 프로젝트가 한도를 초과하면 다음 달이 시작될 때까지 해당 프로젝트에 일치하는 모든 다음 job에 적용됩니다. 물론 프로젝트 Owner가 추가 분을 구매할 수 있지만, 이는 프로젝트가 취해야 하는 수동 작업입니다.
동일한 메커니즘이 곧 allowed_plans에도 사용될 예정입니다.
프로젝트가 필요한 플랜에 없고 job이 해당 러너를 타깃으로 하는 경우,
프로젝트 Owner가 구성을 변경하거나 네임스페이스를 필요한 플랜으로 업그레이드할 때까지 계속 실패합니다.
두 메커니즘 모두 GitLab.com에만 적용되며 규모에 따라 상당한 컴퓨트 리소스를 소비합니다. job이 pending으로 전환되기 전에 확인을 수행하고 일찍 실패하는 것이 이 경우에 매우 합리적입니다.
왜 다른 pending 경우를 처리하고 job을 일찍 제거하지 않는가? 일부 경우에 job이 pending 상태인 것은 러너가 job을 선택하는 데 느리기 때문입니다. 이는 GitLab 수준에서 알 수 없는 것입니다. 러너의 구성 및 용량과 GitLab의 큐 크기에 따라 job이 즉시 선택되거나 기다려야 할 수 있습니다.
다른 가능한 이유들도 있습니다:
-
러너 유지 관리를 처리 중이며, 일시적으로 사용할 수 없는 경우.
-
구성을 업데이트하는 중에 실수로 잘못된 태깅이나 보호 플래그를 사용한 경우.
-
GitLab.com 인스턴스 러너의 경우, 잘못된 비용 요소나
allowed_plans구성을 할당한 경우.
이러한 문제는 일반적으로 일시적이며 빠르게 감지하고 수정해야 합니다. 이러한 조건 중 하나가 발생할 때 즉시 job을 제거하는 것은 원치 않습니다. 러너가 용량에 도달했거나 일시적인 사용 불가/구성 실수로 인해 job을 제거하는 것은 사용자에게 매우 해로울 것입니다.
Job Trace 청크 아키텍처#
GitLab.com에서 러너로부터 트레이스가 전송되면 콘텐츠는 job ID와 인덱스를 포함하는 키와 함께 redis_trace_chunks Redis 클러스터에 저장됩니다.
각 청크를 추적하기 위해 Ci::BuildTraceChunk 레코드도 생성됩니다. 이 레코드는 청크의 현재 데이터 스토어를 나타냅니다. GitLab 설치의 관리자는 사용할 데이터 스토어를 구성할 수 있습니다. GitLab.com이 아닌 인스턴스에서는 ci_job_live_trace_enabled?가 활성화된 경우에도 이 동작이 발생합니다.
수명 주기#
- Trace 추가 단계
러너 → PATCH /api/v4/jobs/1/trace (트레이스 내용 전송)
-
Ci::AppendBuildTraceService가 라이브 스토어에 청크 데이터를 저장합니다(.com의 경우 Redis trace chunks 클러스터) -
PostgreSQL에
data_store: redis_trace_chunks로Ci::BuildTraceChunk레코드 생성 -
트레이스 메타데이터를 추적하기 위한
Ci::BuildTraceMetadata레코드 생성 -
러너에게 200 OK 반환
-
build.trace_chunks는data_store로redis_trace_chunks또는 다른 라이브 스토어를 가진 레코드를 포함합니다 -
Job 업데이트 단계
러너 → PUT /api/v4/jobs/1 (job 업데이트)
-
이 엔드포인트는
Ci::BuildTraceChunkFlushWorker도 실행합니다 -
Ci::BuildTraceChunkFlushWorker가 Redis trace chunks 클러스터에서 청크 데이터를 가져옵니다 -
청크를 오브젝트 스토리지에 복사합니다(각 청크는 자체 파일을 가짐)
-
라이브 데이터 스토어에서 라이브 청크를 삭제합니다(.com의 경우
redis_trace_chunks클러스터) -
PostgreSQL의
Ci::BuildTraceChunk레코드를data_store: fog로 업데이트 -
러너에게 200 OK 반환
-
build.trace_chunks는data_store로fog또는 다른 영속 스토어를 가진 레코드를 포함합니다 -
Job 완료 및 아카이브 단계
러너 → PUT /api/v4/jobs/1 (job 완료)
-
Ci::BuildFinishedWorker트리거 -
Ci::ArchiveTraceWorker가 오브젝트 스토리지에서 모든 fog 청크를 가져옵니다 -
type: :trace의JobArtifact로 단일 통합 아카이브 파일 생성 -
오브젝트 스토리지에서 개별 청크 삭제
-
PostgreSQL에서
Ci::BuildTraceChunk레코드 삭제
Ci::Build::Trace가 live에서 archived 상태로 변경됩니다
-
러너에게 200 OK 반환
-
build.trace_chunks는 빈 배열이 됩니다
sequenceDiagram participant Runner participant API participant Redis as Redis Trace Chunks participant ObjectStorage as Object Storage participant PostgreSQL participant Archive as Archive Storage
Note over Runner, Archive: 1. Trace Append Phase
Runner->>API: PATCH /api/v4/jobs/1/trace<br/>(trace contents)
API->>Redis: Ci::AppendBuildTraceService<br/>stores chunk data
API->>PostgreSQL: Create Ci::BuildTraceChunk<br/>(data_store: redis_trace_chunks)
API->>Runner: 200 OK
Note over Runner, Archive: 2. Job Update Phase
Runner->>API: PUT /api/v4/jobs/1<br/>(job update)
API->>Redis: Ci::BuildTraceChunkFlushWorker<br/>retrieves chunk data
API->>ObjectStorage: Copy chunk to storage<br/>(each chunk = own file)
API->>Redis: Delete chunk in redis
API->>PostgreSQL: Update Ci::BuildTraceChunk<br/>(data_store: fog)
API->>Runner: 200 OK
Note over Runner, Archive: 3. Job Completion & Archive Phase
Runner->>API: PUT /api/v4/jobs/1<br/>(job completion)
API->>API: Trigger Ci::BuildFinishedWorker
API->>ObjectStorage: Ci::ArchiveTraceWorker<br/>retrieves all fog chunks
API->>Archive: Create single archive file
API->>ObjectStorage: Delete individual chunks
API->>PostgreSQL: Update Ci::Build::Trace<br/>(live → archived)
API->>Runner: 200 OK
모니터링 리소스#
GitLab CI/CD에서 "Job"의 정의#
GitLab CI 컨텍스트에서 "Job"은 지속적 통합(Continuous Integration), 지속적 전달(Continuous Delivery) 및 지속적 배포(Continuous Deployment)를 구동하는 작업을 의미합니다. 일반적으로 파이프라인에는 여러 Stage가 포함되고, Stage에는 여러 job이 포함됩니다.
Active Record 모델링에서 Job은 CommitStatus 클래스로 정의됩니다.
그 위에 다음과 같은 유형의 job이 있습니다:
-
Ci::Build… 러너가 실행할 job. -
Ci::Bridge… 다운스트림 파이프라인을 트리거하는 job. -
GenericCommitStatus… 예를 들어 Jenkins와 같은 외부 CI/CD 시스템에서 실행되는 job.
코드베이스에서 "Job" 용어를 사용할 때, 읽는 사람은 해당 클래스/객체가 위의 모든 유형임을 가정합니다.
Ci::Build 클래스를 구체적으로 지칭하는 경우, 혼동을 일으킬 수 있으므로 객체/클래스를 "job"으로 명명하지 않아야 합니다. 문서에서는 "Build" 대신 일반적으로 "Job"을 사용해야 합니다.
코드베이스에는 리팩토링이 필요한 몇 가지 불일치가 있습니다.
예를 들어, CommitStatus는 Ci::Job이어야 하고 Ci::JobArtifact는 Ci::BuildArtifact이어야 합니다.
전체 리팩토링 계획은 이 이슈를 참고하세요.
컴퓨트 분 및 할당량#
컴퓨트 분 개발 문서를 참고하세요.