사용자 정의 실행기

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

GitLab Runner은 기본적으로 지원하지 않는 환경을 위해 사용자 정의 실행기를 제공합니다. 예를 들어, LXD나 Libvirt 등이 있습니다.

이를 통해 GitLab Runner를 환경을 프로비저닝, 실행 및 정리하기 위해 일부 실행 파일을 사용하도록 구성하여 사용자가 직접 실행기를 생성할 수 있습니다.

사용자 정의 실행기에 대해 구성하는 스크립트는 드라이버라고 합니다. 예를 들어, LXD 드라이버 또는 Libvirt 드라이버를 생성할 수 있습니다.

제한 사항

사용자 정의 실행기를 사용할 때 현재 제한 사항은 다음과 같습니다:

구성

사용 가능한 구성 키 몇 가지를 선택할 수 있습니다. 그 중 일부는 선택 사항입니다.

아래는 모든 사용 가능한 구성 키를 사용하여 사용자 정의 실행기를 구성하는 예시입니다:

[[runners]]
  name = "custom"
  url = "https://gitlab.com"
  token = "TOKEN"
  executor = "custom"
  builds_dir = "/builds"
  cache_dir = "/cache"
  [runners.custom]
    config_exec = "/path/to/config.sh"
    config_args = [ "SomeArg" ]
    config_exec_timeout = 200
    
    prepare_exec = "/path/to/script.sh"
    prepare_args = [ "SomeArg" ]
    prepare_exec_timeout = 200
    
    run_exec = "/path/to/binary"
    run_args = [ "SomeArg" ]
    
    cleanup_exec = "/path/to/executable"
    cleanup_args = [ "SomeArg" ]
    cleanup_exec_timeout = 200
    
    graceful_kill_timeout = 200
    force_kill_timeout = 200

필드 정의 및 필수 사항은 여기를 참조하세요.

또한, [[runners]] 내부의 builds_dircache_dir은 필수 필드입니다.

작업 실행을 위한 사전 소프트웨어

사용자는 다음과 같은 환경을 설정해야 합니다. 이 환경은 PATH에 있어야 합니다:

단계

사용자 정의 실행기는 단계를 제공하여 작업의 일부 세부 정보를 구성하고, 환경을 준비하고 정리하며 작업 스크립트를 실행할 수 있습니다. 각 단계는 특정 기능에 책임을 지고 고려해야 할 다른 사항이 있습니다.

사용자 정의 실행기에 의해 실행되는 각 단계는 기본 GitLab Runner 실행기에 의해 실행되는 시기에 실행됩니다.

실행될 각 단계에 대해 특정 환경 변수가 실행 파일에 노출되어 해당 Job에 대한 정보를 얻는 데 사용될 수 있습니다. 모든 단계에서 다음과 같은 환경 변수가 사용 가능합니다:

CI/CD 환경 변수 및 사전 정의된 변수는 시스템 환경 변수와의 충돌을 방지하기 위해 CUSTOM_ENV_로 접두사가 붙습니다. 예를 들어, CI_BUILDS_DIRCUSTOM_ENV_CI_BUILDS_DIR로 사용할 수 있습니다.

서비스

서비스CUSTOM_ENV_CI_JOB_SERVICES로 JSON 배열 형태로 노출됩니다.

예시:

custom:
  script:
    - echo $CUSTOM_ENV_CI_JOB_SERVICES
  services:
    - redis:latest
    - name: my-postgres:9.4
      alias: pg
      entrypoint: ["path", "to", "entrypoint"]
      command: ["path", "to", "cmd"]

위의 예시는 CUSTOM_ENV_CI_JOB_SERVICES 환경 변수를 다음과 같은 값으로 설정합니다:

[{"name":"redis:latest","alias":"","entrypoint":null,"command":null},{"name":"my-postgres:9.4","alias":"pg","entrypoint":["path","to","entrypoint"],"command":["path","to","cmd"]}]

구성

구성 단계는 config_exec에 의해 실행됩니다.

시간 실행 중에 일부 설정을 설정하고 싶을 수 있습니다. 예를 들어 프로젝트 ID에 따라 빌드 디렉터리를 설정할 수 있습니다. config_exec는 STDOUT에서 읽고 특정 키가 있는 유효한 JSON 문자열을 예상합니다.

예를 들어:

#!/usr/bin/env bash

cat << EOS
{
  "builds_dir": "/builds/${CUSTOM_ENV_CI_CONCURRENT_PROJECT_ID}/${CUSTOM_ENV_CI_PROJECT_PATH_SLUG}",
  "cache_dir": "/cache/${CUSTOM_ENV_CI_CONCURRENT_PROJECT_ID}/${CUSTOM_ENV_CI_PROJECT_PATH_SLUG}",
  "builds_dir_is_shared": true,
  "hostname": "custom-hostname",
  "driver": {
    "name": "test driver",
    "version": "v0.0.1"
  },
  "job_env" : {
    "CUSTOM_ENVIRONMENT": "example"
  }
}
EOS

JSON 문자열 내의 추가 키는 무시됩니다. 유효한 JSON 문자열이 아니면, 이 단계는 실패하고 두 번 더 재시도됩니다.

매개변수 유형 필수 허용 여부 설명
builds_dir 문자열 작업의 작업 디렉터리가 만들어질 기본 디렉터리입니다.
cache_dir 문자열 로컬 캐시가 저장될 기본 디렉터리입니다.
builds_dir_is_shared 불리언 n/a 환경이 동시 작업 간에 공유되는지 여부를 정의합니다.
hostname 문자열 러너에 의해 저장된 작업의 “메타데이터”와 연결할 호스트 이름입니다. 정의되지 않으면 호스트 이름이 설정되지 않습니다.
driver.name 문자열 드라이버에 대한 사용자 정의 이름입니다. Using custom executor... 라인과 함께 출력됩니다. 정의되지 않으면 드라이버에 관한 정보를 출력하지 않습니다.
driver.version 문자열 드라이버에 대한 사용자 정의 버전입니다. Using custom executor... 라인과 함께 출력됩니다. 정의되지 않으면 이름 정보만 출력됩니다.
job_env 개체 작업 실행 시 모든 다음 단계에 대해 환경 변수를 통해 사용 가능한 이름-값 쌍입니다. 작업에 사용 가능하고, 드라이버에는 사용할 수 있습니다. 자세한 내용은 job_env 사용법을 참조하세요.

실행 파일의 STDERR는 작업 로그에 출력됩니다.

유저는 config_exec_timeout 를 정의하여 GitLab Runner가 프로세스를 종료하기 전에 JSON 문자열을 반환하기까지 기다릴 시한을 설정할 수 있습니다.

만약 config_exec_args 중 하나라도 정의되어 있다면, 이것들은 config_exec에서 정의된 실행 파일에 순서대로 추가됩니다. 예를 들어 config.toml 내용이 아래와 같다면:

...
[runners.custom]
  ...
  config_exec = "/path/to/config"
  config_args = [ "Arg1", "Arg2" ]
  ...

GitLab Runner는 /path/to/config Arg1 Arg2로 실행합니다.

job_env 사용법

job_env 구성의 주요 목적은 작업 실행 후속 단계에 대한 사용자 정의 실행 드라이버 호출의 컨텍스트로 변수를 전달하는 것입니다.

예를 들어, 작업 실행 환경과의 연결을 위해 일부 자격 증명을 준비해야 하며, 이 작업이 매우 비용이 많이든다고 가정해보겠습니다. 로컬 자격 증명 제공자에 연결하여 사용자 정의 실행 드라이버가 작업 실행 환경과 연결하는 데 사용할 수 있는 임시 SSH 사용자 이름과 암호가 필요한 경우를 생각해 보겠습니다.

각 작업 실행 단계준비, 여러 실행 호출 및 정리는 드라이버의 별도 실행을 나타내는 사용자 정의 실행 흐름에서 각각 별도의 컨텍스트입니다. 자격 증명 해결 예제의 경우, 자격 증명 제공자에 연결은 각 시간마다 수행해야 합니다.

이 작업이 많은 비용이 든다면 전체 작업 실행을 위해 한 번 실행한 후 자격 증명을 재사용하고자 할 수 있습니다. 그런 다음 job_env가 도움이 될 수 있습니다. job_env를 사용하면 config_exec 호출 중에 한 번 연결하고, 다음에 job_env로 수신한 자격 증명을 전달할 수 있습니다. 그런 다음 이들은 prepare_exec, run_execcleanup_exec에 대해 호출되는 사용자 정의 실행도구의 변수 디렉터리에 추가됩니다. 이러면 드라이버는 각 시간마다 자격 증명 제공자에 연결하는 대신 변수를 읽고 존재하는 자격 증명을 사용할 수 있습니다.

이해해야 할 중요한 점은 변수가 작업 그 자체에 자동으로 사용 가능한 것은 아니라는 것입니다. 이것은 완전히 사용자 정의 실행 드라이버가 구현된 방식에 따라 달라집니다. 많은 경우에는 그 곳에 없을 것입니다.

특정 실행기가 실행하는 각 작업에 일련의 변수를 전달할 수 있도록 job_env를 설정한 경우, 해당 실행기의 [[runners]]environment로 살펴보세요.

변수가 동적이고 그 값이 다른 작업 간에 변경될 것으로 예상된다면, job_env에서 전달된 변수가 작업 실행 호출에 추가될 수 있도록 드라이버가 구현되었는지 확인해야 합니다.

게다가, :: 커맨드나 ::: 커맨드로 시작하는 문장의 번역은 금지되어 있습니다.

정리

정리 단계는 cleanup_exec에 의해 실행됩니다.

이 최종 단계는 이전 단계 중 하나라도 실패한 경우에도 실행됩니다. 이 단계의 주요 목표는 설정될 수 있는 모든 환경을 정리하는 것입니다. 예를 들어, VM을 끄거나 컨테이너를 삭제하는 것 등이 있습니다.

cleanup_exec의 결과는 작업 상태에 영향을 주지 않습니다. 예를 들어, 작업은 다음과 같은 경우에도 성공으로 표시됩니다.

  • prepare_execrun_exec 둘 다 성공함.
  • cleanup_exec이 실패함.

사용자는 cleanup_exec_timeout를 설정하여 GitLab Runner가 프로세스를 종료하기 전에 환경을 정리하는 데 소요될 시간을 지정할 수 있습니다.

이 실행 파일의 STDOUT은 GitLab Runner 로그에 DEBUG 수준으로 출력됩니다. STDERR는 WARN 수준으로 로그에 출력됩니다.

cleanup_exec_args 중 하나라도 정의된 경우, 이들은 cleanup_exec에서 정의된 실행 파일에 순서대로 추가됩니다. 예를 들어, 아래 config.toml 내용이 있으면:

...
[runners.custom]
  ...
  cleanup_exec = "/path/to/bin"
  cleanup_args = [ "Arg1", "Arg2" ]
  ...

GitLab Runner는 /path/to/bin Arg1 Arg2로 실행합니다.

실행 프로그램 종료 및 중지

GitLab Runner는 실행 파일을 정상적으로 종료하려고 합니다. 이는 다음과 같은 조건 중 하나일 때 시도됩니다.

  • config_exec_timeout, prepare_exec_timeout, 또는 cleanup_exec_timeout이 충족될 때.
  • 작업이 타임아웃된 경우.
  • 작업이 취소된 경우.

타임아웃이 발생하면 SIGTERM이 실행 파일로 전송되며, exec_terminate_timeout 카운트다운이 시작됩니다. 실행 파일은 이 신호를 듣고 리소스를 정리해야 합니다. 만약 exec_terminate_timeout이 지나도 프로세스가 계속 실행 중이면, SIGKILL이 프로세스로 전송됩니다. exec_force_kill_timeout 가 시작됩니다. 만약 exec_force_kill_timeout이 끝나도 프로세스가 계속 실행 중이면, GitLab Runner는 그 프로세스를 포기하고 더 이상 중지/종료를 시도하지 않습니다. 이러한 타임아웃이 config_exec, prepare_exec, 또는 run_exec 동안 동시에 발생하면, 빌드는 실패로 표시됩니다.

GitLab 13.1부터는 드라이버에 의해 생성된 모든 자식 프로세스가 UNIX 기반 시스템에서 위에서 설명한 정상적인 종료 프로세스를 받습니다. 이것은 모든 자식 프로세스가 속한 프로세스 그룹으로 메인 프로세스를 설정함으로써 달성됩니다.

오류 처리

GitLab Runner가 다르게 처리할 수 있는 오류 유형이 두 가지 있습니다. 이러한 오류는 config_exec, prepare_exec, run_exec, cleanup_exec 내부의 실행 파일이 다음 코드 중 하나로 종료될 때만 처리됩니다. 사용자가 0이 아닌 종료 코드로 종료하면 아래 오류 코드 중 하나로 전파되어야 합니다.

빌드 실패

GitLab Runner는 실행 파일에서 BUILD_FAILURE_EXIT_CODE 환경 변수를 제공하여 사용자 작업에 실패가 있음을 알리는 종료 코드로 사용해야 합니다. 만약 실행 파일이 BUILD_FAILURE_EXIT_CODE로 종료된 경우, GitLab CI에서 작업은 적절히 실패로 표시됩니다.

유저가 .gitlab-ci.yml 파일 내에서 정의한 스크립트가 0이 아닌 코드로 종료된다면, run_execBUILD_FAILURE_EXIT_CODE 값으로 종료되어야 합니다.

note
당신의 바이너리/스크립트가 미래에도 변경될 수 있으므로, 값을 하드 코딩하는 대신에 BUILD_FAILURE_EXIT_CODE를 사용하는 것을 강력히 권장합니다.

시스템 실패

지정된 SYSTEM_FAILURE_EXIT_CODE에서 프로세스를 종료하여 GitLab Runner에 시스템 실패를 보낼 수 있습니다. 이 오류 코드가 반환되면, 일부 단계에서 GitLab Runner는 해당 단계를 재시도하며, 재시도 중에 성공하지 못하면 작업을 실패로 표시합니다.

아래는 어떤 단계들이 재시도되는지, 그리고 각 재시도 사이의 대기 기간은 얼마나 되는지 설명한 표입니다.

단계 이름 재시도 횟수 각 재시도 사이 대기 기간
prepare_exec 3 3초
get_sources GET_SOURCES_ATTEMPTS 변수의 값. (기본값 1) 0초
restore_cache RESTORE_CACHE_ATTEMPTS 변수의 값. (기본값 1) 0초
download_artifacts ARTIFACT_DOWNLOAD_ATTEMPTS 변수의 값. (기본값 1) 0초
note
당신의 바이너리/스크립트가 미래에도 변경될 수 있으므로, 값을 하드 코딩하는 대신에 SYSTEM_FAILURE_EXIT_CODE를 사용하는 것을 강력히 권장합니다.

작업 응답

문서화된 CI/CD 변수 우선순위를 준수하는 작업 수준의 CUSTOM_ENV_ 변수를 변경할 수 있습니다. 이 기능은 유용할 수 있지만, 신뢰할 수 있는 작업 컨텍스트가 필요한 경우에는 실행 중에 전체 JSON 작업 응답이 자동으로 제공됩니다. Runner는 임시 파일을 생성하며, 이 파일은 모든 단계에 존재하며 정리 중에 자동으로 제거됩니다.

$ cat ${JOB_RESPONSE_FILE}
{"id": 123456, "token": "jobT0ken",...}