러너 구성하기

Tier: Free, Premium, Ultimate Offering: GitLab.com, Self-managed, GitLab Dedicated

자체 러너를 설치한 경우 GitLab에서 이를 구성하고 보안을 강화할 수 있습니다.

GitLab 러너를 설치한 기계에서 러너를 구성해야 하는 경우 GitLab 러너 문서를 참조하세요.

최대 작업 시간 설정

각 러너에 대해 최대 작업 시간을 지정하여 더 긴 작업 시간을 가진 프로젝트가 러너를 사용하는 것을 방지할 수 있습니다. 최대 작업 시간은 프로젝트에서 정의된 작업 시간보다 짧을 경우에 사용됩니다.

인스턴스 러너의 경우

사전 준비 사항:

  • 관리자 권한이 있어야 합니다.

GitLab.com에서는 인스턴스 러너의 작업 시간을 무시할 수 없으며 대신 프로젝트에서 정의된 시간 제한을 사용해야 합니다.

최대 작업 시간 설정:

  1. 왼쪽 사이드바에서 맨 아래에서 관리자 영역을 선택합니다.
  2. CI/CD > 러너를 선택합니다.
  3. 편집하려는 러너 오른쪽에 편집 ()을 선택합니다.
  4. 최대 작업 시간 필드에 초 단위의 값을 입력합니다. 최소 길이는 600초(10분)입니다.
  5. 변경 내용 저장을 선택합니다.

그룹 러너의 경우

사전 준비 사항:

  • 그룹의 소유자 역할이 있어야 합니다.

최대 작업 시간 설정:

  1. 왼쪽 사이드바에서 검색 또는 이동을 선택하고 그룹을 찾습니다.
  2. 빌드 > 러너를 선택합니다.
  3. 편집하려는 러너 오른쪽에 편집 ()을 선택합니다.
  4. 최대 작업 시간 필드에 초 단위의 값을 입력합니다. 최소 길이는 600초(10분)입니다.
  5. 변경 내용 저장을 선택합니다.

프로젝트 러너의 경우

사전 준비 사항:

  • 프로젝트의 소유자 역할이 있어야 합니다.

최대 작업 시간 설정:

  1. 왼쪽 사이드바에서 검색 또는 이동을 선택하고 프로젝트를 찾습니다.
  2. 설정 > CI/CD를 선택합니다.
  3. 러너를 확장합니다.
  4. 편집하려는 러너 오른쪽에 편집 ()을 선택합니다.
  5. 최대 작업 시간 필드에 초 단위의 값을 입력합니다. 최소 길이는 600초(10분)입니다. 지정되지 않은 경우 프로젝트의 작업 시간 제한이 대신 사용됩니다.
  6. 변경 내용 저장을 선택합니다.

최대 작업 시간 설정의 동작 방식

예제 1 - 러너 시간 제한이 프로젝트 시간 제한보다 큰 경우

  1. 러너의 _최대 작업 시간_을 24시간으로 설정합니다.
  2. 프로젝트의 _CI/CD 시간 제한_을 2시간으로 설정합니다.
  3. 작업을 시작합니다.
  4. 작업이 지속되면 2시간 후에 작업이 종료됩니다.

예제 2 - 러너 시간 제한이 구성되지 않은 경우

  1. 러너에서 최대 작업 시간 구성을 제거합니다.
  2. 프로젝트의 _CI/CD 시간 제한_을 2시간으로 설정합니다.
  3. 작업을 시작합니다.
  4. 작업이 지속되면 2시간 후에 작업이 종료됩니다.

예제 3 - 러너 시간 제한이 프로젝트 시간 제한보다 작은 경우

  1. 러너의 _최대 작업 시간_을 30분으로 설정합니다.
  2. 프로젝트의 _CI/CD 시간 제한_을 2시간으로 설정합니다.
  3. 작업을 시작합니다.
  4. 작업이 지속되면 30분 후에 작업이 종료됩니다.

scriptafter_script 시간 제한 설정

scriptafter_script가 종료되기 전에 실행되는 시간을 제어하기 위해 시간 제한을 설정할 수 있습니다.

예를 들어, script가 길게 실행되지 않도록 시간 제한을 설정하여 작업 시간 제한을 초과하기 전에 여전히 artefact와 cache를 업로드할 수 있습니다.

  • script의 시간 제한을 설정하려면 작업 변수 RUNNER_SCRIPT_TIMEOUT을 사용하세요.
  • after_script의 시간 제한을 설정하고 기본값인 5분을 재정의하려면 작업 변수 RUNNER_AFTER_SCRIPT_TIMEOUT을 사용하세요.

이러한 변수들은 Go의 지속 시간 형식을 받아들입니다 (예: 40s, 1h20m, 2h 4h30m30s).

예를 들어:

job-with-script-timeouts:
  variables:
    RUNNER_SCRIPT_TIMEOUT: 15m
    RUNNER_AFTER_SCRIPT_TIMEOUT: 10m
  script:
    - "15분 또는 남은 작업 시간  최소값까지 실행할  있습니다."
  after_script:
    - "10분 또는 남은 작업 시간  최소값까지 실행할  있습니다."

job-artifact-upload-on-timeout:
  timeout: 1시간                           # 작업 시간 제한을 1시간으로 설정
  variables:
     RUNNER_SCRIPT_TIMEOUT: 50분           # 스크립트가 50분 동안만 실행되도록 설정
  script:
    - long-running-process > output.txt    # 50분 후에 종료됩니다
  
  artefacts: # artefacts는 대략 ~10분 동안 업로드됩니다
    paths:
      - output.txt
    when: on_failure # 타임아웃 이후 스크립트 종료는 실패로 처리됩니다

민감한 정보 보호

민감한 정보 노출을 방지하기 위해 대규모 GitLab 인스턴스에서 인스턴스 러너의 사용을 제한할 수 있습니다. 이를 통해 GitLab 인스턴스에 대한 액세스를 제어하고 러너 실행자를 안전하게 보호할 수 있습니다.

특정 실행자가 작업을 실행하는 경우 파일 시스템, 러너가 실행하는 코드 및 러너 인증 토큰이 노출될 수 있습니다. 이는 인스턴스 러너에서 작업을 실행하는 사용자가 러너에서 실행되는 다른 사용자의 코드에 액세스할 수 있다는 것을 의미합니다. 러너 인증 토큰에 액세스 권한이 있는 사용자는 해당 토큰을 사용하여 러너의 복제본을 만들고 벡터 공격에서 거짓 작업을 제출할 수 있습니다. 자세한 내용은 보안 고려 사항을 참조하세요.

Long polling 구성

Long polling 을 구성하여 GitLab 서버의 작업 대기 시간과 부하를 줄입니다.

포크된 프로젝트에서 인스턴스 러너 사용하기

프로젝트가 포크되면, 작업과 관련된 작업 설정이 복사됩니다. 프로젝트에 인스턴스 러너가 구성되어 있고 사용자가 해당 프로젝트를 포크하면, 인스턴스 러너는 이 프로젝트의 작업을 처리합니다.

알려진 문제로 인해, 포크된 프로젝트의 러너 설정이 새 프로젝트 네임스페이스와 일치하지 않으면 다음 메시지가 표시됩니다: 프로젝트를 포크하는 동안 오류가 발생했습니다. 다시 시도하십시오..

이 문제를 해결하려면, 포크된 프로젝트와 새 네임스페이스에서 인스턴스 러너 설정이 일관되도록합니다.

  • 포크된 프로젝트에서 인스턴스 러너가 활성화된 경우, 새 네임스페이스에서도 활성화되어야 합니다.
  • 포크된 프로젝트에서 인스턴스 러너가 비활성화된 경우, 새 네임스페이스에서도 비활성화되어야 합니다.

프로젝트에 대한 러너 등록 토큰 재설정(폐기됨)

caution
특정 구성 인수의 지원과 러너 등록 토큰 전달 기능은 GitLab 15.6에서 폐기되었으며 GitLab 17.0에서 제거됩니다. 인증 토큰 대신 사용해야 합니다. 자세한 내용은 새로운 러너 등록 워크플로로 마이그레이션하기를 참조하십시오.

프로젝트의 등록 토큰이 노출된 것으로 판단되면 재설정해야 합니다. 등록 토큰은 프로젝트에 또 다른 러너를 등록하는 데 사용할 수 있습니다. 그 새로운 러너는 비밀 변수의 값을 얻거나 프로젝트 코드를 클론하는 데 사용될 수 있습니다.

등록 토큰을 재설정하려면:

  1. 왼쪽 사이드바에서 검색 또는 이동하여 프로젝트를 찾습니다.
  2. 설정 > CI/CD 선택.
  3. 러너(runner) 확장.
  4. 새 프로젝트 러너 오른쪽에서 수직 태크 ({토글}) 선택.
  5. 등록 토큰 재설정 선택.
  6. 토큰 재설정 선택.

등록 토큰을 재설정하면 더 이상 유효하지 않으며 새 러너를 프로젝트에 등록하지 않습니다. 새 값으로 프로비저닝하고 등록하는 데 사용하는 도구에서도 등록 토큰을 업데이트해야 합니다.

인증 토큰 보안

  • GitLab 15.3에서 도입되었습니다. 기본적으로 비활성화된 enforce_runner_token_expires_at이라는 플래그와 함께.
  • GitLab 15.5에서 일반적으로 사용 가능합니다. 플래그 enforce_runner_token_expires_at이 제거되었습니다.

각 러너는 GitLab 인스턴스와 연결하기 위한 러너 인증 토큰을 갖습니다.

토큰이 노출되지 않도록 도와주기 위해, 특정 간격으로 토큰 자동으로 회전될 수 있습니다. 토큰이 회전되면 각 러너에 대해 업데이트됩니다(온라인 또는 오프라인 상태에 관계없이).

매뉴얼 개입은 필요하지 않으며 실행 중인 작업에 영향을주게해서는 안됩니다.

매뉴얼으로 러너 인증 토큰을 업데이트해야하는 경우 명령을 실행하여 토큰을 재설정할 수 있습니다.

러너 인증 토큰 재설정

러너 인증 토큰이 노출되면 공격자가 해당 토큰을 사용하여 러너(runner)를 클론할 수 있습니다.

러너 인증 토큰을 재설정하려면:

  1. 러너를 삭제합니다:
  2. 새로운 러너를 생성하여 새 러너 인증 토큰을 할당하십시오:
  3. 옵션. 이전 러너 인증 토큰이 폐기되었는지 확인하려면 러너(runner) API를 사용하십시오.

러너 인증 토큰 자동 회전

러너 인증 토큰의 회전 간격을 지정할 수 있습니다. 이 회전은 러너에 할당된 토큰의 보안을 보장하는 데 도움이 됩니다.

전제 조건:

러너 인증 토큰을 자동으로 회전하려면:

  1. 왼쪽 사이드바에서 가장 아래에서 Admin Area를 선택합니다.
  2. 설정 > CI/CD 선택.
  3. 지속적 통합 및 배포 확장.
  4. 러너 만료 시간을 설정하고, 만료시간이 없으면 빈 채로 둡니다.
  5. 변경 사항 저장 선택.

만료 시간이 지나기 전에 러너가 자동으로 새 러너 인증 토큰을 요청합니다.

러너가 민감한 정보를 노출하지 않도록 방지

러너가 민감한 정보를 노출하지 않도록하려면, 보호된 브랜치에서만 작업하거나 보호된 태그를 가진 작업만 실행하도록 구성할 수 있습니다.

보호된 브랜치에서 작업을 실행하도록 구성된 러너는 Merge Request 파이프라인에서 작업을 실행할 수 없습니다.

인스턴스 러너의 경우

전제 조건:

  • 귀하는 관리자여야 합니다.
  1. 왼쪽 사이드바에서 가장 아래에서 Admin Area를 선택합니다.
  2. CI/CD > Runners를 선택합니다.
  3. 보호하려는 러너로 이동하여 편집 ()을 선택합니다.
  4. 보호됨 확인란을 선택합니다.
  5. 변경 사항 저장 선택합니다.

그룹 러너의 경우

전제 조건:

  • 귀하는 그룹의 소유자 역할이어야 합니다.
  1. 왼쪽 사이드바에서 검색 또는 이동하여 귀하의 그룹을 찾습니다.
  2. Build > Runners를 선택합니다.
  3. 보호하려는 러너로 이동하여 편집 ()을 선택합니다.
  4. 보호됨 확인란을 선택합니다.
  5. 변경 사항 저장 선택합니다.

프로젝트 러너용

필수 조건:

  • 프로젝트의 소유자 역할이어야 합니다.
  1. 왼쪽 사이드바에서 검색 또는 이동을 선택하고 프로젝트를 찾습니다.
  2. 설정 > CI/CD를 선택합니다.
  3. 러너(runner)를 확장합니다.
  4. 보호하려는 러너 오른쪽에서 편집 ()을 선택합니다.
  5. 보호됨 확인란을 선택합니다.
  6. 변경 사항 저장을 선택합니다.

러너가 실행할 작업 제어

태그를 사용하여 러너가 실행할 작업을 제어할 수 있습니다. 예를 들어, rails 태그를 지정하여 Rails 테스트 스위트를 실행할 수 있는 의존성을 갖춘 러너를 지정할 수 있습니다.

GitLab CI/CD 태그는 Git 태그와 다릅니다. GitLab CI/CD 태그는 러너와 관련이 있으며 Git 태그는 커밋과 관련이 있습니다.

인스턴스 러너용

필수 조건:

  • 관리자여야 합니다.

최대 작업 시간 제한 설정:

  1. 왼쪽 사이드바에서 맨 아래에서 관리자 영역을 선택합니다.
  2. CI/CD > 러너를 선택합니다.
  3. 편집하려는 러너 오른쪽에서 편집 ()을 선택합니다.
  4. 러너를 태그 지정된 작업 또는 태그 지정되지 않은 작업으로 실행하도록 설정합니다:
    • 태그 지정된 작업을 실행하려면 태그 필드에 쉼표로 구분된 작업 태그를 입력합니다. 예: macos, rails.
    • 태그 지정되지 않은 작업을 실행하려면 태그 지정되지 않은 작업 실행 확인란을 선택합니다.
  5. 변경 사항 저장을 선택합니다.

그룹 러너용

필수 조건:

  • 그룹의 소유자 역할이어야 합니다.

최대 작업 시간 제한 설정:

  1. 왼쪽 사이드바에서 검색 또는 이동을 선택하고 그룹을 찾습니다.
  2. 빌드 > 러너를 선택합니다.
  3. 수정하려는 러너 오른쪽에서 편집 ()을 선택합니다.
  4. 러너를 태그 지정된 작업 또는 태그 지정되지 않은 작업으로 실행하도록 설정합니다:
    • 태그 지정된 작업을 실행하려면 태그 필드에 쉼표로 구분된 작업 태그를 입력합니다. 예: macos, ruby.
    • 태그 지정되지 않은 작업을 실행하려면 태그 지정되지 않은 작업 실행 확인란을 선택합니다.
  5. 변경 사항 저장을 선택합니다.

프로젝트 러너용

필수 조건:

  • 프로젝트의 소유자 역할이어야 합니다.

태그 지정된 작업을 실행하도록 러너 설정:

  1. 왼쪽 사이드바에서 검색 또는 이동을 선택하고 프로젝트를 찾습니다.
  2. 설정 > CI/CD를 선택합니다.
  3. 러너(runner)를 확장합니다.
  4. 보호하려는 러너 오른쪽에서 편집 ()을 선택합니다.
  5. 러너를 태그 지정된 작업 또는 태그 지정되지 않은 작업으로 실행하도록 설정합니다:
    • 태그 지정된 작업을 실행하려면 태그 필드에 쉼표로 구분된 작업 태그를 입력합니다. 예: macos, ruby.
    • 태그 지정되지 않은 작업을 실행하려면 태그 지정되지 않은 작업 실행 확인란을 선택합니다.
  6. 변경 사항 저장을 선택합니다.

러너가 태그를 사용하는 방법

러너는 태그가 지정된 작업만 실행

다음 예제는 러너가 태그가 지정된 작업만 실행하도록 설정된 경우의 잠재적인 영향을 보여줍니다.

예제 1:

  1. 러너가 태그가 지정된 작업만 실행되도록 설정되고 docker 태그를 갖습니다.
  2. hello 태그가 있는 작업이 실행되고 멈춥니다.

예제 2:

  1. 러너가 태그가 지정된 작업만 실행되도록 설정되고 docker 태그를 갖습니다.
  2. docker 태그가 있는 작업이 실행되고 완료됩니다.

예제 3:

  1. 러너가 태그가 지정된 작업만 실행되도록 설정되고 docker 태그를 갖습니다.
  2. 태그가 정의되지 않은 작업이 실행되고 멈춥니다.

러너가 태그가 지정되지 않은 작업도 실행할 수 있는 경우

다음 예제는 러너가 태그가 지정되지 않은 작업과 태그가 지정된 작업을 실행할 수 있는 경우의 잠재적인 영향을 보여줍니다.

예제 1:

  1. 러너가 태그가 지정되지 않은 작업을 실행되도록 설정되고 docker 태그를 갖습니다.
  2. 태그가 정의되지 않은 작업이 실행되고 완료됩니다.
  3. docker 태그가 정의된 두 번째 작업이 실행되고 완료됩니다.

예제 2:

  1. 러너가 태그가 지정되지 않은 작업을 실행되도록 설정되고 태그가 정의되지 않습니다.
  2. 태그가 정의되지 않은 작업이 실행되고 완료됩니다.
  3. docker 태그가 정의된 두 번째 작업이 멈춥니다.

러너와 작업에 여러 태그가 지정된 경우

러너와 작업의 선택 로직은 작업 스크립트 블록에 정의된 태그 디렉터리을 기반으로 합니다. 러너가 작업을 실행하려면 작업 스크립트 블록에 정의된 모든 태그를 가져야 합니다.

예제 1:

  1. 러너는 [docker, shell, gpu] 태그로 구성됩니다.
  2. 작업은 [docker, shell, gpu] 태그를 갖고 있으며 실행되고 완료됩니다.

예제 2:

  1. 러너는 [docker, shell, gpu] 태그로 구성됩니다.
  2. 작업은 [docker, shell,] 태그를 갖고 있으며 실행되고 완료됩니다.

예제 3:

  1. 러너는 [docker, shell] 태그로 구성됩니다.
  2. 작업은 [docker, shell, gpu] 태그를 갖고 있으며 실행되지 않습니다.

다른 플랫폼에서 작업 실행을 위해 태그 사용

각 플랫폼에서 다른 작업을 실행하기 위해 태그를 사용할 수 있습니다. 예를 들어, osx 태그가 있는 OS X 러너와 windows 태그가 있는 Windows 러너가 있다면 각 플랫폼에서 작업을 실행할 수 있습니다.

config.tomltags 필드 업데이트:

windows job:
  stage: build
  tags:
    - windows
  script:
    - echo Hello, %USERNAME%!

osx job:
  stage: build
  tags:
    - osx
  script:
    - echo "Hello, $USER!"

태그에서 CI/CD 변수 사용

.gitlab-ci.yml 파일에서 tags와 함께 CI/CD 변수를 사용하여 동적으로 러너를 선택할 수 있습니다:

variables:
  KUBERNETES_RUNNER: kubernetes
  
  job:
    tags:
      - docker
      - $KUBERNETES_RUNNER
    script:
      - echo "Hello runner selector feature"

변수를 사용하여 러너 동작 구성하기

단일 작업 또는 전역으로 러너 Git 동작을 구성하기 위해 CI/CD 변수를 사용할 수 있습니다:

또한 변수를 사용하여 러너가 작업 실행의 특정 단계를 시도하는 횟수를 덮어쓸 수 있습니다.

Kubernetes executor를 사용할 때 변수를 사용하여 요청 및 리소스에 대한 Kubernetes CPU 및 메모리 할당을 덮어쓸 수 있습니다.

Git 전략

variables 섹션에서 전역 또는 작업별로 사용되는 GIT_STRATEGY를 설정할 수 있습니다:

variables:
  GIT_STRATEGY: clone

clone, fetch, none의 세 가지 가능한 값이 있습니다. 지정하지 않으면 작업은 프로젝트의 파이프라인 설정을 사용합니다.

  • clone은 가장 느린 옵션입니다. 모든 작업에 대해 리포지터리를 처음부터 복제하여 로컬 작업 사본이 항상 풀프로프로스트로 유지되도록합니다. 기존 작업 디렉터리가 발견되면 복제 전에 제거됩니다.

  • fetch는 로컬 작업 사본을 재사용하여 더 빠릅니다. 지난 작업에서 생긴 변경 사항을 되돌리기 위해 git clean을 사용하고, 지난 작업 이후에 만들어진 커밋을 검색하기 위해 git fetch를 사용합니다.

    그러나 fetch는 이전의 작업 디렉터리에 액세스해야 합니다. 기본적으로 shell 또는 docker executor를 사용할 때 잘 작동합니다.

    하지만 Docker Machine executor를 사용하는 경우에는 제한 사항이 있습니다.

  • 일반적으로 none은 로컬 작업 사본을 재사용하지만, GitLab이 수행하는 모든 Git 작업을 건너뛴다. GitLab Runner 사전 복제 스크립트도 생략됩니다. 이 전략은 .gitlab-ci.yml 스크립트fetchcheckout 명령을 추가해야 할 수도 있습니다.

아티팩트만으로 작업하는 작업(예: 배포 작업)에 사용할 수 있습니다. Git 리포지터리 데이터는 있을 수 있지만, 가장 최신 정보는 아닐 것입니다. 로컬 작업 사본으로 가져온 파일에만 의존해야 합니다.

Git 서브모듈 전략

GIT_SUBMODULE_STRATEGY 변수는 빌드 전 코드를 가져올 때 Git 서브 모듈이 어떻게 포함되는지를 제어합니다. 해당 변수를 variables 섹션에서 전역 또는 작업별로 설정할 수 있습니다.

세 가지 가능한 값은 none, normal, recursive입니다:

  • none은 프로젝트 코드를 가져올 때 서브 모듈이 포함되지 않습니다. 이것은 v1.10 이전의 기본 동작입니다.

  • normal은 최상위 서브 모듈만 포함됩니다. 다음과 동등합니다:

    git submodule sync
    git submodule update --init
    
  • recursive은 모든 서브 모듈을 포함합니다. 이 기능은 Git v1.8.1 이후 버전이 필요합니다. Docker를 기반으로 하지 않은 GitLab Runner를 사용할 때는 해당 요구 사항을 충족시켜야 합니다. 다음과 동등합니다:

    git submodule sync --recursive
    git submodule update --init --recursive
    

이 기능이 올바르게 작동하려면 서브 모듈이 공개적으로 접근 가능한 리포지터리의 HTTP(S) URL 또는 GitLab 서버의 다른 리포지터리를 가리키는 상대 경로로 구성되어 있어야합니다. 추가 플래그를 사용하여 고급 동작을 제어할 수 있습니다.

Git 체크아웃

GIT_CHECKOUT 변수는 GIT_STRATEGYclone 또는 fetch로 설정된 경우 git checkout을 실행할지 여부를 지정하는 데 사용할 수 있습니다. 지정되지 않으면 기본값은 true입니다. 전역 또는 작업별로 variables 섹션에서 설정할 수 있습니다.

만약 false로 설정되면 러너:

  • fetch를 실행할 때 - 리포지터리를 업데이트하고 현재 리비전의 작업 사본을 그대로 둡니다.
  • clone을 실행할 때 - 리포지터리를 복제하고 작업 사본을 기본 브랜치에 유지합니다.

GIT_CHECKOUTtrue로 설정되면 clonefetch가 같은 방식으로 작동합니다. 러너는 관련된 CI 파이프라인의 작업 사본을 체크아웃합니다.

variables:
  GIT_STRATEGY: clone
  GIT_CHECKOUT: "false"
script:
  - git checkout -B master origin/master
  - git merge $CI_COMMIT_SHA

Git 정리 플래그

GIT_CLEAN_FLAGS 변수는 소스를 체크아웃한 후의 git clean의 기본 동작을 제어하는 데 사용됩니다. variables 섹션에서 전역 또는 작업별로 설정할 수 있습니다.

GIT_CLEAN_FLAGSgit clean 명령어의 가능한 모든 옵션을 허용합니다.

GIT_CLEAN_FLAGS가 지정되지 않으면 git clean 플래그는 기본적으로 -ffdx로 설정됩니다. 만약 none 값이 주어지면 git clean은 실행되지 않습니다.

예를 들면:

variables:
  GIT_CLEAN_FLAGS: -ffdx -e cache/
script:
  - ls -al cache/

Git fetch extra flags

GIT_FETCH_EXTRA_FLAGS 변수를 사용하여 git fetch의 동작을 제어합니다. 이를 variables 섹션에서 전역적으로 설정하거나 작업별로 설정할 수 있습니다.

GIT_FETCH_EXTRA_FLAGSgit fetch 명령어의 모든 옵션을 받아들입니다. 하지만 GIT_FETCH_EXTRA_FLAGS 플래그들은 수정할 수 없는 기본 플래그들 뒤에 추가됩니다.

기본 플래그들은 다음과 같습니다:

  • GIT_DEPTH.
  • refspecs 디렉터리.
  • origin이라는 이름의 원격 리포지터리.

만약 GIT_FETCH_EXTRA_FLAGS가:

  • 지정되지 않았다면, git fetch 플래그는 기본 플래그들과 함께 --prune --quiet로 설정됩니다.
  • 값으로 none이 주어졌다면, git fetch는 기본 플래그들만으로 실행됩니다.

예를 들어, 기본 플래그들이 --prune --quiet인 경우, 이를 --prune으로 재정의하여 git fetch를 더 상세하게 만들 수 있습니다:

variables:
  GIT_FETCH_EXTRA_FLAGS: --prune
script:
  - ls -al cache/

위의 구성은 git fetch가 다음과 같이 호출되도록 합니다:

git fetch origin $REFSPECS --depth 50  --prune

여기서 $REFSPECS는 GitLab 내부에서 러너에 의해 제공된 값입니다.

동기화 또는 특정 서브모듈 제외하기

GIT_SUBMODULE_PATHS 변수를 사용하여 어떤 서브모듈을 동기화하거나 업데이트해야 하는지를 제어할 수 있습니다. 이를 variables 섹션에서 전역적으로 설정하거나 작업별로 설정할 수 있습니다.

경로 구문은 git submodule과 동일합니다:

  • 특정 경로를 동기화하고 업데이트하는 경우:

     variables:
        GIT_SUBMODULE_PATHS: submoduleA submoduleB
    
  • 특정 경로를 제외하는 경우:

     variables:
        GIT_SUBMODULE_PATHS: :(exclude)submoduleA :(exclude)submoduleB
    
caution
Git은 중첩된 경로를 무시합니다. 중첩된 서브모듈을 무시하려면 상위 서브모듈을 제외하고, 작업 스크립트에서 매뉴얼으로 클론해야 합니다. 예를 들어, git clone <repo> --recurse-submodules=':(exclude)nested-submodule'과 같이 수행합니다. YAML을 성공적으로 구문 분석할 수 있도록 문자열을 반드시 작은 따옴표로 감싸야 합니다.

Git 서브모듈 업데이트 플래그

GIT_SUBMODULE_UPDATE_FLAGS 변수를 사용하여 GIT_SUBMODULE_STRATEGYnormal 또는 recursive로 설정된 경우 git submodule update의 동작을 제어할 수 있습니다. 이를 variables 섹션에서 전역적으로 설정하거나 작업별로 설정할 수 있습니다.

GIT_SUBMODULE_UPDATE_FLAGSgit submodule update 하위 명령어의 모든 옵션을 받아들입니다. 하지만 GIT_SUBMODULE_UPDATE_FLAGS 플래그들은 기본 플래그들 뒤에 추가됩니다:

Git은 인수 디렉터리에서 플래그의 마지막 발생을 존중하므로, GIT_SUBMODULE_UPDATE_FLAGS에서 직접 제공하면 이러한 기본 플래그들이 재정의됩니다.

이 변수를 사용하여 리포지터리에서 추적하는 대신 최신 원격 HEAD를 가져오거나, 여러 병렬 작업에서 서브모듈을 빠르게 가져오도록 할 수 있습니다:

variables:
  GIT_SUBMODULE_STRATEGY: recursive
  GIT_SUBMODULE_UPDATE_FLAGS: --remote --jobs 4
script:
  - ls -al .git/modules/

위의 구성은 git submodule update가 다음과 같이 호출되도록 합니다:

git submodule update --init --depth 50 --recursive --remote --jobs 4
caution
--remote 플래그를 사용할 때 빌드의 보안, 안정성, 그리고 재현성에 대한 영향을 고려해야 합니다. 대부분의 경우, 명시적으로 서브모듈 커밋을 추적하고 자동 복구/의존성 봇을 사용하여 업데이트하는 것이 더 좋습니다.

서브모듈 URL을 HTTPS로 재작성

GIT_SUBMODULE_FORCE_HTTPS 변수를 사용하여 모든 Git 및 SSH 서브모듈 URL을 HTTPS로 강제로 재작성할 수 있습니다. 이를 통해 Git 또는 SSH 프로토콜로 구성되었더라도 절대적인 URL을 사용하는 동일한 GitLab 인스턴스에서 서브모듈을 복제할 수 있습니다.

variables:
  GIT_SUBMODULE_STRATEGY: recursive
  GIT_SUBMODULE_FORCE_HTTPS: "true"

활성화되면, GitLab Runner는 CI/CD 작업 토큰을 사용하여 작업을 실행하는 사용자의 권한으로 서브모듈을 복제하며, SSH 자격 증명이 필요하지 않습니다.

얕은 클론

GIT_DEPTH를 사용하여 가져오고 클론할 커밋의 깊이를 지정할 수 있습니다. GIT_DEPTH는 리포지터리의 얕은 클론을 수행하며, 큰 수의 커밋이나 오래된 큰 파일이 있는 리포지터리를 크게 속도를 향상시킬 수 있습니다. 이 값은 git fetchgit clone으로 전달됩니다.

새로 생성된 프로젝트는 자동으로 기본 git depth 값이 50 값을 갖습니다.

depth 값을 1로 설정하고 작업의 대기열이 있거나 다시 시도하는 경우, 작업이 실패할 수 있습니다.

Git의 가져오기 및 클론은 브랜치 이름과 같은 ref를 기반으로 하므로 러너는 특정 커밋 SHA를 복제할 수 없습니다. 대기 중인 작업이 여러 개 있는 경우나 이전 버전의 작업을 다시 시도하는 경우, 테스트할 커밋은 복제된 Git 기록 내에 있어야 합니다. GIT_DEPTH의 값을 너무 작게 설정하면 이전 커밋을 실행할 수 없게 되며 작업 로그에 unresolved reference가 표시됩니다. 그런 경우 GIT_DEPTH 값을 더 높게 변경해야 합니다.

git describe에 의존하는 작업은 GIT_DEPTH를 사용하는 경우 정상적으로 작동하지 않을 수 있습니다. 왜냐하면 Git 기록의 일부만 존재하기 때문입니다.

최근 3개의 커밋만 가져오거나 클론하려면:

variables:
  GIT_DEPTH: "3"

이를 variables 섹션에서 전역적으로 설정하거나 작업별로 설정할 수 있습니다.

Git 서브모듈 깊이

GIT_SUBMODULE_STRATEGYnormal 또는 recursive로 설정된 경우 GIT_SUBMODULE_DEPTH 변수를 사용하여 서브모듈의 가져오기와 복제 깊이를 지정할 수 있습니다. 이 변수는 전역적으로 설정하거나 작업별로 설정할 수 있습니다.

GIT_SUBMODULE_DEPTH 변수를 설정하면 서브모듈에 대한 GIT_DEPTH 설정을 덮어씁니다.

최근 3개 커밋만 가져오거나 복제하려면:

variables:
  GIT_SUBMODULE_DEPTH: 3

사용자 정의 빌드 디렉터리

기본적으로 GitLab Runner는 리포지터리를 $CI_BUILDS_DIR 디렉터리의 고유한 하위 경로에 복제합니다. 그러나 프로젝트에 따라 코드를 특정 디렉터리에 저장해야 할 수도 있습니다(Go 프로젝트 등). 이 경우, GIT_CLONE_PATH 변수를 지정하여 Runner에게 리포지터리를 복제할 디렉터리를 알려줄 수 있습니다.

variables:
  GIT_CLONE_PATH: $CI_BUILDS_DIR/project-name

test:
  script:
    - pwd

GIT_CLONE_PATH는 항상 $CI_BUILDS_DIR 내에 있어야 합니다. $CI_BUILDS_DIR에 설정된 디렉터리는 runners.builds_dir 설정과 실행자에 따라 달라집니다.

이는 Runner의 설정에서 custom_build_dir가 활성화된 경우에만 사용할 수 있습니다.

동시성 처리

동시성 값이 1보다 큰 실행자는 실패로 이어질 수 있습니다. 작업 간에 builds_dir를 공유하는 경우 여러 작업이 동일한 디렉터리에서 작업할 수 있습니다.

Runner는 이러한 상황을 방지하지 않습니다. 실행자 설정의 요구 사항을 준수하는 것은 관리자와 개발자의 책임입니다.

이러한 시나리오를 피하려면 Runner가 동시에 실행 중인 모든 작업에 대한 고유한 ID를 제공하는 두 가지 추가 변수를 노출합니다.

  • $CI_CONCURRENT_ID: 실행 중인 모든 작업에 대한 고유한 ID입니다.
  • $CI_CONCURRENT_PROJECT_ID: 실행 중인 모든 작업에 대한 고유한 ID이며, 프로젝트 내에서 실행됩니다.

어떠한 시나리오와 실행자에서도 잘 작동하는 가장 안정적인 구성은 GIT_CLONE_PATH$CI_CONCURRENT_ID를 사용하는 것입니다. 예를 들어:

variables:
  GIT_CLONE_PATH: $CI_BUILDS_DIR/$CI_CONCURRENT_ID/project-name

test:
  script:
    - pwd -P

$CI_CONCURRENT_PROJECT_ID$CI_PROJECT_PATH와 함께 사용해야 합니다. $CI_PROJECT_PATH는 리포지터리의 경로를 제공합니다. 즉, group/subgroup/project입니다. 예를 들어:

variables:
  GIT_CLONE_PATH: $CI_BUILDS_DIR/$CI_CONCURRENT_ID/$CI_PROJECT_PATH

test:
  script:
    - pwd -P

중첩 경로

GIT_CLONE_PATH의 값은 한 번 확장되며 내부 변수에 대한 중첩은 지원되지 않습니다.

예를 들어, 다음과 같이 변수를 정의하면:

variables:
  GOPATH: $CI_BUILDS_DIR/go
  GIT_CLONE_PATH: $GOPATH/src/namespace/project

GIT_CLONE_PATH의 값은 한 번 확장되어 $CI_BUILDS_DIR/go/src/namespace/project가 됩니다. 그러나 이것은 실패하게 됩니다. 왜냐하면 $CI_BUILDS_DIR이 확장되지 않았기 때문입니다.

작업 스테이지 시도

실행 중인 작업이 다음 스테이지를 실행하는 시도 횟수를 설정할 수 있습니다.

변수 설명
ARTIFACT_DOWNLOAD_ATTEMPTS 작업을 실행하는 시도 횟수
EXECUTOR_JOB_SECTION_ATTEMPTS No Such Container 오류가 발생한 후 작업에서 섹션을 실행하는 시도 횟수(Docker executor만 해당)
GET_SOURCES_ATTEMPTS 작업을 실행하는 시도 횟수
RESTORE_CACHE_ATTEMPTS 캐시를 복원하는 시도 횟수

기본값은 단일 시도입니다.

예시:

variables:
  GET_SOURCES_ATTEMPTS: 3

이 변수들은 전역적으로 또는 각 작업별로 variables 섹션에서 설정할 수 있습니다.

GitLab.com 인스턴스 실행자에서 사용할 수 없는 시스템 호출

GitLab.com 인스턴스 실행자는 CoreOS에서 실행됩니다. 따라서 C 표준 라이브러리의 getlogin과 같은 일부 시스템 호출을 사용할 수 없습니다.

아티팩트 및 캐시 설정

아티팩트 및 캐시 설정은 아티팩트와 캐시의 압축 비율을 제어합니다. 이 설정을 사용하여 작업에서 생성된 아카이브의 크기를 지정할 수 있습니다.

  • 느린 네트워크에서는 작은 아카이브가 업로드되는 속도가 더 빠를 수 있습니다.
  • 대역폭과 저장공간이 걱정되지 않는 빠른 네트워크에서는 아카이브가 더 커도 더 빠른 압축 비율로 업로드가 더 빨라질 수 있습니다.

GitLab PagesHTTP Range requests를 제공하려면 아티팩트는 ARTIFACT_COMPRESSION_LEVEL: fastest 설정을 사용해야 합니다. 이 기능은 압축되지 않은 zip 아카이브만 지원합니다.

업로드 및 다운로드 속도를 제공하는 미터를 활성화할 수 있습니다.

단일 작업에서 캐시 업로드 및 다운로드의 최대 시간을 설정할 수 있습니다. 이 설정을 사용하면 작업의 지속 시간이 상당히 증가하는 느린 캐시 업로드를 제한하는 데 유용할 수 있습니다.

variables:
  # 2초마다 업로드 및 다운로드 진행률 표시
  TRANSFER_METER_FREQUENCY: "2s"
  
  # 빠른 압축을 사용하여 아티팩트를 생성
  ARTIFACT_COMPRESSION_LEVEL: "fast"
  
  # 압축하지 않고 캐시를 사용
  CACHE_COMPRESSION_LEVEL: "fastest"
  
  # 캐시 업로드 및 다운로드의 최대 지속 시간 설정
  CACHE_REQUEST_TIMEOUT: 5
변수 설명
TRANSFER_METER_FREQUENCY 미터의 전송 속도를 얼마나 자주 표시할지 지정합니다. 시간 간격으로 설정 가능하며, 0으로 설정하면 미터가 비활성화됩니다(기본값). 값이 설정되면 파이프라인에서 아티팩트와 캐시의 업로드 및 다운로드에 대한 진행률 미터가 표시됩니다.
ARTIFACT_COMPRESSION_LEVEL 압축 비율을 조정하기 위해 fastest, fast, default, slow, 또는 slowest로 설정합니다. 이 설정은 Fastzip 아카이버에서만 작동하므로 GitLab Runner의 피처 플래그 FF_USE_FASTZIP를 활성화해야 합니다.
CACHE_COMPRESSION_LEVEL 압축 비율을 조정하기 위해 fastest, fast, default, slow, 또는 slowest로 설정합니다. 이 설정은 Fastzip 아카이버에서만 작동하므로 GitLab Runner의 피처 플래그 FF_USE_FASTZIP를 활성화해야 합니다.
CACHE_REQUEST_TIMEOUT 단일 작업에 대한 캐시 업로드 및 다운로드 작업의 최대 지속 시간을 분 단위로 구성합니다. 기본값은 10분입니다.

아티팩트 원산지 메타데이터

note
Zip 아카이브는 지원하는 유일한 아티팩트 유형입니다. 자세한 내용은 해당 이슈를 참조하세요.

러너(runner)는 모든 빌드 아티팩트에 대해 원산지 메타데이터를 생성하고 생성할 수 있습니다.

아티팩트 원산지 데이터를 활성화하려면 RUNNER_GENERATE_ARTIFACTS_METADATA 환경 변수를 true로 설정하세요. 이 변수를 전역 또는 개별 작업에 설정할 수 있습니다:

variables:
  RUNNER_GENERATE_ARTIFACTS_METADATA: "true"

job1:
  variables:
    RUNNER_GENERATE_ARTIFACTS_METADATA: "true"

메타데이터는 아티팩트와 함께 저장된 일반적인 텍스트 .json 파일에 렌더링됩니다. 파일 이름은 {ARTIFACT_NAME}-metadata.json입니다. ARTIFACT_NAME.gitlab-ci.yml 파일에서 정의된 아티팩트의 이름입니다. 이름이 정의되지 않은 경우 기본 파일 이름은 artifacts-metadata.json입니다.

원산지 메타데이터 형식

원산지 메타데이터는 in-toto attestation format의 0.1 버전을 기준으로 생성됩니다. 러너는 또한 기본적으로 SLSA v0.2를 준수하는 명세를 생성합니다.

SLSA v1.0 명세에 참여하려면 .gitlab-ci.yml 파일에 SLSA_PROVENANCE_SCHEMA_VERSION=v1 변수를 설정하세요. v0.2 명세는 폐기되었으며 GitLab 17.0에서 제거될 예정이며, v1.0 명세가 새로운 기본 형식이 될 예정입니다.

다음 필드는 기본적으로 채워집니다:

필드
_type https://in-toto.io/Statement/v0.1
subject.name 아티팩트의 파일 이름
subject.digest.sha256 아티팩트의 sha256 체크섬
predicateType https://slsa.dev/provenance/v0.2
predicate.buildType https://gitlab.com/gitlab-org/gitlab-runner/-/blob/{GITLAB_RUNNER_VERSION}/PROVENANCE.md 예: v15.0.0
predicate.builder.id 러너 세부 정보 페이지를 가리키는 URI, 예: https://gitlab.com/gitlab-com/www-gitlab-com/-/runners/3785264
predicate.invocation.configSource.uri https://gitlab.example.com/.../{PROJECT_NAME}
predicate.invocation.configSource.digest.sha256 리포지터리의 sha256 체크섬
predicate.invocation.configSource.entryPoint 빌드를 트리거한 CI 작업의 이름
predicate.invocation.environment.name 러너의 이름
predicate.invocation.environment.executor 러너 실행자
predicate.invocation.environment.architecture CI 작업이 실행되는 아키텍처
predicate.invocation.parameters 빌드 명령이 실행될 때 존재했던 모든 CI/CD 또는 환경 변수의 이름. 값은 비밀을 유출하지 않도록 항상 비어 있는 문자열로 표시됩니다.
metadata.buildStartedOn 빌드가 시작된 시간. RFC3339 형식
metadata.buildEndedOn 빌드가 종료된 시간. 메타데이터 생성은 빌드 중에 발생하므로 이 순간의 시간은 GitLab에 보고된 시간보다 약간 이른 시간입니다. RFC3339 형식
metadata.reproducible 빌드가 생성된 모든 메타데이터를 수집하여 재현 가능한지 여부. 항상 false
metadata.completeness.parameters 매개변수가 제공되었는지 여부. 항상 true
metadata.completeness.environment 빌더 환경이 보고되었는지 여부. 항상 true
metadata.completeness.materials 빌드 자료가 보고되었는지 여부. 항상 false

GitLab Runner가 생성할 수 있는 원산지 메타데이터의 예는 다음과 같습니다:

{
    "_type": "https://gitlab.com/gitlab-org/gitlab-runner/-/blob/v15.1.0/PROVENANCE.md",
    "subject": [
        {
            "name": "script.sh",
            "digest": {
                "sha256": "f5ae5ced234922eebe6461d32228ba8ab9c3d0c0f3983a3bef707e6e1a1ab52a"
            }
        }
    ],
    "predicateType": "https://slsa.dev/provenance/v0.2",
    "predicate": {
        "buildType": "https://gitlab.com/gitlab-org/gitlab-runner/-/blob/v15.1.0/PROVENANCE.md",
        "builder": {
            "id": "https://gitlab.com/ggeorgiev_gitlab/playground/-/runners/14811533"
        },
        "invocation": {
            "configSource": {
                "uri": "https://gitlab.com/ggeorgiev_gitlab/playground",
                "digest": {
                    "sha256": "f0582e2c9a16b5cc2cde90e8be8f1b50fd67c631"
                },
                "entryPoint": "whoami shell"
            },
            "environment": {
                "name": "local",
                "executor": "shell",
                "architecture": "amd64"
            },
            "parameters": {
                "CI_PIPELINE_ID": "",
                "CI_PIPELINE_URL": "",
                // 다른 모든 CI 변수 이름이 여기 나열됩니다. 비밀을 유출하지 않도록 항상 값을 빈 문자열로 표시됩니다.
            }
        },
        "metadata": {
            "buildStartedOn": "2022-06-17T00:47:27+03:00",
            "buildFinishedOn": "2022-06-17T00:47:28+03:00",
            "completeness": {
                "parameters": true,
                "environment": true,
                "materials": false
            },
            "reproducible": false
        },
        "materials": []
    }
}

스테이징 디렉터리

시스템의 기본 임시 디렉터리에 캐시 및 아티팩트를 보관하지 않으려면 다른 디렉터리를 지정할 수 있습니다.

시스템의 기본 임시 경로에 제약이 있는 경우 디렉터리를 변경해야 할 수도 있습니다. 디렉터리 위치에 빠른 디스크를 사용하면 성능을 향상시킬 수도 있습니다.

디렉터리를 변경하려면 CI 작업에서 변수로 ARCHIVER_STAGING_DIR를 설정하거나, 러너를 등록할 때 러너 변수를 사용하세요 (gitlab register --env ARCHIVER_STAGING_DIR=<dir>).

지정한 디렉터리는 아티팩트를 추출하기 전의 다운로드 위치로 사용됩니다. fastzip 아카이버를 사용하는 경우, 이 위치는 아카이빙할 때 스크래치 공간으로도 사용됩니다.

fastzip 구성하여 성능 향상시키기

fastzip을 튜닝하려면 FF_USE_FASTZIP 플래그가 활성화되었는지 확인하세요. 그런 다음 다음 환경 변수 중 하나를 사용하세요.

변수 설명
FASTZIP_ARCHIVER_CONCURRENCY 동시에 압축할 파일 수. 기본값은 사용 가능한 CPU 수입니다.
FASTZIP_ARCHIVER_BUFFER_SIZE 각 파일당 할당된 버퍼 크기를 나타냅니다. 이 값을 초과하는 데이터는 스크래치 공간으로 이동합니다. 기본값은 2 MiB입니다.
FASTZIP_EXTRACTOR_CONCURRENCY 동시에 압축 해제할 파일 수입니다. 기본값은 사용 가능한 CPU 수입니다.

zip 아카이브의 파일은 순차적으로 첨부됩니다. 이로 인해 동시 압축이 어려워집니다. fastzip은 이 제약을 극복하기 위해 먼저 파일을 디스크에 동시에 압축한 다음 결과를 zip 아카이브에 순차적으로 복사합니다.

더 작은 파일의 경우 디스크에 쓰지 않고 내용을 다시 읽지 않기 위해 각 스레드당 작은 버퍼가 사용됩니다. 이 설정은 FASTZIP_ARCHIVER_BUFFER_SIZE로 제어할 수 있습니다. 이 버퍼의 기본 크기는 2 MiB이며, 따라서 16의 스레드에는 32 MiB가 할당됩니다. 버퍼 크기를 초과하는 데이터는 디스크에 씌여지고 다시 읽힙니다. 그러므로 버퍼를 사용하지 않고, FASTZIP_ARCHIVER_BUFFER_SIZE: 0를 사용하고 스크래치 공간만 사용하는 것도 유효한 옵션입니다.

FASTZIP_ARCHIVER_CONCURRENCY는 동시에 압축할 파일 수를 제어합니다. 앞에서 언급한 대로, 이 설정은 얼마나 많은 메모리가 사용되고, 얼마나 많은 임시 데이터가 스크래치 공간에 쓰이는지 증가시킬 수 있습니다. 기본값은 사용 가능한 CPU 수이지만, 메모리 관련 문제로 인해 항상 최선의 설정이 아닐 수 있습니다.

FASTZIP_EXTRACTOR_CONCURRENCY는 한 번에 몇 개의 파일이 동시에 압축 해제되는지를 제어합니다. zip 아카이브의 파일은 원래로부터 동시에 읽힐 수 있으므로, 압축 해제기가 요구하는 추가 메모리 이외에는 메모리를 할당하지 않습니다. 이 값은 기본적으로 사용 가능한 CPU 수로 설정됩니다.