커스텀 실행기
- 도입됨 GitLab Runner 12.1에서
GitLab Runner는 네이티브로 지원하지 않는 환경을 위한 커스텀 실행기를 제공합니다. 예를 들어, LXD 또는 Libvirt입니다.
이를 통해 GitLab Runner를 구성하여 환경을 프로비저닝, 실행 및 정리하는 데 사용할 수 있는 실행 파일을 사용하여 자체 실행기를 생성할 수 있습니다.
커스텀 실행기에 대해 구성한 스크립트는 Drivers
라고 불립니다. 예를 들어, 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.custom]
섹션 구성을 참조하세요.
또한 [[runners]]
(../configuration/advanced-configuration.md#the-runners-section) 내의 builds_dir
및 cache_dir
는 필수 필드입니다.
작업 실행을 위한 필수 소프트웨어
사용자는 환경을 설정해야 하며, 다음은 PATH
에 있어야 하는 항목입니다:
-
Git 및 Git LFS:
공통 필수 조건을 참조하세요. - GitLab Runner: 아티팩트를 다운로드/업데이트하는 데 사용됩니다.
단계
커스텀 실행기는 작업의 세부정보를 구성하고, 환경을 준비하고 정리하며, 그 안에서 작업 스크립트를 실행하기 위한 단계를 제공합니다. 각 단계는 특정한 작업을 수행하는 책임이 있으며, 염두에 두어야 할 사항이 다릅니다.
커스텀 실행기에 의해 실행되는 각 단계는 내장 GitLab Runner 실행기가 이를 실행하는 시점에 실행됩니다.
실행될 각 단계에 대해 특정 환경 변수가 실행 파일에 노출되어 현재 실행 중인 특정 작업에 대한 정보를 얻는 데 사용할 수 있습니다. 모든 단계는 다음과 같은 환경 변수를 사용할 수 있습니다:
- 표준 CI/CD 환경 변수, 포함하여
미리 정의된 변수. - 커스텀 실행기 러너 호스트 시스템에서 제공된 모든 환경 변수.
- 모든 서비스 및 그들의 사용 가능한 설정.
JSON 형식으로CUSTOM_ENV_CI_JOB_SERVICES
로 노출됩니다.
CI/CD 환경 변수와 미리 정의된 변수는 시스템 환경 변수와의 충돌을 방지하기 위해 CUSTOM_ENV_
로 접두사가 붙습니다. 예를 들어, CI_BUILDS_DIR
는 CUSTOM_ENV_CI_BUILDS_DIR
로 사용할 수 있습니다.
단계는 다음 순서로 실행됩니다:
config_exec
prepare_exec
run_exec
cleanup_exec
서비스
서비스는 JSON 배열로 노출되며, CUSTOM_ENV_CI_JOB_SERVICES
로 표현됩니다.
예시:
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 단계는 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 사용자 이름과 비밀번호를 얻어야 한다고 가정해 보겠습니다.
각 작업 실행 단계: prepare
, 여러 개의 run
호출과 cleanup
를 사용하여 사용자 지정 실행기를 실행하는 흐름에서 컨텍스트는 각각 별개의 실행입니다. 자격 증명 해결 예제에서는 각 경우마다 자격 증명 제공업체에 연결해야 합니다.
이 작업이 비쌀 경우, 전체 작업 실행을 위해 한 번만 수행하고 모든 작업 실행 단계에 대해 자격 증명을 재사용할 수 있습니다. 여기서 job_env
가 도움이 될 수 있습니다. 이를 통해 config_exec
호출 중에 한 번 제공업체와 연결하고 받은 자격 증명을 job_env
로 전달할 수 있습니다. 그러면 사용자 지정 실행기가 prepare_exec
, run_exec
및 cleanup_exec
호출을 받을 때 해당 자격 증명이 있는 변수 목록에 추가됩니다. 이렇게 하면 드라이버가 매번 자격 증명 제공업체에 연결하는 대신 변수를 읽고 현재 있는 자격 증명을 사용할 수 있습니다.
중요한 것은 변수가 작업 자체에서 자동으로 사용 가능하지 않다는 것을 이해하는 것입니다. 이는 완전히 사용자 지정 실행기 드라이버가 어떻게 구현되었는지에 달려 있으며 대부분의 경우 그곳에 존재하지 않을 것입니다.
특정 러너에 의해 실행된 모든 작업에 변수 세트를 전달하기 위해 job_env
설정을 고려하고 있다면, [[runners]]
의 environment
설정을 살펴보세요.
변수가 동적이고 다양한 작업 간에 값이 변경될 것으로 예상되는 경우, 귀하의 드라이버가 job_env
로 전달된 변수가 작업 실행 호출에 추가되도록 구현되었는지 확인해야 합니다.
준비
준비 단계는 prepare_exec
에 의해 실행됩니다.
이 시점에서 GitLab Runner는 작업에 대한 모든 것을 알고 있습니다(어디에서 어떻게 실행될 것인지). 남은 유일한 것은 작업을 실행할 수 있도록 환경을 설정하는 것입니다. GitLab Runner는 prepare_exec
에 지정된 실행 파일을 실행합니다.
이것은 환경을 설정하는 책임이 있습니다(예: 가상 머신 또는 컨테이너 생성, 서비스 또는 기타 아무 것이든). 완료되면 환경이 작업을 실행할 준비가 되었기를 기대합니다.
이 단계는 작업 실행에서 한 번만 실행됩니다.
사용자는 GitLab Runner가 프로세스를 종료하기 전에 환경을 준비하는 데 얼마나 오랫동안 기다려야 하는지를 설정하려는 경우 prepare_exec_timeout
을 설정할 수 있습니다.
이 실행 파일에서 반환된 STDOUT
및 STDERR
는 작업 로그에 인쇄됩니다.
prepare_exec_args
가 정의된 경우, 이는 prepare_exec
에 정의된 실행 파일에 순서대로 추가됩니다. 예를 들어 아래의 config.toml
내용을 가정해 보겠습니다:
...
[runners.custom]
...
prepare_exec = "/path/to/bin"
prepare_args = [ "Arg1", "Arg2" ]
...
GitLab Runner는 /path/to/bin Arg1 Arg2
로 실행합니다.
실행
실행 단계는 run_exec
에 의해 실행됩니다.
이 실행 파일에서 반환된 STDOUT
및 STDERR
는
작업 로그에 출력됩니다.
다른 단계들과 달리, run_exec
단계는 여러 번 실행되며,
아래에 나열된 하위 단계로 나뉘어 있습니다:
prepare_script
get_sources
restore_cache
download_artifacts
step_*
build_script
step_*
after_script
-
archive_cache
또는archive_cache_on_failure
-
upload_artifacts_on_success
또는upload_artifacts_on_failure
cleanup_file_variables
참고:
GitLab Runner 14.0 이상에서는 build_script
가 step_script
로 대체됩니다. 자세한 내용은 이 문제를 참조하세요.
위에 언급된 각 단계에 대해, run_exec
실행 파일은 다음과 함께 실행됩니다:
- 일반 환경 변수.
- 두 개의 인자:
- GitLab Runner가 커스텀 실행자가 실행할 스크립트의 경로.
- 단계의 이름.
예를 들어:
/path/to/run_exec.sh /path/to/tmp/script1 prepare_executor
/path/to/run_exec.sh /path/to/tmp/script1 prepare_script
/path/to/run_exec.sh /path/to/tmp/script1 get_sources
run_args
가 정의되어 있다면, 그것은 run_exec
실행 파일에 전달되는 첫 번째 인자 세트가 되며,
그 후 GitLab Runner가 다른 인자를 추가합니다. 예를 들어 다음과 같은 config.toml
이 있다고 가정해 봅시다:
...
[runners.custom]
...
run_exec = "/path/to/run_exec.sh"
run_args = [ "Arg1", "Arg2" ]
...
GitLab Runner는 다음 인자와 함께 실행 파일을 실행합니다:
/path/to/run_exec.sh Arg1 Arg2 /path/to/tmp/script1 prepare_executor
/path/to/run_exec.sh Arg1 Arg2 /path/to/tmp/script1 prepare_script
/path/to/run_exec.sh Arg1 Arg2 /path/to/tmp/script1 get_sources
이 실행 파일은 첫 번째 인수로 지정된 스크립트를 실행하는 역할을 합니다. 이 스크립트는 GitLab Runner 실행자가 일반적으로 수행할 수 있는 모든 스크립트를 포함합니다: 복제, 아티팩트 다운로드, 사용자 스크립트 실행 및 아래에 설명된 모든 단계. 스크립트는 다음과 같은 쉘 형식일 수 있습니다:
- Bash
- PowerShell Desktop
- PowerShell Core
- Batch (사용 중단)
우리는 [[runners]]
내의
shell
로 구성된 쉘을 사용하여 스크립트를 생성합니다.
제공되지 않은 경우, OS 플랫폼에 대한 기본값이 사용됩니다.
아래의 표는 각 스크립트가 수행하는 작업과 해당 스크립트의 주요 목표에 대한 자세한 설명입니다.
스크립트 이름 | 스크립트 내용 |
---|---|
prepare_script |
작업이 실행되는 머신에 대한 간단한 디버그 정보. |
get_sources |
Git 구성을 준비하고, 저장소를 복제/패치합니다. GitLab이 제공하는 Git 전략의 모든 이점을 얻기 때문에 그대로 유지하는 것이 좋습니다. |
restore_cache |
정의된 경우 캐시를 추출합니다. $PATH 에서 gitlab-runner 이진 파일이 사용 가능해야 합니다. |
download_artifacts |
정의된 경우 아티팩트를 다운로드합니다. $PATH 에서 gitlab-runner 이진 파일이 사용 가능해야 합니다. |
step_* |
GitLab에 의해 생성됩니다. 실행할 스크립트 세트입니다. 커스텀 실행자에게 전송되지 않을 수 있습니다. step_release 및 step_accessibility 와 같은 여러 단계가 있을 수 있습니다. 이는 .gitlab-ci.yml 파일의 기능일 수 있습니다. |
build_script |
before_script 와 script 의 조합입니다. GitLab Runner 14.0 이상에서는 build_script 가 step_script 로 대체됩니다. 자세한 내용은 이 문제를 참조하세요. |
after_script |
작업에서 정의된 after_script 입니다. 이전 단계가 실패하더라도 항상 호출됩니다. |
archive_cache |
정의된 경우 모든 캐시의 아카이브를 생성합니다. build_script 가 성공할 때만 실행됩니다. |
archive_cache_on_failure |
정의된 경우 모든 캐시의 아카이브를 생성합니다. build_script 가 실패할 때만 실행됩니다. |
upload_artifacts_on_success |
정의된 경우 아티팩트를 업로드합니다. build_script 가 성공할 때만 실행됩니다. |
upload_artifacts_on_failure |
정의된 경우 아티팩트를 업로드합니다. build_script 가 실패할 때만 실행됩니다. |
cleanup_file_variables |
디스크에서 모든 파일 기반 변수를 삭제합니다. |
정리
정리 단계는 cleanup_exec
에 의해 실행됩니다.
이 마지막 단계는 이전 단계 중 하나가 실패하더라도 실행됩니다.
이 단계의 주요 목표는 설정되었을 수 있는 환경을 정리하는 것입니다.
예를 들어, VM을 종료하거나 컨테이너를 삭제하는 것입니다.
cleanup_exec
의 결과는 작업 상태에 영향을 미치지 않습니다.
예를 들어, 다음 경우에도 작업은 성공으로 표시됩니다:
-
prepare_exec
와run_exec
가 성공합니다. -
cleanup_exec
가 실패합니다.
사용자는 GitLab Runner가 프로세스를 종료하기 전에 환경을 정리하는 데 얼마나 기다릴지를 설정하려면
cleanup_exec_timeout
을 설정할 수 있습니다.
이 실행 파일의 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
중에 충족되면 빌드는 실패로 표시됩니다.
드라이버에 의해 생성된 모든 자식 프로세스는 UNIX 기반 시스템에서 위에서 설명한 정상 종료 프로세스를 수신합니다.
이는 메인 프로세스가 모든 자식 프로세스가 속하는 프로세스 그룹으로 설정되어 있도록 하여 달성됩니다.
오류 처리
GitLab Runner가 다르게 처리할 수 있는 두 가지 오류 유형이 있습니다.
이러한 오류는 config_exec
, prepare_exec
, run_exec
및 cleanup_exec
내에서 실행 파일이 이러한 코드로 종료될 때만 처리됩니다.
사용자가 비제로 종료 코드를 반환하면, 아래의 오류 코드 중 하나로 전파되어야 합니다.
사용자 스크립트가 이 코드 중 하나로 종료되면, 실행 파일 종료 코드로 전파되어야 합니다.
빌드 실패
GitLab Runner는 실행 파일에서 사용해야 하는 BUILD_FAILURE_EXIT_CODE
환경 변수를 제공합니다.
이는 사용자의 작업에서 실패가 발생했음을 GitLab Runner에 알리기 위한 종료 코드입니다.
실행 파일이 BUILD_FAILURE_EXIT_CODE
에서 반환된 코드로 종료되면, 빌드는 GitLab CI에서 적절하게 실패로 표시됩니다.
사용자가 .gitlab-ci.yml
파일 내에서 정의한 스크립트가 비영(zero)이 아닌 코드로 종료되면, run_exec
는 BUILD_FAILURE_EXIT_CODE
값으로 종료해야 합니다.
참고:
우리는 하드 코딩된 값 대신 BUILD_FAILURE_EXIT_CODE
를 사용하는 것을 강력히 권장합니다.
이는 모든 릴리스에서 변경될 수 있으므로 여러분의 바이너리/스크립트가 미래에도 호환되도록 합니다.
시스템 실패
시스템 실패를 GitLab Runner에 보내려면 SYSTEM_FAILURE_EXIT_CODE
에서 지정한 오류 코드로 프로세스를 종료하면 됩니다.
이 오류 코드가 반환되면, 특정 단계에서 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초 |
참고:
우리는 하드 코딩된 값 대신 SYSTEM_FAILURE_EXIT_CODE
를 사용하는 것을 강력히 권장합니다.
이는 모든 릴리스에서 변경될 수 있으므로 여러분의 바이너리/스크립트가 미래에도 호환되도록 합니다.
작업 응답
작업 수준의 CUSTOM_ENV_
변수를 변경할 수 있으며, 이는 문서화된 CI/CD 변수 우선 순위를 따릅니다.
이 기능은 바람직할 수 있지만, 신뢰할 수 있는 작업 컨텍스트가 필요할 때 전체 JSON 작업 응답이 자동으로 제공됩니다.
러너는 임시 파일을 생성하며, 이는 JOB_RESPONSE_FILE
환경 변수에서 참조됩니다.
이 파일은 모든 단계에서 존재하며 정리 중에 자동으로 제거됩니다.
$ cat ${JOB_RESPONSE_FILE}
{"id": 123456, "token": "jobT0ken",...}