- 러너가 Kubernetes 포드를 생성하는 방식
- Kubernetes API에 연결
- 구성 설정
- 실행기 서비스 계정 구성
- 포드 및 컨테이너
- 운영 체제, 아키텍처 및 Windows 커널 버전
- 노드
- 네트워킹
- 볼륨
- 빌드에서 Docker 사용하기
- 작업 실행
- 준비 단계 동안의 리소스 확인
- Kubernetes 클러스터의 내결함성
쿠버네티스 실행기
Kubernetes 클러스터를 빌드에 사용하기 위해 Kubernetes 실행기를 사용하세요. 실행기는 Kubernetes 클러스터 API를 호출하고 각 GitLab CI 작업에 대한 포드를 생성합니다.
Kubernetes 실행기는 빌드를 여러 단계로 나눕니다:
-
준비: Kubernetes 클러스터에 대한 포드를 생성합니다.
이는 빌드 및 실행할 서비스에 필요한 컨테이너를 생성합니다. - 사전 빌드: 이전 단계에서 캐시를 복원하고 아티팩트를 다운로드하며 클론합니다. 이 단계는 포드의 일부로서 특수 컨테이너에서 실행됩니다.
- 빌드: 사용자 빌드.
- 사후 빌드: 캐시를 생성하고 GitLab에 아티팩트를 업로드합니다. 이 단계도 포드의 일부로서 특수 컨테이너를 사용합니다.
러너가 Kubernetes 포드를 생성하는 방식
다음 다이어그램은 GitLab 인스턴스와 Kubernetes 클러스터에 호스팅된 러너 간의 상호작용을 보여줍니다. 러너는 클러스터에서 포드를 생성하기 위해 Kubernetes API를 호출합니다.
포드는 .gitlab-ci.yml
또는 config.toml
파일에 정의된 각 service
에 대해 다음 컨테이너로 구성됩니다:
-
build
로 정의된 빌드 컨테이너. -
helper
로 정의된 헬퍼 컨테이너. -
svc-X
로 정의된 서비스 컨테이너, 여기서X
는[0-9]+
입니다.
서비스와 컨테이너는 동일한 Kubernetes 포드에서 실행되며 동일한 localhost 주소를 공유합니다. 다음 제약 조건이 적용됩니다:
- GitLab Runner 12.8 및 Kubernetes 1.7 이상에서 서비스는 DNS 이름을 통해 접근할 수 있습니다. 이전 버전을 사용하는 경우,
localhost
를 사용해야 합니다. - 동일한 포트를 사용하는 여러 서비스를 사용할 수 없습니다. 예를 들어, 동시에 두 개의
mysql
서비스를 가질 수 없습니다.
다이어그램의 상호작용은 모든 Kubernetes 클러스터에 대해 유효합니다. 예를 들어, 주요 퍼블릭 클라우드 제공업체에서 호스팅되는 턴키 솔루션 또는 자체 관리 Kubernetes 설치가 있습니다.
Kubernetes API에 연결
다음 옵션을 사용하여 Kubernetes API에 연결하세요. 제공된 사용자 계정은 지정된 네임스페이스에서 포드를 생성, 나열 및 연결할 수 있는 권한이 있어야 합니다.
옵션 | 설명 |
---|---|
host |
선택적 Kubernetes apiserver 호스트 URL(지정하지 않으면 자동 검색 시도). |
cert_file |
선택적 Kubernetes apiserver 사용자 인증서. |
key_file |
선택적 Kubernetes apiserver 사용자 인증 개인 키. |
ca_file |
선택적 Kubernetes apiserver ca 인증서. |
Kubernetes 클러스터에서 GitLab Runner를 실행하는 경우, GitLab Runner가 Kubernetes API를 자동으로 검색할 수 있도록 이 모든 필드를 생략해야 합니다.
클러스터 외부에서 GitLab Runner를 실행하는 경우, 각 설정을 반드시 지정하고 GitLab Runner가 클러스터에서 Kubernetes API에 접근할 수 있도록 해야 합니다.
Kubernetes API 호출을 위한 Bearer Token 설정
API 호출을 통해 포드를 생성하기 위한 Bearer Token을 설정하려면 KUBERNETES_BEARER_TOKEN
변수를 사용하세요.
이는 프로젝트 소유자가 프로젝트 비밀 변수를 사용하여 Bearer Token을 지정할 수 있도록 합니다.
Bearer Token을 지정할 때는 Host
구성 설정을 설정해야 합니다.
variables:
KUBERNETES_BEARER_TOKEN: thebearertokenfromanothernamespace
러너 API 권한 구성
코어 API 그룹에 대한 권한을 구성하려면 GitLab Runner Helm 차트의 values.yml
파일을 업데이트하세요.
다음 중 하나를 선택할 수 있습니다:
-
rbac.create
를true
로 설정합니다. -
다음 권한을 가진 서비스 계정을
rbac.serviceAccountName: <service_account_name>
으로 지정합니다.values.yml
파일에서.
자원 | 동사 (선택적 기능 플래그) |
---|---|
events | list, watch (FF_PRINT_POD_EVENTS=true ) |
namespaces | create, delete |
pods | attach (FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY=false ), create, delete, exec, get, watch (FF_KUBERNETES_HONOR_ENTRYPOINT=true, FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY=false ) |
pods/log | get (FF_KUBERNETES_HONOR_ENTRYPOINT=true, FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY=false, FF_WAIT_FOR_POD_TO_BE_REACHABLE=true ), list (FF_KUBERNETES_HONOR_ENTRYPOINT=true, FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY=false ) |
secrets | create, delete, get, update |
serviceAccounts | get |
services | create, get |
-
serviceAccount
권한은 다음의 경우에만 필요합니다:-
GitLab 15.0 및 15.1의 경우.
-
GitLab 15.0.1, 15.1.1 및 15.2가
resource_availability_check_max_attempts
가 0보다 높은 값으로 설정된 경우.
-
-
GitLab Runner 15.8부터는
configmaps
권한이 더 이상 필요하지 않습니다. -
event
권한은 다음의 경우에만 필요합니다:- GitLab 16.2.1 이상.
-
namespace
권한은 다음의 경우에만 필요합니다:namespace_per_job
을 통해 네임스페이스 격리를 활성화할 때.
-
pods/log
권한은 다음 시나리오 중 하나가 참일 때만 필요합니다:-
FF_KUBERNETES_HONOR_ENTRYPOINT
기능 플래그가 활성화되어 있습니다. -
CI_DEBUG_SERVICES
변수가true
로 설정된 경우에FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY
기능 플래그가 비활성화됩니다.
-
구성 설정
Kubernetes 실행자를 구성하려면 config.toml
파일에서 다음 설정을 사용하세요.
CPU 요청 및 제한
설정 | 설명 |
---|---|
cpu_limit |
빌드 컨테이너에 할당된 CPU입니다. |
cpu_limit_overwrite_max_allowed |
빌드 컨테이너에 대한 CPU 할당을 쓸 수 있는 최대 값입니다. 비어 있을 경우, CPU 제한 재작성 기능이 비활성화됩니다. |
cpu_request |
빌드 컨테이너에 요청된 CPU입니다. |
cpu_request_overwrite_max_allowed |
빌드 컨테이너에 대한 CPU 요청을 쓸 수 있는 최대 값입니다. 비어 있을 경우, CPU 요청 재작성 기능이 비활성화됩니다. |
helper_cpu_limit |
빌드 도우미 컨테이너에 할당된 CPU입니다. |
helper_cpu_limit_overwrite_max_allowed |
도우미 컨테이너에 대한 CPU 할당을 쓸 수 있는 최대 값입니다. 비어 있을 경우, CPU 제한 재작성 기능이 비활성화됩니다. |
helper_cpu_request |
빌드 도우미 컨테이너에 요청된 CPU입니다. |
helper_cpu_request_overwrite_max_allowed |
도우미 컨테이너에 대한 CPU 요청을 쓸 수 있는 최대 값입니다. 비어 있을 경우, CPU 요청 재작성 기능이 비활성화됩니다. |
service_cpu_limit |
빌드 서비스 컨테이너에 할당된 CPU입니다. |
service_cpu_limit_overwrite_max_allowed |
서비스 컨테이너에 대한 CPU 할당을 쓸 수 있는 최대 값입니다. 비어 있을 경우, CPU 제한 재작성 기능이 비활성화됩니다. |
service_cpu_request |
빌드 서비스 컨테이너에 요청된 CPU입니다. |
service_cpu_request_overwrite_max_allowed |
서비스 컨테이너에 대한 CPU 요청을 쓸 수 있는 최대 값입니다. 비어 있을 경우, CPU 요청 재작성 기능이 비활성화됩니다. |
메모리 요청 및 제한
설정 | 설명 |
---|---|
memory_limit |
빌드 컨테이너에 할당된 메모리 양입니다. |
memory_limit_overwrite_max_allowed |
빌드 컨테이너에 대해 메모리 할당이 기록될 수 있는 최대 양입니다. 비어 있으면 메모리 제한 재작성 기능이 비활성화됩니다. |
memory_request |
빌드 컨테이너에서 요청된 메모리 양입니다. |
memory_request_overwrite_max_allowed |
빌드 컨테이너에 대해 메모리 할당 요청이 기록될 수 있는 최대 양입니다. 비어 있으면 메모리 요청 재작성 기능이 비활성화됩니다. |
helper_memory_limit |
빌드 헬퍼 컨테이너에 할당된 메모리 양입니다. |
helper_memory_limit_overwrite_max_allowed |
헬퍼 컨테이너에 대해 메모리 할당이 기록될 수 있는 최대 양입니다. 비어 있으면 메모리 제한 재작성 기능이 비활성화됩니다. |
helper_memory_request |
빌드 헬퍼 컨테이너에 요청된 메모리 양입니다. |
helper_memory_request_overwrite_max_allowed |
헬퍼 컨테이너에 대해 메모리 할당 요청이 기록될 수 있는 최대 양입니다. 비어 있으면 메모리 요청 재작성 기능이 비활성화됩니다. |
service_memory_limit |
빌드 서비스 컨테이너에 할당된 메모리 양입니다. |
service_memory_limit_overwrite_max_allowed |
서비스 컨테이너에 대해 메모리 할당이 기록될 수 있는 최대 양입니다. 비어 있으면 메모리 제한 재작성 기능이 비활성화됩니다. |
service_memory_request |
빌드 서비스 컨테이너에 요청된 메모리 양입니다. |
service_memory_request_overwrite_max_allowed |
서비스 컨테이너에 대해 메모리 할당 요청이 기록될 수 있는 최대 양입니다. 비어 있으면 메모리 요청 재작성 기능이 비활성화됩니다. |
저장소 요청 및 제한
설정 | 설명 |
---|---|
ephemeral_storage_limit |
빌드 컨테이너에 대한 임시 저장소 제한입니다. |
ephemeral_storage_limit_overwrite_max_allowed |
빌드 컨테이너에 대한 임시 저장소 제한이 재작성될 수 있는 최대 양입니다. 비어 있으면 임시 저장소 제한 재작성 기능이 비활성화됩니다. |
ephemeral_storage_request |
빌드 컨테이너에 제공된 임시 저장소 요청입니다. |
ephemeral_storage_request_overwrite_max_allowed |
빌드 컨테이너에 대해 임시 저장소 요청이 재작성될 수 있는 최대 양입니다. 비어 있으면 임시 저장소 요청 재작성 기능이 비활성화됩니다. |
helper_ephemeral_storage_limit |
헬퍼 컨테이너에 주어진 임시 저장소 제한입니다. |
helper_ephemeral_storage_limit_overwrite_max_allowed |
헬퍼 컨테이너에 대해 임시 저장소 제한이 재작성될 수 있는 최대 양입니다. 비어 있으면 임시 저장소 요청 재작성 기능이 비활성화됩니다. |
helper_ephemeral_storage_request |
헬퍼 컨테이너에 주어진 임시 저장소 요청입니다. |
helper_ephemeral_storage_request_overwrite_max_allowed |
헬퍼 컨테이너에 대해 임시 저장소 요청이 재작성될 수 있는 최대 양입니다. 비어 있으면 임시 저장소 요청 재작성 기능이 비활성화됩니다. |
service_ephemeral_storage_limit |
서비스 컨테이너에 주어진 임시 저장소 제한입니다. |
service_ephemeral_storage_limit_overwrite_max_allowed |
서비스 컨테이너에 대해 임시 저장소 제한이 재작성될 수 있는 최대 양입니다. 비어 있으면 임시 저장소 요청 재작성 기능이 비활성화됩니다. |
service_ephemeral_storage_request |
서비스 컨테이너에 주어진 임시 저장소 요청입니다. |
service_ephemeral_storage_request_overwrite_max_allowed |
서비스 컨테이너에 대해 임시 저장소 요청이 재작성될 수 있는 최대 양입니다. 비어 있으면 임시 저장소 요청 재작성 기능이 비활성화됩니다. |
기타 config.toml
설정
| 설정 | 설명 |
|———|————-|
| affinity
| 빌드를 실행할 노드를 결정하는 affinity 규칙을 지정합니다. affinity 사용에 대해 더 알아보기를 읽어보세요. |
| allow_privilege_escalation
| allowPrivilegeEscalation
플래그가 활성화된 모든 컨테이너를 실행합니다. 비어 있을 경우, 컨테이너의 SecurityContext
에서 allowPrivilegeEscalation
플래그를 정의하지 않으며, 기본 privilege escalation 동작을 사용하도록 Kubernetes가 허용됩니다. |
| allowed_images
| .gitlab-ci.yml
에서 지정할 수 있는 이미지의 와일드카드 목록입니다. 없으면 모든 이미지가 허용됩니다(동일한 의미: ["*/*:*"]
). 자세히 보기. |
| allowed_pull_policies
| .gitlab-ci.yml
파일 또는 config.toml
파일에서 지정할 수 있는 풀 정책 목록입니다. |
| allowed_services
| .gitlab-ci.yml
에서 지정할 수 있는 서비스의 와일드카드 목록입니다. 없으면 모든 이미지가 허용됩니다(동일한 의미: ["*/*:*"]
). 자세히 보기. |
| automount_service_account_token
| 빌드 포드에서 서비스 계정 토큰의 자동 정산을 제어하는 부울 값입니다. |
| bearer_token
| 빌드 포드를 시작하는 데 사용되는 기본 베어러 토큰입니다. |
| bearer_token_overwrite_allowed
| 프로젝트가 빌드 포드를 만들 때 사용될 베어러 토큰을 지정할 수 있도록 허용하는 부울 값입니다. |
| build_container_security_context
| 빌드 컨테이너에 대한 보안 컨텍스트를 설정합니다. 보안 컨텍스트에 대해 더 알아보기. |
| cap_add
| 작업 포드 컨테이너에 추가해야 하는 Linux 기능을 지정합니다. Kubernetes executor에서 기능 구성에 대해 더 알아보기. |
| cap_drop
| 작업 포드 컨테이너에서 삭제해야 하는 Linux 기능을 지정합니다. Kubernetes executor에서 기능 구성에 대해 더 알아보기. |
| cleanup_grace_period_seconds
| 작업이 완료되면, 포드가 정상적으로 종료하는 데 필요한 시간(초)입니다. 이 기간이 지나면 프로세스가 종료 신호로 강제로 중단됩니다. terminationGracePeriodSeconds
가 지정될 경우 무시됩니다. |
| dns_policy
| 포드를 구성할 때 사용해야 하는 DNS 정책을 지정합니다: none
, default
, cluster-first
, cluster-first-with-host-net
. 설정하지 않으면 Kubernetes 기본값(cluster-first
)이 사용됩니다. |
| dns_config
| 포드를 구성할 때 사용해야 하는 DNS 구성을 지정합니다. 포드의 DNS 구성 사용에 대해 더 알아보기. |
| helper_container_security_context
| 헬퍼 컨테이너에 대한 보안 컨텍스트를 설정합니다. 보안 컨텍스트에 대해 더 알아보기. |
| helper_image
| (고급) 레포를 복제하고 아티팩트를 업로드하는 데 사용되는 기본 헬퍼 이미지를 재정의합니다. |
| helper_image_flavor
| 헬퍼 이미지 맛을 설정합니다(alpine
, alpine3.16
, alpine3.17
, alpine3.18
, alpine3.19
또는 ubuntu
). 기본값은 alpine
입니다. alpine
을 사용하는 것은 alpine3.18
과 동일합니다. |
| host_aliases
| 모든 컨테이너에 추가해줄 호스트 이름 별칭 목록입니다. 추가 호스트 별칭 사용에 대해 더 알아보기. |
| image_pull_secrets
| 개인 레지스트리에서 Docker 이미지를 인증하기 위해 사용되는 Kubernetes docker-registry
비밀 이름의 항목 배열입니다. |
| init_permissions_container_security_context
| init-permissions 컨테이너에 대한 보안 컨텍스트를 설정합니다. 보안 컨텍스트에 대해 더 알아보기. |
| namespace
| Kubernetes Pods를 실행할 네임스페이스입니다. |
| namespace_per_job
| 작업을 별도의 네임스페이스로 격리합니다. 활성화되면 namespace
및 namespace_overwrite_allowed
는 무시됩니다. |
| namespace_overwrite_allowed
| 네임스페이스 덮어쓰기 환경 변수의 내용 검증을 위한 정규 표현식입니다(아래 문서화됨). 비어 있으면 네임스페이스 덮어쓰기 기능이 비활성화됩니다. |
| node_selector
| key=value
쌍을 string=string
형식으로 나타내는 table
입니다(환경 변수가 있는 경우에는
string:string). 이는 Kubernetes 노드에서 모든
key=value 쌍과 일치하는 포드 생성을 제한합니다. [노드 선택자 사용에 대해 더 알아보기](#specify-the-node-to-execute-builds). |
|
node_tolerations |
“key=value” = “Effect” 쌍의
table입니다. 이는
string=string:string 형식으로 설정되며, 이는 포드가 모두 또는 부분적인 허용된 오염 물질이 있는 노드에서 예약될 수 있도록 허용합니다. 환경 변수 구성에서 하나의 허용만 제공될 수 있습니다.
key,
value, 및
effect는 Kubernetes 포드 허용 구성에서 해당 필드 이름과 일치합니다. |
|
pod_annotations |
key=value 쌍의
table입니다. 이는 러너가 생성한 각 빌드 포드에 추가할 주석 목록입니다. 이들의 값은 변수 확장을 포함할 수 있습니다. 포드 주석은 각 빌드에서 덮어쓸 수 있습니다. |
|
pod_annotations_overwrite_allowed | 포드 주석 덮어쓰기 환경 변수의 내용 검증을 위한 정규 표현식입니다. 비어 있으면 포드 주석 덮어쓰기 기능이 비활성화됩니다. |
|
pod_labels |
key=value 쌍의
table입니다. 이는 러너가 생성한 각 빌드 포드에 추가할 레이블 목록입니다. 이들의 값은 변수 확장을 포함할 수 있습니다. 포드 레이블은
pod_labels_overwrite_allowed를 사용하여 각 빌드에서 덮어쓸 수 있습니다. |
|
pod_labels_overwrite_allowed | 포드 레이블 덮어쓰기 환경 변수의 내용 검증을 위한 정규 표현식입니다. 비어 있으면 포드 레이블 덮어쓰기 기능이 비활성화됩니다. |
|
pod_security_context | 구성 파일을 통해 구성이 이루어지며, 이 설정은 빌드 포드에 대한 보안 컨텍스트를 설정합니다. [보안 컨텍스트에 대해 더 알아보기](#set-a-security-policy-for-the-pod). |
|
pod_termination_grace_period_seconds | 포드 수준 설정으로, 포드가 정상적으로 종료되는 데 필요한 시간(초)을 결정합니다. 그 후, 프로세스가 강제로 종료 신호로 종료됩니다.
terminationGracePeriodSeconds가 지정될 경우 무시됩니다. |
|
poll_interval | 러너가 방금 생성한 Kubernetes 포드의 상태를 확인하기 위해 폴링하는 빈도(초)입니다(기본값 = 3). |
|
poll_timeout | 러너가 방금 생성한 컨테이너에 연결 시도를 시간 초과하기까지 경과해야 하는 시간(초)입니다. 클러스터가 한 번에 처리할 수 있는 빌드를 큐에 추가하는 데 유용합니다(기본값 = 180). |
|
cleanup_resources_timeout | 작업이 완료된 후 Kubernetes 리소스가 정리되는 데 걸리는 총 시간입니다. 지원되는 문법:
1h30m,
300s,
10m. 기본값은 5분(
5m)입니다. |
|
priority_class_name | 포드에 설정할 우선 순위 클래스를 지정합니다. 설정하지 않으면 기본값이 사용됩니다. |
|
privileged | 특권 플래그가 있는 컨테이너를 실행합니다. |
|
pull_policy | 이미지 풀 정책을 지정합니다:
never,
if-not-present,
always. 설정하지 않으면 클러스터의 이미지 [기본 풀 정책](https://kubernetes.io/docs/concepts/containers/images/#updating-images)이 사용됩니다. 여러 풀 정책 설정에 대한 더 많은 정보 및 지침은 [풀 정책 사용](#set-a-pull-policy)을 참조하십시오. 또한 [
if-not-present,
never 보안 고려사항](../../security/index.md#usage-of-private-docker-images-with-if-not-present-pull-policy)을 참조하세요. [풀 정책 제한](#restrict-docker-pull-policies)도 가능합니다. |
|
resource_availability_check_max_attempts | 사용할 수 있는 리소스(서비스 계정 및/또는 풀 비밀)가 있는지 확인하기 위한 최대 시도 횟수입니다. 각 시도 사이에는 5초 간격이 있습니다. [Introduced](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/27664) in GitLab 15.0. [준비 단계에서 리소스 확인에 대해 더 알아보기](#resources-check-during-prepare-step). |
|
runtime_class_name | 생성된 모든 포드에 사용할 런타임 클래스를 지정합니다. 클러스터에서 기능이 지원되지 않으면 작업이 종료되거나 실패합니다. |
|
service_container_security_context | 서비스 컨테이너에 대한 보안 컨텍스트를 설정합니다. [보안 컨텍스트에 대해 더 알아보기](#set-a-security-policy-for-the-pod). |
|
scheduler_name | 빌드 포드를 예약하는 데 사용할 스케줄러입니다. |
|
service_account | 기본 서비스 계정 작업/실행자가 Kubernetes API와 통신하는 데 사용됩니다. |
|
service_account_overwrite_allowed | 서비스 계정 덮어쓰기 환경 변수의 내용 검증을 위한 정규 표현식입니다. 비어 있으면 서비스 계정 덮어쓰기 기능이 비활성화됩니다. |
|
services | [sidecar 패턴](https://learn.microsoft.com/en-us/azure/architecture/patterns/sidecar)을 사용하여 빌드 컨테이너에 연결된 [서비스](https://docs.gitlab.com/ee/ci/services/) 목록입니다. [서비스 사용에 대해 더 알아보기](#define-a-list-of-services). |
|
use_service_account_image_pull_secrets | 활성화되면 실행자가 생성한 포드에는
imagePullSecrets가 없습니다. 이는 설정된 경우 서비스 계정의 [
imagePullSecrets](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-image-pull-secret-to-service-account)를 사용하여 포드가 생성되도록 합니다. |
|
terminationGracePeriodSeconds | 포드 내에서 실행 중인 프로세스가 종료 신호를 받고 프로세스가 강제로 종료되는 시간입니다. [
cleanup_grace_period_seconds 및
pod_termination_grace_period_seconds에 대한 deprecation](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/28165). |
|
volumes | 구성 파일을 통해 구성되며, 빌드 컨테이너에 마운트된 볼륨 목록입니다. [볼륨 사용에 대해 더 알아보기](#configure-volume-types). |
|
pod_spec | 이 설정은 실험입니다. CI 작업을 실행하는 데 사용되는 포드에 설정된 구성 목록으로 러너 관리자가 생성한 포드 사양을 재정의합니다.
Kubernetes Pod Specification에 나열된 모든 속성을 설정할 수 있습니다. [생성된 포드 사양을 재정의하기](#overwrite-generated-pod-specifications) 관련 정보를 확인하세요. |
|
retry_limit | Kubernetes API와 통신하기 위한 최대 시도 횟수입니다. 각 시도 간의 재시도 간격은 500ms에서 시작하는 백오프 알고리즘에 따라 결정됩니다. |
|
retry_backoff_max | 각 시도에 대한 재시도 간격의 사용자 지정 최대 백오프 값(밀리초)입니다. 기본값은 2000ms이며, 500ms보다 낮을 수 없습니다. 각 시도에 도달하는 최대 재시도 간격의 기본값은 2초이며,
retry_backoff_max로 사용자 지정할 수 있습니다. |
|
retry_limits | 각 요청 오류를 얼마나 많은 횟수로 재시도할 것인지입니다. |
|
logs_base_dir | 생성된 경로에 추가되어 빌드 로그를 저장하는 기본 디렉토리입니다. 빌드 로그 및 스크립트의 기본 디렉토리 변경에 대한 추가 정보는 [Change the base directory for build logs and scripts](#change-the-base-directory-for-build-logs-and-scripts)를 참조하세요. |
|
scripts_base_dir` | 생성된 경로에 추가되어 빌드 스크립트를 저장하는 기본 디렉토리입니다. 빌드 로그 및 스크립트의 기본 디렉토리 변경에 대한 추가 정보는 Change the base directory for build logs and scripts를 참조하세요. |
구성 예시
다음 샘플은 Kubernetes 실행기용 config.toml
파일의 구성 예시를 보여줍니다.
concurrent = 4
[[runners]]
name = "myRunner"
url = "https://gitlab.com/ci"
token = "......"
executor = "kubernetes"
[runners.kubernetes]
host = "https://45.67.34.123:4892"
cert_file = "/etc/ssl/kubernetes/api.crt"
key_file = "/etc/ssl/kubernetes/api.key"
ca_file = "/etc/ssl/kubernetes/ca.crt"
namespace = "gitlab"
namespace_overwrite_allowed = "ci-.*"
bearer_token_overwrite_allowed = true
privileged = true
cpu_limit = "1"
memory_limit = "1Gi"
service_cpu_limit = "1"
service_memory_limit = "1Gi"
helper_cpu_limit = "500m"
helper_memory_limit = "100Mi"
poll_interval = 5
poll_timeout = 3600
dns_policy = "cluster-first"
priority_class_name = "priority-1"
logs_base_dir = "/tmp"
scripts_base_dir = "/tmp"
[runners.kubernetes.node_selector]
gitlab = "true"
[runners.kubernetes.node_tolerations]
"node-role.kubernetes.io/master" = "NoSchedule"
"custom.toleration=value" = "NoSchedule"
"empty.value=" = "PreferNoSchedule"
"onlyKey" = ""
실행기 서비스 계정 구성
실행기 서비스 계정을 구성하려면 KUBERNETES_SERVICE_ACCOUNT
환경 변수를 설정하거나 --kubernetes-service-account
플래그를 사용할 수 있습니다.
포드 및 컨테이너
작업 실행 방식을 제어하기 위해 포드 및 컨테이너를 구성할 수 있습니다.
작업 포드에 대한 기본 주석
작업을 실행하는 포드에 대해 기본적으로 추가되는 주석은 다음과 같습니다:
키 | 설명 |
---|---|
job.runner.gitlab.com/id |
GitLab 인스턴스 내의 모든 작업에서 고유한 작업 ID. |
job.runner.gitlab.com/url |
작업 세부정보의 URL. |
job.runner.gitlab.com/sha |
프로젝트가 빌드된 커밋 리비전. |
job.runner.gitlab.com/before_sha |
브랜치 또는 태그에 존재하는 이전 최신 커밋. |
job.runner.gitlab.com/ref |
프로젝트가 빌드된 브랜치 또는 태그 이름. |
job.runner.gitlab.com/name |
작업의 이름. |
project.runner.gitlab.com/id |
작업의 프로젝트 ID. |
기본 주석을 덮어쓰려면 GitLab Runner 구성에서 pod_annotations
를 사용하세요.
각 CI/CD 작업의 주석을 덮어쓸 수도 있습니다 .gitlab-ci.yml
파일에서.
포드 생명주기
포드의 생명주기는 다음에 영향을 받을 수 있습니다:
-
TOML
구성 파일에서pod_termination_grace_period_seconds
속성을 설정합니다. 포드에서 실행 중인 프로세스는TERM
신호가 전송된 후 주어진 시간 동안 실행될 수 있습니다. 이 마감 시간 이후에 포드가 성공적으로 종료되지 않으면 킬 신호가 전송됩니다. -
FF_USE_POD_ACTIVE_DEADLINE_SECONDS
기능 플래그를 사용합니다. 사용 시 작업이 제한시간 초과되면 CI/CD 작업을 실행 중인 포드가 실패로 표시되고 모든 관련 컨테이너가 종료됩니다. GitLab에서 작업이 먼저 제한시간 초과되도록 하려면,activeDeadlineSeconds
가configured timeout + 1 second
로 설정됩니다.
주의 사항:
FF_USE_POD_ACTIVE_DEADLINE_SECONDS
기능 플래그가 활성화되고 pod_termination_grace_period_seconds
가 0이 아닌 값으로 설정된 경우,
CI 작업 포드는 작업이 제한시간 초과된 경우 즉시 종료되지 않습니다. 포드 terminationGracePeriods
는 포드가 만료되었을 때만 종료됩니다.
파드 내구성 재정의
Kubernetes 파드 내구성을 재정의하려면:
-
config.toml
또는 Helmvalues.yaml
파일에서 CI 작업 파드 내구성의 재정의를 활성화하려면node_tolerations_overwrite_allowed
에 대한 정규 표현식을 정의합니다.
이 정규 표현식은KUBERNETES_NODE_TOLERATIONS_
로 시작하는 CI 변수 이름의 값을 검증합니다.runners: ... config: | [[runners]] [runners.kubernetes] node_tolerations_overwrite_allowed = ".*"
-
.gitlab-ci.yml
파일에서 CI 작업 파드 내구성을 재정의하기 위해 하나 이상의 CI 변수를 정의합니다.variables: KUBERNETES_NODE_TOLERATIONS_1: 'node-role.kubernetes.io/master:NoSchedule' KUBERNETES_NODE_TOLERATIONS_2: 'custom.toleration=value:NoSchedule' KUBERNETES_NODE_TOLERATIONS_3: 'empty.value=:PreferNoSchedule' KUBERNETES_NODE_TOLERATIONS_4: 'onlyKey' KUBERNETES_NODE_TOLERATIONS_5: '' # 모든 얼룩을 허용
파드 레이블 재정의
각 CI/CD 작업에 대한 Kubernetes 파드 레이블을 재정의하려면:
-
.config.yaml
파일에서pod_labels_overwrite_allowed
에 대한 정규 표현식을 정의합니다. -
.gitlab-ci.yml
파일에서KUBERNETES_POD_LABELS_*
변수를key=value
값으로 설정합니다. 파드 레이블은key=value
로 재정의됩니다. 여러 값을 적용할 수 있습니다:variables: KUBERNETES_POD_LABELS_1: "Key1=Val1" KUBERNETES_POD_LABELS_2: "Key2=Val2" KUBERNETES_POD_LABELS_3: "Key3=Val3"
파드 주석 재정의
각 CI/CD 작업에 대한 Kubernetes 파드 주석을 재정의하려면:
-
.config.yaml
파일에서pod_annotations_overwrite_allowed
에 대한 정규 표현식을 정의합니다. -
.gitlab-ci.yml
파일에서KUBERNETES_POD_ANNOTATIONS_*
변수를 설정하고key=value
를 값으로 사용합니다.
파드 주석은key=value
로 재정의됩니다. 여러 주석을 지정할 수 있습니다:variables: KUBERNETES_POD_ANNOTATIONS_1: "Key1=Val1" KUBERNETES_POD_ANNOTATIONS_2: "Key2=Val2" KUBERNETES_POD_ANNOTATIONS_3: "Key3=Val3"
아래 예에서는 pod_annotations
및 pod_annotations_overwrite_allowed
가 설정되어 있습니다.
이 구성은 config.toml
에서 구성된 모든 pod_annotations
를 재정의할 수 있습니다.
[[runners]]
# 일반 구성
executor = "kubernetes"
[runners.kubernetes]
image = "alpine"
pod_annotations_overwrite_allowed = ".*"
[runners.kubernetes.pod_annotations]
"Key1" = "Val1"
"Key2" = "Val2"
"Key3" = "Val3"
"Key4" = "Val4"
생성된 팟 사양 덮어쓰기
- Introduced in GitLab Runner 15.10.
이 기능은 베타 상태입니다. 우리는 이 기능을 프로덕션 클러스터에서 사용하기 전에 테스트 Kubernetes 클러스터에서 사용하기를 강력히 권장합니다. 이 기능을 사용하려면 FF_USE_ADVANCED_POD_SPEC_CONFIGURATION
기능 플래그를 활성화해야 합니다.
일반적으로 사용 가능해지기 전에 개선사항에 대한 피드백을 추가하려면 이 문제를 사용하세요.
러너 관리자가 생성한 PodSpec
를 수정하려면 config.toml
파일의 pod_spec
설정을 사용하십시오.
pod_spec
설정:
-
생성된 팟 사양의 필드를 덮어쓰고 완성합니다.
-
[runners.kubernetes]
아래의config.toml
에서 설정될 수 있는 구성 값을 덮어씁니다.
여러 pod_spec
설정을 구성할 수 있습니다.
설정 | 설명 |
---|---|
name |
사용자 정의 pod_spec 에 주어진 이름. |
patch_path |
최종 PodSpec 객체에 적용할 변경 사항을 정의하는 파일의 경로입니다. 파일은 JSON 또는 YAML 파일이어야 합니다. |
patch |
최종 PodSpec 객체에 적용해야 할 변경 사항을 설명하는 JSON 또는 YAML 형식의 문자열입니다. |
patch_type |
러너가 GitLab Runner에 의해 생성된 PodSpec 객체에 지정된 변경 사항을 적용하는 전략입니다. 허용된 값은 merge , json , 및 strategic 입니다. |
동일한 pod_spec
구성에 patch_path
와 patch
를 설정할 수 없으며, 그렇지 않으면 오류가 발생합니다.
config.toml
에서 여러 pod_spec
구성의 예:
[[runners]]
[runners.kubernetes]
[[runners.kubernetes.pod_spec]]
name = "hostname"
patch = '''
hostname: "custom-pod-hostname"
'''
patch_type = "merge"
[[runners.kubernetes.pod_spec]]
name = "subdomain"
patch = '''
subdomain: "subdomain"
'''
patch_type = "strategic"
[[runners.kubernetes.pod_spec]]
name = "terminationGracePeriodSeconds"
patch = '''
[{"op": "replace", "path": "/terminationGracePeriodSeconds", "value": 60}]
'''
patch_type = "json"
병합 패치 전략
merge
패치 전략은 기존의 PodSpec
에 키-값 교체를 적용합니다.
이 전략을 사용하는 경우, config.toml
의 pod_spec
구성은 생성되기 전에 최종 PodSpec
객체의 값을 덮어씁니다. 값이 완전히 덮어쓰기 때문에 이 패치 전략을 사용할 때는 주의해야 합니다.
merge
패치 전략을 가진 pod_spec
구성의 예:
concurrent = 1
check_interval = 1
log_level = "debug"
shutdown_timeout = 0
[session_server]
session_timeout = 1800
[[runners]]
name = ""
url = "https://gitlab.example.com"
id = 0
token = "__REDACTED__"
token_obtained_at = 0001-01-01T00:00:00Z
token_expires_at = 0001-01-01T00:00:00Z
executor = "kubernetes"
shell = "bash"
environment = ["FF_USE_ADVANCED_POD_SPEC_CONFIGURATION=true", "CUSTOM_VAR=value"]
[runners.kubernetes]
image = "alpine"
...
[[runners.kubernetes.pod_spec]]
name = "build envvars"
patch = '''
containers:
- env:
- name: env1
value: "value1"
- name: env2
value: "value2"
name: build
'''
patch_type = "merge"
이 구성으로 인해 최종 PodSpec
는 build
라는 이름의 단일 컨테이너와 두 개의 환경 변수 env1
및 env2
만을 포함하게 됩니다. 위의 예는 관련 CI 작업이 실패하게 만들 수 있습니다:
-
helper
컨테이너 사양이 제거됩니다. -
build
컨테이너 사양이 GitLab Runner에 의해 설정된 모든 필수 구성을 잃습니다.
작업 실패를 방지하기 위해 이 예에서는 pod_spec
에 GitLab Runner에 의해 생성된 보존된 속성이 포함되어야 합니다.
JSON 패치 전략
json
패치 전략은 JSON Patch 사양을 사용하여 업데이트할 PodSpec
객체와 배열에 대한 제어를 제공합니다. 이 전략은 array
속성에서는 사용할 수 없습니다.
다음은 json
패치 전략을 사용한 pod_spec
구성의 예입니다. 이 구성에서는 기존의 nodeSelector
에 새로운 key: value pair
가 추가됩니다. 기존 값은 덮어쓰지 않습니다.
concurrent = 1
check_interval = 1
log_level = "debug"
shutdown_timeout = 0
[session_server]
session_timeout = 1800
[[runners]]
name = ""
url = "https://gitlab.example.com"
id = 0
token = "__REDACTED__"
token_obtained_at = 0001-01-01T00:00:00Z
token_expires_at = 0001-01-01T00:00:00Z
executor = "kubernetes"
shell = "bash"
environment = ["FF_USE_ADVANCED_POD_SPEC_CONFIGURATION=true", "CUSTOM_VAR=value"]
[runners.kubernetes]
image = "alpine"
...
[[runners.kubernetes.pod_spec]]
name = "val1 node"
patch = '''
{ "op": "add", "path": "/nodeSelector", "value": { key1: "val1" } }
'''
patch_type = "json"
전략적 패치 전략
이 strategic
패치 전략은 PodSpec
객체의 각 필드에 적용된 기존 patchStrategy
를 사용합니다.
다음은 strategic
패치 전략을 사용한 pod_spec
구성의 예입니다. 이 구성에서는 빌드 컨테이너에 resource request
가 설정됩니다.
concurrent = 1
check_interval = 1
log_level = "debug"
shutdown_timeout = 0
[session_server]
session_timeout = 1800
[[runners]]
name = ""
url = "https://gitlab.example.com"
id = 0
token = "__REDACTED__"
token_obtained_at = 0001-01-01T00:00:00Z
token_expires_at = 0001-01-01T00:00:00Z
executor = "kubernetes"
shell = "bash"
environment = ["FF_USE_ADVANCED_POD_SPEC_CONFIGURATION=true", "CUSTOM_VAR=value"]
[runners.kubernetes]
image = "alpine"
...
[[runners.kubernetes.pod_spec]]
name = "cpu request 500m"
patch = '''
containers:
- name: build
resources:
requests:
cpu: "500m"
'''
patch_type = "strategic"
이 구성에서는 빌드 컨테이너에 resource request
가 설정됩니다.
모범 사례
-
배포 전에 테스트 환경에서 추가된
pod_spec
를 테스트하세요. -
pod_spec
구성이 GitLab Runner가 생성한 사양에 부정적인 영향을 미치지 않도록 하세요. -
복잡한 pod 사양 업데이트에 대해
merge
패치 전략을 사용하지 마세요. -
가능할 경우 구성 가능할 때
config.toml
을 사용하세요. 예를 들어, 다음 구성은 GitLab Runner가 설정한 첫 번째 환경 변수를 기존 목록에 추가하는 대신 사용자 정의pod_spec
에서 설정한 것으로 대체합니다.
concurrent = 1
check_interval = 1
log_level = "debug"
shutdown_timeout = 0
[session_server]
session_timeout = 1800
[[runners]]
name = ""
url = "https://gitlab.example.com"
id = 0
token = "__REDACTED__"
token_obtained_at = 0001-01-01T00:00:00Z
token_expires_at = 0001-01-01T00:00:00Z
executor = "kubernetes"
shell = "bash"
environment = ["FF_USE_ADVANCED_POD_SPEC_CONFIGURATION=true", "CUSTOM_VAR=value"]
[runners.kubernetes]
image = "alpine"
...
[[runners.kubernetes.pod_spec]]
name = "build envvars"
patch = '''
containers:
- env:
- name: env1
value: "value1"
name: build
'''
patch_type = "strategic"
각 빌드 작업을 위한 PVC 생성하기: Pod Spec 수정
각 빌드 작업을 위한 PersistentVolumeClaim을 생성하려면 Pod Spec 기능을 활성화하는 방법을 확인해야 합니다.
Kubernetes는 Pod의 생명 주기에 연결된 일회용 PersistentVolumeClaim을 생성할 수 있도록 허용합니다.
이것은 동적 프로비저닝이 Kubernetes 클러스터에서 활성화되면 작동하며, 각 PVC
가 새로운 Volume을 요청할 수 있게 해 주고, 이 볼륨 또한 Pod의 수명에 연결됩니다.
동적 프로비저닝이 활성화된 후, 다음과 같이 config.toml
을 수정하여 일회용 PVC
를 생성할 수 있습니다:
[[runners.kubernetes.pod_spec]]
name = "ephemeral-pvc"
patch = '''
containers:
- name: build
volumeMounts:
- name: builds
mountPath: /builds
- name: helper
volumeMounts:
- name: builds
mountPath: /builds
volumes:
- name: builds
ephemeral:
volumeClaimTemplate:
spec:
storageClassName: <동적 프로비저닝으로 볼륨을 생성할 스토리지 클래스>
accessModes: [ ReadWriteOnce ]
resources:
requests:
storage: 1Gi
'''
Pod의 보안 정책 설정하기
config.toml
에서 보안 컨텍스트를 구성하여 빌드 Pod의 보안 정책을 설정합니다.
다음 옵션을 사용하세요:
옵션 | 유형 | 필수 | 설명 |
---|---|---|---|
fs_group |
int |
아니요 | Pod의 모든 컨테이너에 적용되는 특수 보조 그룹입니다. |
run_as_group |
int |
아니요 | 컨테이너 프로세스의 진입점이 실행될 GID입니다. |
run_as_non_root |
boolean | 아니요 | 컨테이너가 비루트 사용자로 실행되어야 함을 나타냅니다. |
run_as_user |
int |
아니요 | 컨테이너 프로세스의 진입점이 실행될 UID입니다. |
supplemental_groups |
int 목록 |
아니요 | 각 컨테이너에서 실행되는 첫 번째 프로세스에 적용되는 그룹 목록입니다. 주요 GID 외에 추가됩니다. |
selinux_type |
string |
아니요 | Pod의 모든 컨테이너에 적용되는 SELinux 유형 레이블입니다. |
config.toml
에서의 Pod 보안 컨텍스트 예제:
concurrent = %(concurrent)s
check_interval = 30
[[runners]]
name = "myRunner"
url = "gitlab.example.com"
executor = "kubernetes"
[runners.kubernetes]
helper_image = "gitlab-registry.example.com/helper:latest"
[runners.kubernetes.pod_security_context]
run_as_non_root = true
run_as_user = 59417
run_as_group = 59417
fs_group = 59417
오래된 러너 팟 제거
- GitLab Runner 14.6에서 소개됨.
가끔 오래된 러너 팟이 정리되지 않을 수 있습니다. 이는 러너 관리자가 잘못 종료되었을 때 발생할 수 있습니다.
이 상황을 처리하기 위해 GitLab Runner Pod Cleanup 애플리케이션을 사용하여 오래된 팟의 정리를 예약할 수 있습니다. 더 많은 정보는 다음을 참조하세요:
컨테이너에 대한 보안 정책 설정
- GitLab Runner 14.5에서 소개됨.
config.toml
실행기에서 컨테이너 보안 컨텍스트를 구성하여 빌드, 헬퍼 또는 서비스 팟에 대한 컨테이너 보안 정책을 설정합니다.
다음 옵션을 사용하세요:
옵션 | 유형 | 필수 | 설명 |
---|---|---|---|
run_as_group |
int | 아니오 | 컨테이너 프로세스의 진입점을 실행할 GID입니다. |
run_as_non_root |
boolean | 아니오 | 컨테이너가 비루트 사용자로 실행되어야 함을 나타냅니다. |
run_as_user |
int | 아니오 | 컨테이너 프로세스의 진입점을 실행할 UID입니다. |
capabilities.add |
string list | 아니오 | 컨테이너 실행 시 추가할 기능입니다. |
capabilities.drop |
string list | 아니오 | 컨테이너 실행 시 삭제할 기능입니다. |
selinux_type |
string | 아니오 | 컨테이너 프로세스와 연결된 SELinux 유형 레이블입니다. |
다음 예제는 config.toml
의 보안 컨텍스트 구성입니다:
- 팟 보안 컨텍스트를 설정합니다.
- 빌드 및 헬퍼 컨테이너에 대한
run_as_user
및run_as_group
을 재정의합니다. - 모든 서비스 컨테이너가 팟 보안 컨텍스트에서
run_as_user
및run_as_group
를 상속받도록 지정합니다.
concurrent = 4
check_interval = 30
[[runners]]
name = "myRunner"
url = "gitlab.example.com"
executor = "kubernetes"
[runners.kubernetes]
helper_image = "gitlab-registry.example.com/helper:latest"
[runners.kubernetes.pod_security_context]
run_as_non_root = true
run_as_user = 59417
run_as_group = 59417
fs_group = 59417
[runners.kubernetes.init_permissions_container_security_context]
run_as_user = 1000
run_as_group = 1000
[runners.kubernetes.build_container_security_context]
run_as_user = 65534
run_as_group = 65534
[runners.kubernetes.build_container_security_context.capabilities]
add = ["NET_ADMIN"]
[runners.kubernetes.helper_container_security_context]
run_as_user = 1000
run_as_group = 1000
[runners.kubernetes.service_container_security_context]
run_as_user = 1000
run_as_group = 1000
풀 정책 설정
config.toml
파일에서 pull_policy
매개변수를 사용하여 단일 또는 다중 풀 정책을 지정합니다.
정책은 이미지가 어떻게 가져오고 업데이트되는지를 제어하며, 빌드 이미지, 헬퍼 이미지 및 모든 서비스에 적용됩니다.
어떤 정책을 사용할지 결정하려면 풀 정책에 대한 Kubernetes 문서를 참조하세요.
단일 풀 정책의 경우:
[runners.kubernetes]
pull_policy = "never"
다중 풀 정책의 경우:
[runners.kubernetes]
# 다중 풀 정책 사용
pull_policy = ["always", "if-not-present"]
여러 정책을 정의할 경우, 이미지를 성공적으로 가져올 때까지 각 정책이 시도됩니다.
예를 들어, [ always, if-not-present ]
를 사용하면 if-not-present
정책은 always
정책이 임시 레지스트리 문제로 실패할 경우 사용됩니다.
실패한 풀을 재시도하려면:
[runners.kubernetes]
pull_policy = ["always", "always"]
GitLab 명명 규칙은 Kubernetes 것과 다릅니다.
러너 풀 정책 | Kubernetes 풀 정책 | 설명 |
---|---|---|
blank | blank | Kubernetes에서 지정한 기본 정책을 사용합니다. |
if-not-present |
IfNotPresent |
이미 노드에 존재하지 않는 경우에만 이미지를 가져옵니다. 보안 고려 사항이 있습니다. |
always |
Always |
작업이 실행될 때마다 이미지를 가져옵니다. |
never |
Never |
이미지를 절대 가져오지 않으며, 노드에 이미 존재해야 합니다. |
컨테이너 기능 지정
컨테이너에서 사용할 Kubernetes 기능을 지정할 수 있습니다.
컨테이너 기능을 지정하려면 config.toml
파일의 cap_add
및 cap_drop
옵션을 사용하세요. 컨테이너 런타임은 Docker와 container와 같은 기본 기능 목록을 정의할 수도 있습니다.
런너가 기본적으로 제거하는 기능의 목록이 있습니다.
cap_add
옵션에 나열한 기능은 제거 목록에서 제외됩니다.
config.toml
파일의 예시 구성:
concurrent = 1
check_interval = 30
[[runners]]
name = "myRunner"
url = "gitlab.example.com"
executor = "kubernetes"
[runners.kubernetes]
# ...
cap_add = ["SYS_TIME", "IPC_LOCK"]
cap_drop = ["SYS_ADMIN"]
# ...
기능을 지정할 때:
- 사용자 정의
cap_drop
이 사용자 정의cap_add
보다 우선합니다. 두 설정 모두에서 동일한 기능을 정의하는 경우,cap_drop
에서 정의된 기능만 컨테이너에 전달됩니다. - 컨테이너 구성에 전달되는 기능 식별자에서
CAP_
접두사를 제거하세요. 예를 들어,CAP_SYS_TIME
기능을 추가하거나 제거하려면, 구성 파일에 문자열SYS_TIME
을 입력합니다. - Kubernetes 클러스터의 소유자는 PodSecurityPolicy를 정의할 수 있습니다, 여기에서 특정 기능이 허용되거나 제한되거나 기본적으로 추가됩니다. 이러한 규칙은 사용자 정의 구성보다 우선합니다.
컨테이너 리소스 덮어쓰기
각 CI/CD 작업에 대한 Kubernetes CPU 및 메모리 할당을 덮어쓸 수 있습니다. 빌드 컨테이너, 헬퍼 컨테이너 및 서비스 컨테이너에 대한 요청과 제한에 대한 설정을 적용할 수 있습니다.
컨테이너 리소스를 덮어쓰려면 .gitlab-ci.yml
파일에서 다음 변수를 사용하세요.
변수의 값은 해당 리소스에 대한 최대 덮어쓰기 설정으로 제한됩니다. 리소스에 대한 최대 덮어쓰기가 설정되지 않은 경우, 변수는 사용되지 않습니다.
variables:
KUBERNETES_CPU_REQUEST: "3"
KUBERNETES_CPU_LIMIT: "5"
KUBERNETES_MEMORY_REQUEST: "2Gi"
KUBERNETES_MEMORY_LIMIT: "4Gi"
KUBERNETES_EPHEMERAL_STORAGE_REQUEST: "512Mi"
KUBERNETES_EPHEMERAL_STORAGE_LIMIT: "1Gi"
KUBERNETES_HELPER_CPU_REQUEST: "3"
KUBERNETES_HELPER_CPU_LIMIT: "5"
KUBERNETES_HELPER_MEMORY_REQUEST: "2Gi"
KUBERNETES_HELPER_MEMORY_LIMIT: "4Gi"
KUBERNETES_HELPER_EPHEMERAL_STORAGE_REQUEST: "512Mi"
KUBERNETES_HELPER_EPHEMERAL_STORAGE_LIMIT: "1Gi"
KUBERNETES_SERVICE_CPU_REQUEST: "3"
KUBERNETES_SERVICE_CPU_LIMIT: "5"
KUBERNETES_SERVICE_MEMORY_REQUEST: "2Gi"
KUBERNETES_SERVICE_MEMORY_LIMIT: "4Gi"
KUBERNETES_SERVICE_EPHEMERAL_STORAGE_REQUEST: "512Mi"
KUBERNETES_SERVICE_EPHEMERAL_STORAGE_LIMIT: "1Gi"
서비스 목록 정의
- GitLab Runner 16.9에서
HEALTCHECK_TCP_SERVICES
에 대한 지원이 도입되었습니다. 링크
config.toml
파일에서 서비스 목록을 정의합니다.
concurrent = 1
check_interval = 30
[[runners]]
name = "myRunner"
url = "gitlab.example.com"
executor = "kubernetes"
[runners.kubernetes]
helper_image = "gitlab-registy.example.com/helper:latest"
[[runners.kubernetes.services]]
name = "postgres:12-alpine"
alias = "db1"
[[runners.kubernetes.services]]
name = "registry.example.com/svc1"
alias = "svc1"
entrypoint = ["entrypoint.sh"]
command = ["executable","param1","param2"]
environment = ["ENV=value1", "ENV2=value2"]
서비스 환경에 HEALTHCHECK_TCP_PORT
가 포함되어 있으면, GitLab Runner는 사용자 CI 스크립트를 시작하기 전에 해당 포트에서 서비스가 응답할 때까지 기다립니다. .gitlab-ci.yml
의 services
섹션에서 HEALTHCHECK_TCP_PORT
환경 변수를 구성할 수도 있습니다.
서비스 컨테이너 리소스 덮어쓰기
작업에 여러 서비스 컨테이너가 있는 경우, 각 서비스 컨테이너에 명시적 리소스 요청 및 제한을 설정할 수 있습니다. 각 서비스에서 변수를 사용하여 .gitlab-ci.yml
에 지정된 컨테이너 리소스를 덮어쓸 수 있습니다.
services:
- name: redis:5
alias: redis5
variables:
KUBERNETES_SERVICE_CPU_REQUEST: "3"
KUBERNETES_SERVICE_CPU_LIMIT: "6"
KUBERNETES_SERVICE_MEMORY_REQUEST: "3Gi"
KUBERNETES_SERVICE_MEMORY_LIMIT: "6Gi"
KUBERNETES_EPHEMERAL_STORAGE_REQUEST: "2Gi"
KUBERNETES_EPHEMERAL_STORAGE_LIMIT: "3Gi"
- name: postgres:12
alias: MY_relational-database.12
variables:
KUBERNETES_CPU_REQUEST: "2"
KUBERNETES_CPU_LIMIT: "4"
KUBERNETES_MEMORY_REQUEST: "1Gi"
KUBERNETES_MEMORY_LIMIT: "2Gi"
KUBERNETES_EPHEMERAL_STORAGE_REQUEST: "1Gi"
KUBERNETES_EPHEMERAL_STORAGE_LIMIT: "2Gi"
이러한 특정 설정은 작업의 일반 설정보다 우선합니다.
값은 여전히 해당 리소스에 대한 최대 덮어쓰기 설정으로 제한됩니다.
Kubernetes 기본 서비스 계정 덮어쓰기
.gitlab-ci.yml
파일에서 각 CI/CD 작업에 대한 Kubernetes 서비스 계정을 덮어쓰려면, 변수 KUBERNETES_SERVICE_ACCOUNT_OVERWRITE
를 설정하세요.
이 변수를 사용하여 복잡한 RBAC 구성에 필요할 수 있는 네임스페이스에 첨부된 서비스 계정을 지정할 수 있습니다.
variables:
KUBERNETES_SERVICE_ACCOUNT_OVERWRITE: ci-service-account
CI 실행 중에 지정된 서비스 계정만 사용하도록 하려면, 다음 중 하나에 대한 정규 표현식을 정의하세요:
-
service_account_overwrite_allowed
설정. -
KUBERNETES_SERVICE_ACCOUNT_OVERWRITE_ALLOWED
환경 변수.
둘 다 설정하지 않으면, 덮어쓰기가 비활성화됩니다.
RuntimeClass 설정
- GitLab Runner 14.9에서 도입됨.
runtime_class_name
을 사용하여 각 작업 컨테이너의 RuntimeClass를 설정하세요.
RuntimeClass 이름을 지정하고 클러스터에 구성되지 않았거나 기능이 지원되지 않으면, 실행자는 작업을 생성하지 못합니다.
concurrent = 1
check_interval = 30
[[runners]]
name = "myRunner"
url = "gitlab.example.com"
executor = "kubernetes"
[runners.kubernetes]
runtime_class_name = "myclass"
빌드 로그 및 스크립트를 위한 기본 디렉터리 변경
- GitLab Runner 17.2에서 도입됨.
emptyDir
볼륨이 빌드 로그 및 스크립트를 위한 포드에 마운트되는 디렉토리를 변경할 수 있습니다.
디렉토리를 사용하여:
- 수정된 이미지를 사용하여 작업 포드를 실행합니다.
- 비특권 사용자로 실행합니다.
-
SecurityContext
설정을 사용자 지정합니다.
디렉터리를 변경하려면:
- 빌드 로그의 경우
logs_base_dir
를 설정합니다. - 빌드 스크립트의 경우
scripts_base_dir
를 설정합니다.
기대되는 값은 슬래시가 없는 기본 디렉토리를 나타내는 문자열입니다
(예: /tmp
또는 /mydir/example
). 디렉터리는 이미 존재해야 합니다.
이 값은 빌드 로그 및 스크립스를 위한 생성된 경로에 추가됩니다. 예를 들어:
[[runners]]
name = "myRunner"
url = "gitlab.example.com"
executor = "kubernetes"
[runners.kubernetes]
logs_base_dir = "/tmp"
scripts_base_dir = "/tmp"
이 구성은 다음과 같은 emptyDir
볼륨을 마운트합니다:
-
/tmp/logs-${CI_PROJECT_ID}-${CI_JOB_ID}
빌드 로그용 기본값인/logs-${CI_PROJECT_ID}-${CI_JOB_ID}
대신입니다. -
/tmp/scripts-${CI_PROJECT_ID}-${CI_JOB_ID}
빌드 스크립트용입니다.
사용자 네임스페이스
Kubernetes 1.30 이상에서, 컨테이너에서 실행되는 사용자를 호스트의 사용자와 격리할 수 있는 사용자 네임스페이스를 사용할 수 있습니다.
컨테이너 내에서 root로 실행되는 프로세스는 호스트에서 다른 비특권 사용자로 실행될 수 있습니다.
사용자 네임스페이스를 사용하면 CI/CD 작업을 실행하는 데 사용되는 이미지에 대한 더 많은 제어를 할 수 있습니다.
추가 설정이 필요한 작업(예: root로 실행)을 수행할 수 있으며, 호스트에 대한 추가 공격 표면을 열지 않고도 작동할 수 있습니다.
이 기능을 사용하려면 클러스터가 적절하게 구성되었는지 확인하세요.
다음 예제에서는 hostUsers
키에 대한 pod_spec
을 추가하고 특권 포드 및 권한 상승을 모두 비활성화합니다:
[[runners]]
environment = ["FF_USE_ADVANCED_POD_SPEC_CONFIGURATION=true"]
builds_dir = "/tmp/builds"
[runners.kubernetes]
logs_base_dir = "/tmp"
scripts_base_dir = "/tmp"
privileged = false
allowPrivilegeEscalation = false
[[runners.kubernetes.pod_spec]]
name = "hostUsers"
patch = '''
[{"op": "add", "path": "/hostUsers", "value": false}]
'''
patch_type = "json"
사용자 네임스페이스를 사용할 때는 빌드 디렉토리(builds_dir
), 빌드 로그(logs_base_dir
), 또는 빌드 스크립트(scripts_base_dir
)에 대한 기본 경로를 사용할 수 없습니다.
그렇지 않으면, 컨테이너의 root 사용자조차도 볼륨을 마운트하거나 컨테이너 파일 시스템의 루트에 디렉터리를 생성할 권한이 없습니다.
대신, 빌드 로그 및 스크립트의 기본 디렉토리를 변경할 수 있습니다. [[runners]].builds_dir
를 설정하여 빌드 디렉토리를 변경할 수도 있습니다.
운영 체제, 아키텍처 및 Windows 커널 버전
Kubernetes 실행기를 사용하는 GitLab Runner는 구성된 클러스터에 해당 운영 체제를 실행하는 노드가 있는 경우 다양한 운영 체제에서 빌드를 실행할 수 있습니다.
시스템은 헬퍼 이미지의 운영 체제, 아키텍처 및 Windows 커널 버전(해당되는 경우)을 결정합니다. 그런 다음 이 매개변수를 다른 빌드 측면, 예를 들어 사용할 컨테이너나 이미지를 위해 사용합니다.
다음 다이어그램은 시스템이 이러한 세부 정보를 감지하는 방법을 설명합니다:
다음은 빌드의 운영 체제, 아키텍처 및 Windows 커널 버전 선택에 영향을 미치는 유일한 매개변수입니다.
-
helper_image_autoset_arch_and_os
구성 -
kubernetes.io/os
,kubernetes.io/arch
및node.kubernetes.io/windows-build
레이블 선택기:-
node_selector
구성 -
node_selector
오버라이드
-
위에 설명된 선택 프로세스에는 다른 매개변수가 영향을 미치지 않습니다. 그러나, 예를 들어 affinity
구성은 빌드가 예약될 노드를 추가로 제한하는 데 사용될 수 있습니다.
노드
빌드를 실행할 노드 지정
node_selector
옵션을 사용하여 Kubernetes 클러스터에서 빌드를 실행할 수 있는 노드를 지정합니다.
이는 string=string
형식의 key=value
쌍입니다. (환경 변수의 경우 string:string
).
러너는 제공된 정보를 사용하여 빌드를 위한 운영 체제 및 아키텍처를 결정합니다. 이는 정확한 헬퍼 이미지가 사용되도록 보장합니다. 기본 운영 체제 및 아키텍처는 linux/amd64
입니다.
특정 레이블을 사용하여 서로 다른 운영 체제와 아키텍처를 가진 노드를 예약할 수 있습니다.
linux/arm64
예제
[[runners]]
name = "myRunner"
url = "gitlab.example.com"
executor = "kubernetes"
[runners.kubernetes.node_selector]
"kubernetes.io/arch" = "arm64"
"kubernetes.io/os" = "linux"
windows/amd64
예제
Windows용 Kubernetes에는 특정 제한 사항이 있습니다.
프로세스 격리를 사용하는 경우, node.kubernetes.io/windows-build
레이블과 함께 특정 Windows 빌드 버전을 제공해야 합니다.
[[runners]]
name = "myRunner"
url = "gitlab.example.com"
executor = "kubernetes"
# PowerShell이 Windows 노드를 대상으로 할 때 Linux 환경에서 경로를 올바르게 해결할 수 있도록
# FF_USE_POWERSHELL_PATH_RESOLVER 기능 플래그를 활성화해야 합니다.
environment = ["FF_USE_POWERSHELL_PATH_RESOLVER=true"]
[runners.kubernetes.node_selector]
"kubernetes.io/arch" = "amd64"
"kubernetes.io/os" = "windows"
"node.kubernetes.io/windows-build" = "10.0.20348"
노드 선택기 덮어쓰기
노드 선택기를 덮어쓰려면:
-
config.toml
또는 Helmvalues.yaml
파일에서 노드 선택기 덮어쓰기를 활성화합니다:runners: ... config: | [[runners]] [runners.kubernetes] node_selector_overwrite_allowed = ".*"
-
.gitlab-ci.yml
파일에서 노드 선택기를 덮어쓰는 변수를 정의합니다:variables: KUBERNETES_NODE_SELECTOR_* = ''
아래 예제에서는 Kubernetes 노드 아키텍처를 덮어쓰기 위해 설정이 config.toml
및 .gitlab-ci.yml
파일에 구성됩니다:
config.toml
concurrent = 1
check_interval = 1
log_level = "debug"
shutdown_timeout = 0
listen_address = ':9252'
[session_server]
session_timeout = 1800
[[runners]]
name = ""
url = "https://gitlab.com/"
id = 0
token = "__REDACTED__"
token_obtained_at = "0001-01-01T00:00:00Z"
token_expires_at = "0001-01-01T00:00:00Z"
executor = "kubernetes"
shell = "bash"
[runners.kubernetes]
host = ""
bearer_token_overwrite_allowed = false
image = "alpine"
namespace = ""
namespace_overwrite_allowed = ""
pod_labels_overwrite_allowed = ""
service_account_overwrite_allowed = ""
pod_annotations_overwrite_allowed = ""
node_selector_overwrite_allowed = "kubernetes.io/arch=.*" # <--- 아키텍처 덮어쓰기를 허용
.gitlab-ci.yml
job:
image: IMAGE_NAME
variables:
KUBERNETES_NODE_SELECTOR_ARCH: 'kubernetes.io/arch=amd64' # <--- 아키텍처 선택
노드 선호도 목록 정의
빌드 시 포드 사양에 추가할 노드 선호도 목록을 정의합니다.
주의:
node_affinities
는 빌드가 실행될 운영 체제를 결정하지 않으며, 오직 node_selectors
만 결정합니다. 자세한 내용은 운영 체제, 아키텍처 및 Windows 커널 버전을 참조하세요.
config.toml
에서의 예시 구성:
concurrent = 1
[[runners]]
name = "myRunner"
url = "gitlab.example.com"
executor = "kubernetes"
[runners.kubernetes]
[runners.kubernetes.affinity]
[runners.kubernetes.affinity.node_affinity]
[[runners.kubernetes.affinity.node_affinity.preferred_during_scheduling_ignored_during_execution]]
weight = 100
[runners.kubernetes.affinity.node_affinity.preferred_during_scheduling_ignored_during_execution.preference]
[[runners.kubernetes.affinity.node_affinity.preferred_during_scheduling_ignored_during_execution.preference.match_expressions]]
key = "cpu_speed"
operator = "In"
values = ["fast"]
[[runners.kubernetes.affinity.node_affinity.preferred_during_scheduling_ignored_during_execution.preference.match_expressions]]
key = "mem_speed"
operator = "In"
values = ["fast"]
[[runners.kubernetes.affinity.node_affinity.preferred_during_scheduling_ignored_during_execution]]
weight = 50
[runners.kubernetes.affinity.node_affinity.preferred_during_scheduling_ignored_during_execution.preference]
[[runners.kubernetes.affinity.node_affinity.preferred_during_scheduling_ignored_during_execution.preference.match_expressions]]
key = "core_count"
operator = "In"
values = ["high", "32"]
[[runners.kubernetes.affinity.node_affinity.preferred_during_scheduling_ignored_during_execution.preference.match_fields]]
key = "cpu_type"
operator = "In"
values = ["arm64"]
[runners.kubernetes.affinity.node_affinity.required_during_scheduling_ignored_during_execution]
[[runners.kubernetes.affinity.node_affinity.required_during_scheduling_ignored_during_execution.node_selector_terms]]
[[runners.kubernetes.affinity.node_affinity.required_during_scheduling_ignored_during_execution.node_selector_terms.match_expressions]]
key = "kubernetes.io/e2e-az-name"
operator = "In"
values = [
"e2e-az1",
"e2e-az2"
]
포드가 예약되는 노드 정의
- GitLab Runner 14.3에 소개됨.
포드 친화성과 비친화성을 사용하여 노드를 제한합니다.
your pod is eligible 포드가 예약될 수 있도록, 다른 포드의 레이블에 기반합니다.
config.toml
에서의 예시 구성:
concurrent = 1
[[runners]]
name = "myRunner"
url = "gitlab.example.com"
executor = "kubernetes"
[runners.kubernetes]
[runners.kubernetes.affinity]
[runners.kubernetes.affinity.pod_affinity]
[[runners.kubernetes.affinity.pod_affinity.required_during_scheduling_ignored_during_execution]]
topology_key = "failure-domain.beta.kubernetes.io/zone"
namespaces = ["namespace_1", "namespace_2"]
[runners.kubernetes.affinity.pod_affinity.required_during_scheduling_ignored_during_execution.label_selector]
[[runners.kubernetes.affinity.pod_affinity.required_during_scheduling_ignored_during_execution.label_selector.match_expressions]]
key = "security"
operator = "In"
values = ["S1"]
[[runners.kubernetes.affinity.pod_affinity.preferred_during_scheduling_ignored_during_execution]]
weight = 100
[runners.kubernetes.affinity.pod_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term]
topology_key = "failure-domain.beta.kubernetes.io/zone"
[runners.kubernetes.affinity.pod_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.label_selector]
[[runners.kubernetes.affinity.pod_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.label_selector.match_expressions]]
key = "security_2"
operator = "In"
values = ["S2"]
[runners.kubernetes.affinity.pod_anti_affinity]
[[runners.kubernetes.affinity.pod_anti_affinity.required_during_scheduling_ignored_during_execution]]
topology_key = "failure-domain.beta.kubernetes.io/zone"
namespaces = ["namespace_1", "namespace_2"]
[runners.kubernetes.affinity.pod_anti_affinity.required_during_scheduling_ignored_during_execution.label_selector]
[[runners.kubernetes.affinity.pod_anti_affinity.required_during_scheduling_ignored_during_execution.label_selector.match_expressions]]
key = "security"
operator = "In"
values = ["S1"]
[runners.kubernetes.affinity.pod_anti_affinity.required_during_scheduling_ignored_during_execution.namespace_selector]
[[runners.kubernetes.affinity.pod_anti_affinity.required_during_scheduling_ignored_during_execution.namespace_selector.match_expressions]]
key = "security"
operator = "In"
values = ["S1"]
[[runners.kubernetes.affinity.pod_anti_affinity.preferred_during_scheduling_ignored_during_execution]]
weight = 100
[runners.kubernetes.affinity.pod_anti_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term]
topology_key = "failure-domain.beta.kubernetes.io/zone"
[runners.kubernetes.affinity.pod_anti_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.label_selector]
[[runners.kubernetes.affinity.pod_anti_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.label_selector.match_expressions]]
key = "security_2"
operator = "In"
values = ["S2"]
[runners.kubernetes.affinity.pod_anti_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.namespace_selector]
[[runners.kubernetes.affinity.pod_anti_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.namespace_selector.match_expressions]]
key = "security_2"
operator = "In"
values = ["S2"]
네트워킹
컨테이너 생애 주기 후크 구성
- GitLab Runner 14.2에서 도입됨.
컨테이너 생애 주기 후크를 사용하여 해당 생애 주기 후크가 실행될 때 핸들러에 대해 구성된 코드를 실행합니다.
두 가지 유형의 후크를 구성할 수 있습니다: PreStop
및 PostStart
. 각 후크는 한 가지 유형의 핸들러만 설정할 수 있습니다.
config.toml
파일의 예제 구성:
[[runners]]
name = "kubernetes"
url = "https://gitlab.example.com/"
executor = "kubernetes"
token = "yrnZW46BrtBFqM7xDzE7dddd"
[runners.kubernetes]
image = "alpine:3.11"
privileged = true
namespace = "default"
[runners.kubernetes.container_lifecycle.post_start.exec]
command = ["touch", "/builds/postStart.txt"]
[runners.kubernetes.container_lifecycle.pre_stop.http_get]
port = 8080
host = "localhost"
path = "/test"
[[runners.kubernetes.container_lifecycle.pre_stop.http_get.http_headers]]
name = "header_name_1"
value = "header_value_1"
[[runners.kubernetes.container_lifecycle.pre_stop.http_get.http_headers]]
name = "header_name_2"
value = "header_value_2"
각 생애 주기 후크를 구성하는 데 사용할 수 있는 설정은 다음과 같습니다:
옵션 | 유형 | 필수 | 설명 |
---|---|---|---|
exec |
KubernetesLifecycleExecAction |
아니요 |
Exec 는 수행할 작업을 지정합니다. |
http_get |
KubernetesLifecycleHTTPGet |
아니요 |
HTTPGet 은 수행할 http 요청을 지정합니다. |
tcp_socket |
KubernetesLifecycleTcpSocket |
아니요 |
TCPsocket 은 TCP 포트와 관련된 작업을 지정합니다. |
KubernetesLifecycleExecAction
옵션 | 유형 | 필수 | 설명 |
---|---|---|---|
command |
string 목록 |
예 | 컨테이너 내에서 실행할 명령어입니다. |
KubernetesLifecycleHTTPGet
옵션 | 유형 | 필수 | 설명 |
---|---|---|---|
port |
int |
예 | 컨테이너에서 접근할 포트 번호입니다. |
host |
string | 아니요 | 연결할 호스트 이름으로, 기본적으로 파드 IP로 설정됩니다(선택 사항). |
path |
string | 아니요 | HTTP 서버에서 접근할 경로입니다(선택 사항). |
scheme |
string | 아니요 | 호스트에 연결할 때 사용하는 스킴으로, 기본적으로 HTTP입니다(선택 사항). |
http_headers |
KubernetesLifecycleHTTPGetHeader 목록 |
아니요 | 요청에 설정할 사용자 정의 헤더입니다(선택 사항). |
KubernetesLifecycleHTTPGetHeader
옵션 | 유형 | 필수 | 설명 |
---|---|---|---|
name |
string | 예 | HTTP 헤더 이름입니다. |
value |
string | 예 | HTTP 헤더 값입니다. |
KubernetesLifecycleTcpSocket
옵션 | 유형 | 필수 | 설명 |
---|---|---|---|
port |
int |
예 | 컨테이너에서 접근할 포트 번호입니다. |
host |
string | 아니오 | 연결할 호스트 이름, 기본값은 포드 IP입니다(선택적). |
포드 DNS 설정 구성
다음 옵션을 사용하여 포드의 DNS 설정을 구성합니다.
옵션 | 유형 | 필수 | 설명 |
---|---|---|---|
nameservers |
string 리스트 |
아니오 | 포드에 대한 DNS 서버로 사용될 IP 주소의 목록입니다. |
options |
KubernetesDNSConfigOption |
아니오 | 각 객체가 필수 속성인 이름과 선택적 속성인 값을 가질 수 있는 객체 목록입니다. |
searches |
string 리스트 |
아니오 | 포드에서 호스트 이름을 조회하기 위한 DNS 검색 도메인의 목록입니다. |
config.toml
파일의 예제 구성:
concurrent = 1
check_interval = 30
[[runners]]
name = "myRunner"
url = "https://gitlab.example.com"
token = "__REDACTED__"
executor = "kubernetes"
[runners.kubernetes]
image = "alpine:latest"
[runners.kubernetes.dns_config]
nameservers = [
"1.2.3.4",
]
searches = [
"ns1.svc.cluster-domain.example",
"my.dns.search.suffix",
]
[[runners.kubernetes.dns_config.options]]
name = "ndots"
value = "2"
[[runners.kubernetes.dns_config.options]]
name = "edns0"
KubernetesDNSConfigOption
옵션 | 유형 | 필수 | 설명 |
---|---|---|---|
name |
string | 예 | 구성 옵션 이름입니다. |
value |
*string |
아니오 | 구성 옵션 값입니다. |
기본 드롭된 기능 목록
GitLab Runner는 기본적으로 다음 기능을 드롭합니다.
사용자 정의 cap_add
가 기본 드롭된 기능 목록보다 우선합니다.
기본적으로 드롭된 기능을 추가하려면 cap_add
에 추가하세요.
NET_RAW
추가 호스트 별칭 추가
이 프리미엄 기능은 Kubernetes 1.7 이상에서 사용할 수 있습니다.
Kubernetes에 컨테이너의 /etc/hosts
파일에 항목을 추가하도록 지시하기 위해 호스트 별칭을 구성합니다.
다음 옵션을 사용하세요:
옵션 | 유형 | 필수 | 설명 |
---|---|---|---|
IP |
string | 예 | 호스트를 연결하려는 IP 주소입니다. |
Hostnames |
string 리스트 |
예 | IP에 연결될 호스트 이름 별칭 목록입니다. |
config.toml
파일의 예제 구성:
concurrent = 4
[[runners]]
# 일반 구성
executor = "kubernetes"
[runners.kubernetes]
[[runners.kubernetes.host_aliases]]
ip = "127.0.0.1"
hostnames = ["web1", "web2"]
[[runners.kubernetes.host_aliases]]
ip = "192.168.1.1"
hostnames = ["web14", "web15"]
또한 JSON 입력이 포함된 명령줄 매개변수 --kubernetes-host_aliases
를 사용하여 호스트 별칭을 구성할 수 있습니다. 예를 들어:
gitlab-runner register --kubernetes-host_aliases '[{"ip":"192.168.1.100","hostnames":["myservice.local"]},{"ip":"192.168.1.101","hostnames":["otherservice.local"]}]'
볼륨
Kubernetes 실행자와 함께 캐시 사용하기
Kubernetes 실행자와 함께 캐시를 사용할 때, /cache
라는 볼륨이 파드에 마운트됩니다.
작업 실행 중, 캐시된 데이터가 필요할 경우, 러너는 캐시된 데이터가 사용 가능한지 확인합니다.
캐시된 데이터는 압축된 파일이 캐시 볼륨에 있을 때 사용 가능합니다.
캐시 볼륨을 설정하려면, config.toml
파일의 cache_dir
설정을 사용하세요.
-
사용 가능한 경우, 압축된 파일이 빌드 폴더로 추출되어 작업에서 사용할 수 있습니다.
-
사용 가능하지 않은 경우, 캐시된 데이터는 구성된 저장소에서 다운로드되어
cache dir
에 압축된 파일로 저장됩니다. 그런 다음 압축된 파일이build
폴더로 추출됩니다.
볼륨 유형 구성하기
다음 볼륨 유형을 마운트할 수 있습니다:
hostPath
persistentVolumeClaim
configMap
secret
emptyDir
csi
여러 볼륨 유형이 포함된 구성의 예:
concurrent = 4
[[runners]]
# 일반 구성
executor = "kubernetes"
[runners.kubernetes]
[[runners.kubernetes.volumes.host_path]]
name = "hostpath-1"
mount_path = "/path/to/mount/point"
read_only = true
host_path = "/path/on/host"
[[runners.kubernetes.volumes.host_path]]
name = "hostpath-2"
mount_path = "/path/to/mount/point_2"
read_only = true
[[runners.kubernetes.volumes.pvc]]
name = "pvc-1"
mount_path = "/path/to/mount/point1"
[[runners.kubernetes.volumes.config_map]]
name = "config-map-1"
mount_path = "/path/to/directory"
[runners.kubernetes.volumes.config_map.items]
"key_1" = "relative/path/to/key_1_file"
"key_2" = "key_2"
[[runners.kubernetes.volumes.secret]]
name = "secrets"
mount_path = "/path/to/directory1"
read_only = true
[runners.kubernetes.volumes.secret.items]
"secret_1" = "relative/path/to/secret_1_file"
[[runners.kubernetes.volumes.empty_dir]]
name = "empty-dir"
mount_path = "/path/to/empty_dir"
medium = "Memory"
[[runners.kubernetes.volumes.csi]]
name = "csi-volume"
mount_path = "/path/to/csi/volume"
driver = "my-csi-driver"
[runners.kubernetes.volumes.csi.volume_attributes]
size = "2Gi"
hostPath
볼륨
지정된 호스트 경로를 컨테이너에 마운트하기 위해 hostPath
볼륨을 구성하세요.
config.toml
파일에서 다음 옵션을 사용하세요:
옵션 | 유형 | 필수 여부 | 설명 |
---|---|---|---|
name |
string | 예 | 볼륨의 이름입니다. |
mount_path |
string | 예 | 볼륨이 마운트되는 컨테이너 내 경로입니다. |
sub_path |
string | 아니오 | 루트 대신 볼륨 안에 서브 경로를 마운트합니다. |
host_path |
string | 아니오 | 볼륨으로 마운트 할 호스트 경로입니다. 지정하지 않으면 mount_path 와 동일한 경로로 설정됩니다. |
read_only |
boolean | 아니오 | 볼륨을 읽기 전용 모드로 설정합니다(기본값은 false입니다). |
persistentVolumeClaim
볼륨
persistentVolumeClaim
볼륨을 구성하여
Kubernetes에 Kubernetes 클러스터에서 정의된 persistentVolumeClaim
을 사용하고 이를 컨테이너에 마운트하도록 지시합니다.
config.toml
파일에 다음 옵션을 사용하세요:
옵션 | 유형 | 필수 | 설명 |
---|---|---|---|
name |
string | 예 | 볼륨의 이름이자 사용해야 할 PersistentVolumeClaim 의 이름입니다. 변수를 지원합니다. 자세한 정보는 동시 빌드 볼륨을 지속적으로 유지하기를 참조하세요. |
mount_path |
string | 예 | 볼륨이 마운트되는 컨테이너 내 경로입니다. |
read_only |
boolean | 아니오 | 볼륨을 읽기 전용 모드로 설정합니다(기본값은 false입니다). |
sub_path |
string | 아니오 | 루트 대신 볼륨 내에 서브 경로를 마운트합니다. |
configMap
볼륨
configMap
볼륨을 구성하여 Kubernetes에
Kubernetes 클러스터에서 정의된 configMap
을 사용하고 이를 컨테이너에 마운트하도록 지시합니다.
config.toml
에 다음 옵션을 사용하세요:
옵션 | 유형 | 필수 | 설명 |
---|---|---|---|
name |
string | 예 | 볼륨의 이름이자 사용해야 할 _configMap_의 이름입니다. |
mount_path |
string | 예 | 볼륨이 마운트되는 컨테이너 내 경로입니다. |
read_only |
boolean | 아니오 | 볼륨을 읽기 전용 모드로 설정합니다(기본값은 false입니다). |
sub_path |
string | 아니오 | 루트 대신 볼륨 내에 서브 경로를 마운트합니다. |
items |
map[string]string |
아니오 | 사용해야 할 _configMap_의 키-경로 매핑입니다. |
configMap
의 각 키는 파일로 변경되어 마운트 경로에 저장됩니다. 기본적으로:
- 모든 키가 포함됩니다.
-
configMap
키가 파일 이름으로 사용됩니다. - 값은 파일 내용으로 저장됩니다.
기본 키 및 값 저장 방식을 변경하려면 items
옵션을 사용하세요. items
옵션을 사용하는 경우, 지정된 키만 볼륨에 추가되고 다른 모든 키는 건너뜁니다.
참고: 존재하지 않는 키를 사용하는 경우, 작업이 포드 생성 단계에서 실패합니다.
secret
볼륨
secret
볼륨을 구성하여 Kubernetes에
Kubernetes 클러스터에서 정의된 secret
을 사용하고 이를 컨테이너에 마운트하도록 지시합니다.
config.toml
파일에 다음 옵션을 사용하세요:
옵션 | 유형 | 필수 | 설명 |
---|---|---|---|
name |
string | 예 | 볼륨의 이름이자 사용해야 할 _secret_의 이름입니다. |
mount_path |
string | 예 | 볼륨이 마운트되는 컨테이너 내 경로입니다. |
read_only |
boolean | 아니오 | 볼륨을 읽기 전용 모드로 설정합니다(기본값은 false입니다). |
sub_path |
string | 아니오 | 루트 대신 볼륨 내에 서브 경로를 마운트합니다. |
items |
map[string]string |
아니오 | 사용해야 할 _configMap_의 키-경로 매핑입니다. |
선택한 secret
의 각 키는 선택한 마운트 경로에 저장된 파일로 변경됩니다. 기본적으로:
- 모든 키가 포함됩니다.
-
configMap
키가 파일 이름으로 사용됩니다. - 값은 파일 내용으로 저장됩니다.
기본 키 및 값 저장 방식을 변경하려면 items
옵션을 사용하세요. items
옵션을 사용하는 경우, 지정된 키만 볼륨에 추가되고 다른 모든 키는 건너뜁니다.
참고: 존재하지 않는 키를 사용하는 경우, 작업이 포드 생성 단계에서 실패합니다.
emptyDir
볼륨
emptyDir
볼륨을 구성하여 Kubernetes에 컨테이너에 빈 디렉토리를 마운트하도록 지시합니다.
config.toml
파일에서 다음 옵션을 사용하세요:
옵션 | 타입 | 필수 | 설명 |
---|---|---|---|
name |
문자열 | 예 | 볼륨의 이름입니다. |
mount_path |
문자열 | 예 | 볼륨이 마운트되어야 하는 컨테이너 내부 경로입니다. |
sub_path |
문자열 | 아니오 | 루트 대신 볼륨의 서브 경로를 마운트합니다. |
medium |
문자열 | 아니오 | “Memory”는 tmpfs 를 제공하며, 기본적으로 노드 디스크 저장소를 사용합니다(기본값: “”). |
size_limit |
문자열 | 아니오 |
emptyDir 볼륨에 필요한 로컬 저장소의 총 용량입니다. |
csi
볼륨
컨테이너 저장소 인터페이스(csi
) 볼륨을 구성하여 Kubernetes에 사용자 지정 csi
드라이버를 사용하여 컨테이너에 임의의 저장 시스템을 마운트하도록 지시합니다.
config.toml
에서 다음 옵션을 사용하세요:
옵션 | 타입 | 필수 | 설명 |
---|---|---|---|
name |
문자열 | 예 | 볼륨의 이름입니다. |
mount_path |
문자열 | 예 | 볼륨이 마운트되어야 하는 컨테이너 내부 경로입니다. |
driver |
문자열 | 예 | 사용할 볼륨 드라이버의 이름을 지정하는 문자열 값입니다. |
fs_type |
문자열 | 아니오 | 파일 시스템 유형의 이름을 지정하는 문자열 값입니다(예: “ext4”, “xfs”, “ntfs”). |
volume_attributes |
map[string]string |
아니오 | CSI 볼륨 속성에 대한 키-값 쌍 매핑입니다. |
sub_path |
문자열 | 아니오 | 루트 대신 볼륨 내의 서브 경로를 마운트합니다. |
read_only |
불리언 | 아니오 | 볼륨을 읽기 전용 모드로 설정합니다(기본값: false). |
서비스 컨테이너에 볼륨 마운트
빌드 컨테이너에 정의된 볼륨은 모든 서비스 컨테이너에 자동으로 마운트됩니다. 이 기능은 데이터베이스 저장소를 RAM에 마운트하여 테스트 속도를 높이기 위해 services_tmpfs
대신 사용할 수 있습니다(오직 Docker 실행자에서만 사용 가능).
config.toml
파일에서의 예시 구성:
[[runners]]
# 일반 구성
executor = "kubernetes"
[runners.kubernetes]
[[runners.kubernetes.volumes.empty_dir]]
name = "mysql-tmpfs"
mount_path = "/var/lib/mysql"
medium = "Memory"
사용자 정의 볼륨 마운트
작업을 위한 빌드 디렉토리를 저장하려면 구성된 builds_dir
(기본값: /builds
)에 사용자 정의 볼륨 마운트를 정의하세요.
PVC 볼륨을 사용하는 경우, 접근 모드에 따라 한 노드에서만 작업을 실행해야 할 수도 있습니다.
config.toml
파일에서의 예시 구성:
concurrent = 4
[[runners]]
# 일반 구성
executor = "kubernetes"
builds_dir = "/builds"
[runners.kubernetes]
[[runners.kubernetes.volumes.empty_dir]]
name = "repo"
mount_path = "/builds"
medium = "Memory"
지속적인 동시 빌드 볼륨
pvc.name
에 대한 변수 주입 지원이 GitLab 16.3에서 도입되었습니다.
Kubernetes CI 작업의 빌드 디렉토리는 기본적으로 일시적입니다.
작업 간에 Git 클론을 유지하려면(GIT_STRATEGY=fetch
가 작동하도록 하려면),
빌드 폴더에 대한 지속적인 볼륨 클레임을 마운트해야 합니다.
여러 작업이 동시에 실행될 수 있으므로,
ReadWriteMany
볼륨을 사용하거나
같은 러너에서 잠재적인 동시 작업마다 하나의 볼륨을 가져야 합니다.
후자의 경우 더 높은 성능을 발휘할 가능성이 높습니다.
다음은 이러한 구성의 예입니다:
concurrent = 4
[[runners]]
executor = "kubernetes"
builds_dir = "/mnt/builds"
[runners.kubernetes]
[[runners.kubernetes.volumes.pvc]]
# CI_CONCURRENT_ID는 같은 러너의 병렬 작업을 식별합니다.
name = "build-pvc-$CI_CONCURRENT_ID"
mount_path = "/mnt/builds"
이 예시에서는
build-pvc-0
에서 build-pvc-3
까지의 지속적 볼륨 클레임을
직접 생성해야 합니다.
러너의 concurrent
설정이 지시하는 만큼 생성하세요.
헬퍼 이미지 사용하기
보안 정책을 설정한 후,
헬퍼 이미지는 정책을 준수해야 합니다.
이미지는 루트 그룹의 권한을 받지 않으므로,
사용자 ID가 루트 그룹의 일부인지 확인해야 합니다.
참고:
nonroot
환경만 필요하다면,
OpenShift(OCP) 이미지를 헬퍼 이미지 대신 사용할 수 있습니다.
다음 예는 nonroot
라는 사용자와 그룹을 생성하고
해당 사용자로 실행되도록 헬퍼 이미지를 설정합니다.
ARG tag
FROM registry.gitlab.com/gitlab-org/ci-cd/gitlab-runner-ubi-images/gitlab-runner-helper-ocp:${tag}
USER root
RUN groupadd -g 59417 nonroot && \
useradd -u 59417 nonroot -g nonroot
WORKDIR /home/nonroot
USER 59417:59417
빌드에서 Docker 사용하기
빌드에서 Docker를 사용할 때,
알아야 할 몇 가지 고려사항이 있습니다.
노출된 /var/run/docker.sock
호스트의 /var/run/docker.sock
을 빌드 컨테이너에 노출하기 위해
runners.kubernetes.volumes.host_path
옵션을 사용하는 경우,
특정 위험이 있습니다.
노드의 컨테이너는 빌드 컨테이너에서 접근할 수 있으며,
프로덕션 컨테이너와 동일한 클러스터에서 빌드를 실행하는 경우에는
그렇게 하는 것이 현명하지 않을 수 있습니다.
docker:dind
사용하기
docker:dind
를 실행하면
docker-in-docker
이미지라고도 하며,
컨테이너는 특권 모드에서 실행해야 합니다.
이로 인해 잠재적인 위험이 있으며
추가적인 문제가 발생할 수 있습니다.
Docker 데몬은 팟에서 별도의 컨테이너로 실행되며
service
로 시작되므로
일반적으로 .gitlab-ci.yml
에서 실행됩니다.
팟의 컨테이너는 그들에게 할당된 볼륨과
서로 통신하는 데 사용하는 IP 주소만 공유합니다.
docker:dind
컨테이너는 /var/run/docker.sock
을 공유하지 않으며
docker
바이너리는 기본적으로 이를 사용하려고 합니다.
클라이언트가 Docker 데몬에 TCP로 접속하도록 구성하려면,
다른 컨테이너에
빌드 컨테이너의 환경 변수를 포함하세요:
- TLS 연결이 없는 경우
DOCKER_HOST=tcp://<hostname>:2375
입니다. - TLS 연결이 있는 경우
DOCKER_HOST=tcp://<hostname>:2376
입니다.
hostname
의 값을 설정합니다:
- GitLab Runner 12.7 이하, Kubernetes 1.6 이하의 경우
localhost
입니다. - GitLab Runner 12.8 이상, Kubernetes 1.7 이상에서
docker
입니다.
Docker 19.03 이상에서는
기본적으로 TLS가 활성화되어 있지만
클라이언트에 인증서를 매핑해야 합니다.
DIND에 대한 비 TLS 연결을 활성화하거나
인증서를 마운트할 수 있습니다.
자세한 내용은
Docker 실행기를 사용한 Docker In Docker 워크플로우 사용하기를 참조하세요.
호스트 커널 노출 방지
docker:dind
또는 /var/run/docker.sock
을 사용하는 경우, Docker 데몬은 호스트 머신의 기본 커널에 접근할 수 있습니다. 이는 Docker 이미지를 빌드할 때 포드에 설정된 어떤 limits
도 작동하지 않음을 의미합니다. Docker 데몬은 Kubernetes에서 생성된 Docker 빌드 컨테이너에 부과된 제한과 상관없이 노드의 전체 용량을 보고합니다.
빌드 컨테이너를 특권 모드로 실행하거나 /var/run/docker.sock
이 노출되면, 호스트 커널이 빌드 컨테이너에 노출될 수 있습니다. 노출을 최소화하려면, node_selector
옵션에 라벨을 지정하세요. 이는 컨테이너가 노드에 배포되기 전에 노드가 라벨과 일치하는지 확인합니다. 예를 들어, role=ci
라벨을 지정하면, 빌드 컨테이너는 role=ci
로 라벨링된 노드에서만 실행되며, 모든 다른 프로덕션 서비스는 다른 노드에서 실행됩니다.
빌드 컨테이너를 추가로 분리하기 위해, 노드 taints를 사용할 수 있습니다. Taints는 추가 구성 없이 빌드 포드와 동일한 노드에 다른 포드가 스케줄링되는 것을 방지합니다.
kaniko를 사용하여 Docker 이미지 빌드
Kubernetes 클러스터 내에서 Docker 이미지를 빌드하려면 kaniko를 사용할 수 있습니다.
Kaniko는 Docker 데몬 없이 작동하며, 특권 접근 권한 없이 이미지를 빌드합니다.
더 많은 정보는 kaniko 및 GitLab CI/CD로 이미지 빌드하기를 참조하세요.
kaniko를 사용하여 multi-stage Dockerfile
을 빌드할 때 알려진 문제가 있습니다. 파이프라인 작업에 after_script
섹션이 포함되어 있으면, after_script
섹션이 실행될 때 다음 오류 메시지와 함께 실패합니다. 작업은 여전히 성공적으로 완료됩니다.
OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: chdir to cwd
("/workspace") set in config.json failed: no such file or directory: unknown
이 섹션은 kaniko가 multi-stage Dockerfile
을 빌드할 때 컨테이너의 WORKDIR
을 삭제하기 때문에 실패합니다. 이로 인해 kubectl exec
(그리고 유사한 SDK API)이 컨테이너에 연결되지 못합니다.
이 문제에 대한 두 가지 우회 방법이 있습니다:
- kaniko 실행 호출에
--ignore-path /workspace
를 추가합니다. - kaniko 실행 호출 후에 작업의
script
에mkdir -p /workspace
를 추가합니다.
더 많은 정보는 이슈 30769를 참조하세요.
Docker 이미지 및 서비스 제한
- GitLab Runner 14.2에서 Kubernetes 실행자에 추가되었습니다.
작업을 실행하는 데 사용되는 Docker 이미지를 제한할 수 있습니다. 이를 위해 와일드카드 패턴을 지정합니다. 예를 들어, 개인 Docker 레지스트리에서 이미지만 허용하려면:
[[runners]]
(...)
executor = "kubernetes"
[runners.kubernetes]
(...)
allowed_images = ["my.registry.tld:5000/*:*"]
allowed_services = ["my.registry.tld:5000/*:*"]
또는 이 레지스트리에서 특정 이미지 목록으로 제한하려면:
[[runners]]
(...)
executor = "kubernetes"
[runners.kubernetes]
(...)
allowed_images = ["my.registry.tld:5000/ruby:*", "my.registry.tld:5000/node:*"]
allowed_services = ["postgres:9.4", "postgres:latest"]
Docker 풀 정책 제한
- GitLab 15.1에서 소개됨.
.gitlab-ci.yml
파일에서 풀 정책을 지정할 수 있습니다. 이 정책은 CI/CD 작업이 이미지를 가져오는 방식을 결정합니다.
.gitlab-ci.yml
파일에서 사용할 수 있는 풀 정책을 제한하려면 allowed_pull_policies
를 사용합니다.
예를 들어, always
와 if-not-present
풀 정책만 허용하려면:
[[runners]]
(...)
executor = "kubernetes"
[runners.kubernetes]
(...)
allowed_pull_policies = ["always", "if-not-present"]
-
allowed_pull_policies
를 지정하지 않으면, 기본값은pull_policy
키워드의 값입니다. -
pull_policy
를 지정하지 않으면 클러스터의 이미지 기본 풀 정책이 사용됩니다. - 기존의
pull_policy
키워드는allowed_pull_policies
에 지정되지 않은 풀 정책을 포함하면 안 됩니다. 포함된 경우 작업은 오류를 반환합니다.
작업 실행
- 기본적으로 활성화된 기능 플래그
FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY
뒤에 있습니다.- GitLab Runner 14.0에서 기본적으로 attach 사용.
GitLab Runner는 기본적으로 kube attach
를 사용합니다. 이는 작업이 중간에 성공으로 표시되는 문제를 방지해야 합니다.
불안정한 네트워크 환경에서 발생할 수 있습니다.
GitLab Runner 14.0으로 업데이트한 후 문제가 발생하면 기능 플래그 FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY
를 true
로 전환하고 문제를 제출하세요.
레거시 실행 전략 제거에 대한 진행 상황은 문제 #27976를 참조하세요.
Kubernetes API에 대한 요청 시도 횟수 구성
기본적으로 Kubernetes 실행자는 Kubernetes API에 특정 요청을 5회 실패한 후 재시도합니다. 지연은 500밀리초 플로어와 기본값이 2초인 사용자 지정 가능한 상한을 가진 백오프 알고리즘으로 제어됩니다. 재시도 횟수와 백오프 상한을 구성하려면 config.toml
파일에서 각각 retry_limit
과 retry_backoff_max
옵션을 사용합니다.
다음 실패는 자동으로 재시도됩니다:
error dialing backend
TLS handshake timeout
read: connection timed out
connect: connection timed out
Timeout occurred
http2: client connection lost
connection refused
tls: internal error
io.unexpected EOF
syscall.ECONNRESET
syscall.ECONNREFUSED
syscall.ECONNABORTED
syscall.EPIPE
각 오류에 대한 재시도 횟수를 제어하려면 retry_limits
옵션을 사용합니다.
retry_limits
는 각 오류에 대한 재시도 횟수를 별도로 지정하며, 오류 메시지와 재시도 횟수의 맵입니다.
오류 메시지는 Kubernetes API에서 반환된 오류 메시지의 서브스트링일 수 있습니다.
retry_limits
옵션은 retry_limit
옵션보다 우선합니다.
예를 들어, TLS 관련 오류의 수를 제어해야 하는 경우, retry_limits
옵션을 구성하여 해당 오류를 기본 5회 대신 10회 재시도하도록 설정할 수 있습니다:
[[runners]]
name = "myRunner"
url = "https://gitlab.example.com/"
executor = "kubernetes"
[runners.kubernetes]
retry_limit = 5
[runners.kubernetes.retry_limits]
"TLS handshake timeout" = 10
"tls: internal error" = 10
exceeded quota
와 같은 전혀 다른 오류를 20회 재시도하려면:
[[runners]]
name = "myRunner"
url = "https://gitlab.example.com/"
executor = "kubernetes"
[runners.kubernetes]
retry_limit = 5
[runners.kubernetes.retry_limits]
"exceeded quota" = 20
컨테이너 엔트리포인트 알려진 문제
kube attach
를 사용할 때 Docker 이미지에서 정의된 엔트리포인트를 사용합니다.GitLab 15.1 이상에서는
FF_KUBERNETES_HONOR_ENTRYPOINT
가 설정되어 있을 때 Docker 이미지에서 정의된 엔트리포인트가 Kubernetes 실행기와 함께 사용됩니다.컨테이너 엔트리 포인트에는 다음과 같은 알려진 문제가 있습니다:
-
이미지의 Dockerfile에 엔트리포인트가 정의된 경우, 유효한 셸을 열어야 합니다. 그렇지 않으면 작업이 중단됩니다.
- 셸을 열기 위해 시스템은 명령을
args
매개변수로 빌드 컨테이너에 전달합니다.
- 셸을 열기 위해 시스템은 명령을
- 파일 유형 CI/CD 변수는 엔트리포인트가 실행될 때 디스크에 기록되지 않습니다. 파일은 오직 스크립트 실행 중에 작업에서만 접근할 수 있습니다.
- 다음의 CI/CD 변수는 엔트리포인트에서 접근할 수 없습니다.
before_script
를 사용하여 스크립트 명령을 실행하기 전에 필요한 설정 변경을 수행할 수 있습니다:
GitLab Runner 17.4 이전:
- 엔트리포인트 로그는 빌드 로그로 전달되지 않았습니다.
-
kube exec
를 사용하는 Kubernetes 실행기와 함께 GitLab Runner는 엔트리포인트가 셸을 열기를 기다리지 않았습니다 (위의 open-valid-shell 참조).
GitLab Runner 17.4부터는 엔트리포인트 로그가 이제 전달됩니다. 시스템은 엔트리포인트가 실행되어 셸을 생성할 때까지 기다립니다. 이는 다음과 같은 영향을 미칩니다:
-
FF_KUBERNETES_HONOR_ENTRYPOINT
가 설정되어 있고, 이미지의 엔트리포인트가poll_timeout
(기본값: 180초)보다 오래 걸릴 경우, 빌드가 실패합니다.
엔트리포인트가 더 오래 실행될 것으로 예상되는 경우poll_timeout
값(및 잠재적으로poll_interval
)을 조정해야 합니다. -
FF_KUBERNETES_HONOR_ENTRYPOINT
및FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY
가 설정되어 있을 때, 시스템은 빌드 컨테이너에
시작 프로브를 추가하여 엔트리포인트가 셸을 생성할 때 알 수 있도록 합니다.
사용자 정의 엔트리포인트가 제공된args
를 사용하여 예상되는 셸을 생성하는 경우, 시작 프로브가 자동으로 해결됩니다.
그러나 컨테이너 이미지가args
를 통해 전달된 명령을 사용하지 않고 셸을 생성하는 경우, 엔트리포인트는 빌드 디렉터리의 루트에.gitlab-startup-marker
라는 파일을 생성하여 시작 프로브를 해결해야 합니다.
시작 프로브는.gitlab-startup-marker
파일을 위해 매poll_interval
마다 확인합니다. 파일이poll_timeout
내에 존재하지 않으면, 파드는 비정상으로 간주되며 시스템은 빌드를 중단합니다.
작업 변수에 대한 접근 제한
Kubernetes 실행자를 사용할 때, Kubernetes 클러스터에 접근할 수 있는 사용자는 작업에 사용되는 변수를 읽을 수 있습니다. 기본적으로 작업 변수는 다음에 저장됩니다:
- Pod의 환경 섹션
작업 변수 데이터를 보호하기 위해, GitLab 관리자가 GitLab Runner가 사용하는 네임스페이스에만 접근할 수 있도록 역할 기반 접근 제어(RBAC)를 사용해야 합니다.
다른 사용자가 GitLab Runner 네임스페이스에 접근할 수 있도록 하려면, 다음의 verbs
를 설정하여 사용자가 GitLab Runner 네임스페이스에서 가지는 접근 유형을 제한하세요:
-
pods
및configmaps
의 경우:get
watch
list
-
pods/exec
및pods/attach
의 경우,create
를 사용하세요.
인증된 사용자를 위한 예시 RBAC 정의:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: gitlab-runner-authorized-users
rules:
- apiGroups: [""]
resources: ["configmaps", "pods"]
verbs: ["get", "watch", "list"]
- apiGroups: [""]
resources: ["pods/exec", "pods/attach"]
verbs: ["create"]
준비 단계 동안의 리소스 확인
- GitLab 15.0에 도입됨.
- GitLab 15.2에서 업데이트됨.
전제 조건:
-
image_pull_secrets
또는service_account
가 설정되어 있어야 합니다. -
resource_availability_check_max_attempts
가 0보다 큰 숫자로 설정되어야 합니다. -
get
및list
권한으로 사용된 KubernetesserviceAccount
가 필요합니다.
GitLab Runner는 새로운 서비스 계정이나 비밀이 사용 가능한지 5초 간격으로 확인합니다.
- GitLab 15.0 및 15.1에서는 이 기능을 비활성화할 수 없으며, 부정값이 설정되었을 때 기본값은
5
입니다. - GitLab 15.0.1, 15.1.1, 15.2 및 이후 버전에서는 이 기능이 기본적으로 비활성화되어 있습니다. 이 기능을 활성화하려면
resource_availability_check_max_attempts
를0
이 아닌 값으로 설정하세요.
설정한 값은 러너가 서비스 계정이나 비밀을 확인하는 횟수를 정의합니다.
Kubernetes 네임스페이스 재정의
전제 조건:
- GitLab Runner Helm 차트의
values.yml
파일에서rbac.clusterWideAccess
가true
로 설정되어 있어야 합니다. - 러너가 권한을 core API 그룹에서 구성해야 합니다.
CI 목적으로 네임스페이스를 지정하기 위해 Kubernetes 네임스페이스를 재정의하고, 사용자 정의된 pods 세트를 배포할 수 있습니다. 러너에 의해 생성된 pods는 재정의된 네임스페이스에 있어 CI 단계 동안 컨테이너 간의 접근을 가능하게 합니다.
각 CI/CD 작업에 대한 Kubernetes 네임스페이스를 재정의하려면, .gitlab-ci.yml
파일의 KUBERNETES_NAMESPACE_OVERWRITE
변수를 설정하세요.
variables:
KUBERNETES_NAMESPACE_OVERWRITE: ci-${CI_COMMIT_REF_SLUG}
참고: 이 변수는 클러스터에 네임스페이스를 생성하지 않습니다. 작업을 실행하기 전에 네임스페이스가 존재하는지 확인하세요.
CI 실행 중에 지정된 네임스페이스만 사용하려면, config.toml
파일에서 namespace_overwrite_allowed
에 대한 정규 표현식을 정의하세요:
[runners.kubernetes]
...
namespace_overwrite_allowed = "ci-.*"
Kubernetes 클러스터의 내결함성
- 도입됨 GitLab Runner 17.5에.
GitLab Runner의 내결함성 기능은 러너 관리자가 재시작할 때 고아 리소스(예: Kubernetes 포드)와 실행 중
상태에 있는 작업을 방지하는 데 도움이 됩니다.
다음 단계는 일반적인 조건 하에서 작업 실행이 어떻게 작동하는지를 설명합니다.
러너 관리자는:
-
GitLab에서 작업을 수신합니다.
-
Kubernetes에서 작업 포드를 생성합니다.
-
작업 포드에서 실행될 명령을 보냅니다.
-
작업 로그 및 상태를 읽고, 정보를 GitLab에 다시 전송합니다.
그러면 GitLab은 UI를 새로 고칩니다.
Kubernetes에서 러너 관리자 포드를 호스팅하는 노드가 클러스터에서 CI/CD 작업을 조정할 때 제거되면, 러너 포드는 고아 상태가 됩니다.
그들은 다른 메커니즘에 의해 제거될 때까지 계속 실행됩니다.
새로운 러너 관리자는 활성 러너 포드와 관련된 CI/CD 작업에 접근할 수 없습니다.
결과적으로, 고아 러너 포드는 클러스터에서 계속 리소스를 소모합니다.
GitLab UI는 작업이 결국 구성된 타임아웃 때문에 실패할 때까지 작업 상태를 업데이트하지 않습니다.
내결함성 기능을 사용하면 GitLab Runner는 중단된 지점에서 작업을 다시 실행합니다.
GitLab Runner는 작업 및 각 작업의 실행 상태를 구성된 저장소에 저장합니다.
새로운 작업을 요청하기 전에, GitLab은 이미 실행 중인 작업이 있는지 저장소를 확인합니다.
내결함성 러너 관리자는:
-
실행자가
상태 저장 실행기
인 경우, 구성된 저장소를 생성합니다.-
저장소가 구성되지 않았지만 실행자가
상태 저장
인 경우,no-op
(작업 없음) 저장소가 사용됩니다.
no-op
저장소 덕분에 추가 논리 분기 없이 데이터 호출을 절약할 수 있습니다.store := NewNoopStore() if isStatefulExecutor := executor.(StatefulExecutor); isStatefulExecutor { store, _ = provider.GetStore(runnerConfig) }
-
-
작업을 평소와 같이 실행하지만, 주기적으로 또는 특정 이벤트 시 저장소에 기록합니다.
-
재시작 중에 저장소에서 실행 중인 작업을 확인합니다.
작업이 최근에 업데이트되지 않았다면, 러너는:
-
작업을 재개합니다.
-
작업 실행 시작 중에 러너가 수많은 작업 로그를 생성하므로 로그 중복을 방지하기 위해 모든 추적 로그 작성을 비활성화합니다.
-
먼저 Kubernetes 실행기에서
상태 메타데이터
를 복원합니다.type executorStateMetadata struct { // 실행자에 의해 생성된 비밀 Credentials *api.Secret `json:"credentials"` // 빌드 포드 Pod *api.Pod `json:"pod"` // 서비스 Services []api.Service `json:"services"` // 오프셋은 빌드 포드에서 작업 로그를 읽는 오프셋입니다 Offset int64 `json:"offset"` } // 이러한 리소스의 이름과 네임스페이스만 저장소에 직렬화됩니다 /* { credentials: { name: "", namespace: "" } pod: { name: "", namespace: "" } services: [{ name: "", namespace: "" }] offset: 0 } */
-
작업 처리를 위해
Executor
의Prepare
메서드를 호출합니다. -
추적 로그 작성을 다시 활성화하고 재개합니다.
-
Kubernetes 클러스터에 대한 전체 API 객체를 쿼리하는
StatefulExecutor
인터페이스의 일환으로Restore
메서드를 호출합니다.func (s *executor) Restore(ctx context.Context) error { s.state.Pod, _ = s.kubeClient.CoreV1().Pods(s.state.Pod.Namespace).Get(s.state.Pod.Name) s.state.Credentials, _ = s.kubeClient.CoreV1().Secrets(s.state.Credentials.Namespace).Get(s.state.Credentials.Name) // 서비스에 대해서도 동일하게 수행합니다 return nil }
-
일반적인
Run
메서드 대신StatefulExecutor
인터페이스의Resume
메서드를 호출합니다.
Resume
메서드는Pod
에 다시 연결하고 작업 추적 및 상태를 GitLab에 계속 전달합니다.
-
재시작 후, 새로운 작업 실행 메커니즘은 다음과 같이 작동합니다: