사용자 지정 실행기
- 소개됨 : GitLab Runner 12.1에서
GitLab Runner은 기본적으로 지원하지 않는 환경을 위해 사용자 지정 실행기를 제공합니다. 예를 들어, LXD 또는 Libvirt를 사용하는 경우입니다.
이를 통해 환경을 프로비저닝, 실행 및 정리하는 데 사용할 실행 파일을 구성하여 자체 실행기를 만들 수 있습니다.
사용자 정의 실행기에 구성하는 스크립트는 드라이버
라고 불립니다. 예를 들어 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]]
내부의 builds_dir
와 cache_dir
은 필수 필드입니다.
작업 실행에 필요한 전제 소프트웨어
사용자는 다음과 같은 환경을 설정해야 합니다. 이러한 환경은 PATH
에 있어야 합니다:
- Git 및 Git LFS: 일반 전제 조건을 참조하세요.
- GitLab Runner: 아티팩트 다운로드/업데이트 및 캐시에 사용됩니다.
단계
사용자 지정 실행기는 작업의 세부 정보를 구성하고, 환경을 준비하고 정리하며 작업 스크립트를 실행하기 위한 단계를 제공합니다. 각 단계는 특정 작업을 담당하며 고려해야 할 사항이 다릅니다.
사용자 지정 실행기에 의해 실행되는 각 단계는 내장된 GitLab Runner 실행기가 그들을 실행하는 시간에 실행됩니다.
실행될 각 단계에 대해 해당 실행 파일에서 사용할 수 있는 특정 환경 변수가 노출됩니다. 이러한 모든 단계에 대해 다음과 같은 환경 변수가 제공됩니다.
- 표준 CI/CD 환경 변수 및 사전 정의된 변수.
- 사용자 정의 실행기 실행 호스트 시스템에서 제공하는 모든 환경 변수.
- 모든 서비스 및 이용 가능한 설정.
CUSTOM_ENV_CI_JOB_SERVICES
로 JSON 형식으로 노출됩니다.
CI/CD 환경 변수와 사전 정의 변수는 시스템 환경 변수와의 충돌을 방지하기 위해 CUSTOM_ENV_
로 접두어가 붙습니다. 예를 들어 CI_BUILDS_DIR
은 CUSTOM_ENV_CI_BUILDS_DIR
로 사용할 수 있습니다.
단계는 다음 순서로 실행됩니다:
config_exec
prepare_exec
run_exec
cleanup_exec
서비스
- 소개됨 : GitLab Runner 13.6에서
서비스는 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.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
가 도움을 줄 수 있습니다. 이를 통해 config_exec
호출 중에 제공자를 한 번 연결하고 나서 job_env
로 수신된 자격 증명을 전달할 수 있습니다. 이것들은 다음으로 사용자 정의 실행기 호출에 의해 prepare_exec
, run_exec
및 cleanup_exec
에 전달됩니다. 이를 통해 드라이버는 매번 자격 증명 제공자에 연결하는 대신 변수를 읽고 있는 자격 증명을 사용할 수 있습니다.
중요한 점은 변수가 작업 자체에 자동으로 사용 가능하지는 않다는 것입니다. 이것은 사용자 정의 실행기 드라이버가 어떻게 구현되었는지에 완전히 의존하며 많은 경우에는 여기에 존재하지 않을 것입니다.
특정 실행기에서 특정 실행기에 의해 실행되는 각 작업에 일련의 변수를 전달할 수 있도록 job_env
설정을 고려하고 있다면 [[runners]]
의 environment
설정을 확인하세요.
변수가 동적이고 그 값이 다른 작업 간에 변경될 것으로 예상된다면 job_env
에 의해 전달된 변수가 작업 실행 호출에 추가될 것이 확실하도록 사용자 정의 실행기가 구현되었는지 확인해야 합니다.
준비
준비 단계는 prepare_exec
에 의해 실행됩니다.
이 시점에서 GitLab Runner는 작업에 대해 모든 것을 알고 있습니다(어디에서 실행될 것인가, 어떻게 실행될 것인가). 환경이 설정되어 작업이 실행될 수 있도록 하는 것만 남았습니다. GitLab Runner는 prepare_exec
에 지정된 실행 파일을 실행할 것입니다.
이것은 환경을 설정하는 데 책임이 있습니다(예: 가상 머신이나 컨테이너, 서비스 등을 만드는 것). 이 작업이 완료된 후, 우리는 환경이 작업을 실행할 수 있는 준비가 되어 있다고 기대합니다.
이 단계는 작업 실행 중에 한 번만 실행됩니다.
사용자는 구성에서 prepare_exec_timeout
을 설정하여 GitLab Runner가 프로세스를 종료하기 전에 환경을 준비하는 데 대기할 시간 제한을 설정할 수 있습니다.
이 실행 파일에서 반환된 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
위에서 언급된 각 단계에 대해 run_exec
실행 파일은 다음과 함께 실행될 것입니다:
- 평소의 환경 변수.
- 두 가지 인자:
- 사용자 정의 실행기에서 실행해야 하는 스크립트의 경로.
- 단계의 이름.
예를 들어:
/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 (deprecated)
우리는 [[runners]]
내부의 shell
로 구성된 쉘을 사용하여 스크립트를 생성합니다. 제공되지 않는 경우 OS 플랫폼에 대한 기본값이 사용됩니다.
아래 표는 각 스크립트가 무엇을 하는지와 해당 스크립트의 주된 목표가 무엇인지에 대해 자세히 설명한 것입니다.
스크립트 이름 | 스크립트 내용 |
---|---|
prepare_script
| 작업이 실행 중인 기계에 대한 간단한 디버그 정보입니다. |
get_sources
| Git 구성을 준비하고 리포지터리를 클론/페치합니다. GitLab의 모든 이점을 얻을 수 있도록 이것을 그대로 유지하는 것을 권장합니다. |
restore_cache
| 정의된 경우 캐시를 추출합니다. 이것은 gitlab-runner 바이너리가 $PATH 에서 사용 가능하다고 예상합니다.
|
download_artifacts
| 정의된 경우 아티팩트를 다운로드합니다. 이것은 gitlab-runner 바이너리가 $PATH 에서 사용 가능하다고 예상합니다.
|
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
이 실패하는 경우
사용자는 cleanup_exec_timeout
을 설정하여 GitLab Runner가 환경을 정리하기 전에 대기해야 하는 시간 제한을 설정할 수 있습니다.
이 실행 파일의 STDOUT
은 DEBUG 수준의 GitLab Runner 로그에 출력됩니다. 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
내부의 실행 파일이 다음 코드 중 하나로 종료될 때에만 처리됩니다. 사용자가 0이 아닌 종료 코드로 종료하면, 아래의 오류 코드 중 하나로 전파되어야 합니다.
빌드 실패
GitLab Runner는 사용자 작업에서 실패가 발생했음을 GitLab Runner에 알리기 위해 실행 파일에서 사용되어야 하는 BUILD_FAILURE_EXIT_CODE
환경 변수를 제공합니다. 실행 파일이 BUILD_FAILURE_EXIT_CODE
에서 코드로 종료하면, GitLab CI에서 작업이 적절히 실패로 표시됩니다.
만약 사용자가 .gitlab-ci.yml
파일 내에서 정의한 스크립트가 0이 아닌 코드로 종료하면, run_exec
은 BUILD_FAILURE_EXIT_CODE
값으로 종료해야 합니다.
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 초 |
SYSTEM_FAILURE_EXIT_CODE
를 사용하는 것을 강력히 권장합니다.작업 응답
작업 수준의 CUSTOM_ENV_
변수를 변경할 수 있으며, 이들은 CI/CD 변수 우선순위를 준수합니다. 이 기능이 바람직할 수 있지만, 신뢰할 수 있는 작업 컨텍스트가 필요한 경우, 전체 JSON 작업 응답이 자동으로 제공됩니다. Runner는 JOB_RESPONSE_FILE
환경 변수에서 참조되는 임시 파일을 생성하고, 이 파일은 모든 단계에 존재하며 정리 중에 자동으로 제거됩니다.
$ cat ${JOB_RESPONSE_FILE}
{"id": 123456, "token": "jobT0ken",...}