Kubernetes executor
- プラン: Free、Premium、Ultimate
- 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated
ビルドにKubernetesクラスターを使用する場合、Kubernetes executorを使用します。executorはKubernetesクラスターAPIを呼び出し、GitLab CIジョブごとにポッドを作成します。
Kubernetes executorは、ビルドを複数のステップに分割します。
- 準備: Kubernetesクラスターに対してポッドを作成します。これにより、ビルドに必要なコンテナと、実行するサービスが作成されます。
- ビルド前: クローン、キャッシュの復元、および前のステージからアーティファクトのダウンロードを実行します。このステップは、ポッドの一部である特別なコンテナで実行されます。
- ビルド: ユーザービルド。
- ビルド後: キャッシュの作成、GitLabへのアーティファクトのアップロードを実行します。このステップでも、ポッドの一部である特別なコンテナを使用します。
RunnerがKubernetesポッドを作成する仕組み
次の図は、GitLabインスタンスとKubernetesクラスターでホストされているRunner間の相互作用を示しています。RunnerはKubernetes APIを呼び出して、クラスター上にポッドを作成します。
ポッドは、.gitlab-ci.ymlファイルまたはconfig.tomlファイルで定義されているserviceごとに次のコンテナで構成されます。
buildとして定義されているビルドコンテナ。helperとして定義されているヘルパーコンテナ。svc-Xとして定義されているサービスコンテナ。Xは[0-9]+です。
サービスとコンテナは同じKubernetesポッドで実行され、同じlocalhostアドレスを共有します。次の制限が適用されます。
- これらのサービスには、そのDNS名を介してアクセスできます。これよりも古いバージョンを使用する場合は、
localhostを使用する必要があります。 - 同じポートを使用する複数のサービスを使用することはできません。たとえば、2つの
mysqlサービスを同時に使用することはできません。
sequenceDiagram
participant G as GitLab instance
participant R as Runner on Kubernetes cluster
participant Kube as Kubernetes API
participant P as POD
R->>+G: Get a CI job.
loop
G-->R: ;
end
Note over R,G: POST /api/v4/jobs/request
G->>+R: CI job data.
R-->>-Kube: Create a POD to run the CI job.
Note over R,Kube: POST to Kube API
P->>+P: Execute job.
Note over P: CI build job = Prepare + Pre-build + Build + Post-build
P->>+G: Job logs
この図に示されている相互作用は、すべてのKubernetesクラスターで有効です。たとえば、主要パブリッククラウドプロバイダーでホストされているターンキーソリューションや、Self-Managed Kubernetesインストールなどです。
Kubernetes APIに接続する
Kubernetes APIに接続するには次のオプションを使用します。提供されるユーザーアカウントには、指定されたネームスペースでポッドを作成、リストし、ポッドにアタッチするための権限が必要です。
| オプション | 説明 |
|---|---|
host | オプションのKubernetes APIサーバーホストのURL(指定されていない場合は自動検出が試行されます)。 |
context | お使いのkubectl設定から使用するオプションのKubernetesコンテキスト名。hostを指定しない場合、このオプションを使用します。 |
cert_file | オプションのKubernetes APIサーバーユーザー認証証明書。 |
key_file | オプションのKubernetes APIサーバーユーザー認証秘密キー。 |
ca_file | オプションのKubernetes APIサーバーCA証明書。 |
KubernetesクラスターでGitLab Runnerを実行している場合に、GitLab RunnerがKubernetes APIを自動的に検出できるようにするには、これらのフィールドを省略します。
クラスターの外部でGitLab Runnerを実行している場合、これらの設定により、GitLab Runnerがクラスター上のKubernetes APIにアクセスできるようになります。hostを認証情報とともに指定するか、contextを使用してkubectl設定の特定のコンテキストを参照できます。
Kubernetes APIコールのベアラートークンを設定する
ポッドを作成するためにAPIコールのベアラートークンを設定するには、KUBERNETES_BEARER_TOKEN変数を使用します。これにより、プロジェクトのオーナーがプロジェクトのシークレット変数を使用してベアラートークンを指定できます。
ベアラートークンを指定する場合は、Host設定を指定する必要があります。
variables:
KUBERNETES_BEARER_TOKEN: thebearertokenfromanothernamespaceRunner APIの権限を設定する
コアAPIグループの権限を設定するには、GitLab Runner Helmチャートのvalues.ymlファイルを更新します。
次のいずれかの方法があります。
rbac.createをtrueに設定します。values.ymlファイルで、次の権限が付与されているサービスアカウントserviceAccount.name: <service_account_name>を指定します。
| リソース | 動詞(オプションの機能/設定フラグ) |
|---|---|
| events | list(print_pod_warning_events=true)、watch(FF_PRINT_POD_EVENTS=true) |
| namespaces | create(kubernetes.NamespacePerJob=true)、delete(kubernetes.NamespacePerJob=true) |
| poddisruptionbudgets | 作成 (pod_disruption_budget=true)、取得 (pod_disruption_budget=true) |
| pods | create、delete、get、list(Informerを使用)、watch(Informerを使用、FF_KUBERNETES_HONOR_ENTRYPOINT=true、FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY=false) |
| pods/attach | create(FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY=false)、delete(FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY=false)、get(FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY=false)、patch(FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY=false) |
| pods/exec | create、delete、get、patch |
| 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 |
必要な権限を持つロールを作成するには、次のYAMLロール定義を使用できます。
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: gitlab-runner
namespace: default
rules:
- apiGroups: [""]
resources: ["events"]
verbs:
- "list" # Required when `print_pod_warning_events=true`
- "watch" # Required when `FF_PRINT_POD_EVENTS=true`
- apiGroups: [""]
resources: ["namespaces"]
verbs:
- "create" # Required when `kubernetes.NamespacePerJob=true`
- "delete" # Required when `kubernetes.NamespacePerJob=true`
- apiGroups: ["policy"]
resources: ["poddisruptionbudgets"]
verbs:
- "create" # Required when `pod_disruption_budget=true`
- "get" # Required when `pod_disruption_budget=true`
- apiGroups: [""]
resources: ["pods"]
verbs:
- "create"
- "delete"
- "get"
- "list" # Required when using Informers (https://docs.gitlab.com/runner/executors/kubernetes/#informers)
- "watch" # Required when `FF_KUBERNETES_HONOR_ENTRYPOINT=true`, `FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY=false`, using Informers (https://docs.gitlab.com/runner/executors/kubernetes/#informers)
- apiGroups: [""]
resources: ["pods/attach"]
verbs:
- "create" # Required when `FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY=false`
- "delete" # Required when `FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY=false`
- "get" # Required when `FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY=false`
- "patch" # Required when `FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY=false`
- apiGroups: [""]
resources: ["pods/exec"]
verbs:
- "create"
- "delete"
- "get"
- "patch"
- apiGroups: [""]
resources: ["pods/log"]
verbs:
- "get" # Required when `FF_KUBERNETES_HONOR_ENTRYPOINT=true`, `FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY=false`, `FF_WAIT_FOR_POD_TO_BE_REACHABLE=true`
- "list" # Required when `FF_KUBERNETES_HONOR_ENTRYPOINT=true`, `FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY=false`
- apiGroups: [""]
resources: ["secrets"]
verbs:
- "create"
- "delete"
- "get"
- "update"
- apiGroups: [""]
resources: ["serviceaccounts"]
verbs:
- "get"
- apiGroups: [""]
resources: ["services"]
verbs:
- "create"
- "get"追加の詳細:
event権限はGitLab 16.2.1以降でのみ必要です。namespace権限は、namespace_per_jobを使用してネームスペースの分離を有効にする場合にのみ必要です。pods/log権限は、以下のいずれかのシナリオに該当する場合にのみ必要です:FF_KUBERNETES_HONOR_ENTRYPOINT機能フラグが有効になっている場合。FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY機能フラグが、CI_DEBUG_SERVICES変数がtrueに設定されている場合に無効になっていること。FF_WAIT_FOR_POD_TO_BE_REACHABLE機能フラグが有効になっている場合。
informer
GitLab Runner 17.9.0以降では、Kubernetes informerがビルドポッドの変更を追跡します。これにより、executorが変更をより迅速に検出できるようになります。
informerには、podsに対するlist権限とwatch権限が必要です。executorがビルドを開始すると、Kubernetes APIで権限が確認されます。すべての権限が付与されている場合、executorはinformerを使用します。いずれかの権限がない場合には、GitLab Runnerは警告をログに記録します。ビルドは続行され、以前のメカニズムを使用してビルドポッドの状態と変更を追跡します。
設定
Kubernetes executorを設定するには、config.tomlファイルで次の設定を使用します。
CPUリクエストと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リクエスト上書き機能が無効になります。 |
pod_cpu_limit | ビルドポッドに割り当てられたCPU割り当て。 |
pod_cpu_limit_overwrite_max_allowed | ビルドポッドに書き込み可能なCPU割り当ての最大量。空の場合、CPU制限上書き機能が無効になります。 |
pod_cpu_request | ビルドポッドにリクエストされたCPU割り当て。 |
pod_cpu_request_overwrite_max_allowed | ビルドポッドに書き込み可能なCPU割り当てリクエストの最大量。空の場合、CPUリクエスト上書き機能が無効になります。 |
ポッドレベルのリソース仕様は、Kubernetes v1.32でアルファ機能として導入され、Kubernetes v1.34でベータ版に移行しました。
メモリのリクエストと制限
| 設定 | 説明 |
|---|---|
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 | サービスコンテナのメモリ割り当てリクエストを上書きできる最大量。空の場合、メモリリクエスト上書き機能が無効になります。 |
pod_memory_limit | ビルドポッドに割り当てられたメモリ量。 |
pod_memory_limit_overwrite_max_allowed | ビルドポッドに書き込み可能なメモリ割り当ての最大量。空の場合、メモリ制限上書き機能が無効になります。 |
pod_memory_request | ビルドポッドにリクエストされたメモリ量。 |
pod_memory_request_overwrite_max_allowed | ビルドポッドに書き込み可能なメモリ割り当てリクエストの最大量。空の場合、メモリリクエスト上書き機能が無効になります。 |
ヘルパーコンテナのメモリサイジングの推奨事項
最適なパフォーマンスを得るには、ワークロードの要件に基づいてヘルパーコンテナのメモリ制限を設定します:
- Workloads with caching and artifact generation: 最低250 MiB
- Basic workloads without cache/artifacts: より低い制限 (128~200 MiB) でも機能する可能性があります。
Basic configuration example:
[[runners]]
executor = "kubernetes"
[runners.kubernetes]
helper_memory_limit = "250Mi"
helper_memory_request = "250Mi"
helper_memory_limit_overwrite_max_allowed = "1Gi"Job-specific memory overrides::
KUBERNETES_HELPER_MEMORY_LIMIT変数を使用して、管理者の変更を必要とせずに特定のジョブのメモリを調整します:
job_with_higher_helper_memory_limit:
variables:
KUBERNETES_HELPER_MEMORY_LIMIT: "512Mi"
script:このアプローチにより、デベロッパーはhelper_memory_limit_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 | ビルドを実行するノードを決定するアフィニティルールを指定します。アフィニティの使用についての詳細を参照してください。 |
allow_privilege_escalation | allowPrivilegeEscalationフラグを有効にしてすべてのコンテナを実行します。空の場合、コンテナSecurityContextのallowPrivilegeEscalationフラグは定義されず、Kubernetesはデフォルトの特権エスカレーション動作を使用できます。 |
allowed_groups | コンテナグループに指定できるグループIDの配列。存在しない場合、すべてのグループが許可されます。詳細については、コンテナユーザーとグループの設定を参照してください。 |
allowed_images | .gitlab-ci.ymlで指定できるイメージのワイルドカードリスト。この設定が存在しない場合は、すべてのイメージが許可されます(["*/*:*"]と同等)。詳細を参照してください。 |
allowed_pull_policies | .gitlab-ci.ymlファイルまたはconfig.tomlファイルで指定できるプルポリシーのリスト。 |
allowed_services | .gitlab-ci.ymlで指定できるサービスのワイルドカードリスト。この設定が存在しない場合は、すべてのイメージが許可されます(["*/*:*"]と同等)。詳細を参照してください。 |
allowed_users | コンテナユーザーに指定できるユーザーIDの配列。存在しない場合、すべてのユーザーが許可されます。詳細については、コンテナユーザーとグループの設定を参照してください。 |
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 | ジョブの完了後、ポッドが正常に終了するまでの秒数。この期間を過ぎると、プロセスはkill(強制終了)シグナルによって強制的に停止します。terminationGracePeriodSecondsが指定されている場合は無視されます。 |
context | kubectl設定から使用するKubernetesコンテキスト名 (hostが指定されていない場合)。 |
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.21、またはubuntu) を設定します。alpineがデフォルトです。alpineを使用する場合、これはalpine3.21と同じです。 |
host_aliases | すべてのコンテナに追加される追加のホスト名エイリアスのリスト。追加のホストエイリアスの使用についての詳細を参照してください。 |
image_pull_secrets | プライベートレジストリからのDockerイメージのプルを認証するために使用されるKubernetes docker-registryシークレット名を含むアイテムの配列。 |
init_permissions_container_security_context | init-permissionsコンテナのコンテナセキュリティコンテキストを設定します。セキュリティコンテキストの詳細を参照してください。 |
namespace | Kubernetesポッドを実行するネームスペース。 |
namespace_per_job | ジョブを個別のネームスペースに隔離します。有効にすると、namespaceとnamespace_overwrite_allowedは無視されます。 |
namespace_overwrite_allowed | ネームスペース上書き環境変数の内容を検証する正規表現(下記を参照)。空の場合、ネームスペース上書き機能が無効になります。 |
node_selector | string=string(環境変数の場合はstring:string)形式のkey=valueペアのtable。これを設定すると、ポッドの作成は、すべてのkey=valueペアに一致するKubernetesノードに制限されます。ノードセレクターの使用についての詳細を参照してください。 |
node_tolerations | string=string:string形式の"key=value" = "Effect"ペアのtable。これを設定すると、ポッドは、許容されるすべてのtaintまたはその一部を持つノードでスケジュールできます。環境変数設定では、1つのtolerationのみを指定できます。key、value、およびeffectは、Kubernetesポッドのtoleration設定の対応するフィールド名と一致します。 |
pod_annotations | string=string形式のkey=valueペアのtable。このtableには、Runnerによって作成された各ビルドポッドに追加されるアノテーションのリストが含まれています。これらの値には、拡張用の環境変数を含めることができます。ポッドのアノテーションは、各ビルドで上書きできます。 |
pod_annotations_overwrite_allowed | ポッドアノテーション上書き環境変数の内容を検証する正規表現。空の場合、ポッドアノテーション上書き機能が無効になります。 |
pod_labels | string=string形式のkey=valueペアのtable。このtableには、Runnerによって作成された各ビルドポッドに追加されるラベルのリストが含まれています。これらの値には、拡張用の環境変数を含めることができます。各ビルドでポッドラベルを上書きするには、pod_labels_overwrite_allowedを使用します。 |
pod_labels_overwrite_allowed | ポッドラベル上書き環境変数の内容を検証する正規表現。空の場合、ポッドラベルの上書き機能が無効になります。runner.gitlab.comラベルネームスペースのポッドラベルは上書きできないことに注意してください。 |
pod_security_context | 設定ファイルで設定されている場合、これによりビルドポッドのポッドセキュリティコンテキストが設定されます。セキュリティコンテキストの詳細を参照してください。 |
pod_termination_grace_period_seconds | ポッドが正常に終了するまでの秒数を決定するポッドレベルの設定です。この期間を過ぎると、プロセスはkill(強制終了)シグナルによって強制的に停止します。terminationGracePeriodSecondsが指定されている場合は無視されます。 |
poll_interval | RunnerがKubernetesポッドを作成した直後に、その状態を確認するためにポッドをポーリングする頻度(秒単位)(デフォルト= 3)。 |
poll_timeout | Runnerが作成したコンテナへの接続を試行する際に、タイムアウトになるまでの経過時間(秒単位)。クラスターが一度に処理できるビルドの数を上回るビルドをキューに入れる場合に、この設定を使用します(デフォルト= 180)。 |
cleanup_resources_timeout | ジョブの完了後にKubernetesリソースをクリーンアップするための合計時間。サポートされている構文は1h30m、300s、10mです。デフォルトは5分(5m)です。 |
priority_class_name | ポッドに設定する優先度クラスを指定します。設定されていない場合は、デフォルトの優先度クラスが使用されます。 |
privileged | 特権フラグを指定してコンテナを実行します。 |
pull_policy | イメージプルポリシー(never、if-not-present、always)を指定します。設定されていない場合は、クラスターのイメージのデフォルトプルポリシーが使用されます。複数のプルポリシーの設定方法と詳細については、プルポリシーの使用を参照してください。if-not-presentおよびneverのセキュリティに関する考慮事項も参照してください。プルポリシーを制限することもできます。 |
resource_availability_check_max_attempts | 設定されたリソース(サービスアカウントとプルシークレット)が使用可能であるかどうかを確認する操作の最大試行回数。この回数を超えると試行されなくなります。各試行の間隔は5秒です。準備ステップでのリソースチェックについての詳細を参照してください。 |
runtime_class_name | 作成されたすべてのポッドに使用するランタイムクラス。クラスターでこの機能がサポートされていない場合、ジョブは終了または失敗します。 |
service_container_security_context | サービスコンテナのコンテナセキュリティコンテキストを設定します。セキュリティコンテキストの詳細を参照してください。 |
scheduler_name | ビルドポッドのスケジュールに使用するスケジューラ。 |
service_account | ジョブ/executorポッドがKubernetes APIと通信するために使用するデフォルトのサービスアカウント。 |
service_account_overwrite_allowed | サービスアカウント上書き環境変数の内容を検証する正規表現。空の場合、サービスアカウント上書き機能が無効になります。 |
services | サイドカーパターンを使用してビルドコンテナにアタッチされているサービスのリスト。サービスの使用についての詳細を参照してください。 |
use_service_account_image_pull_secrets | 有効にすると、executorによって作成されるポッドにimagePullSecretsが含まれなくなります。これにより、ポッドはサービスアカウントのimagePullSecrets(設定されている場合)を使用して作成されます。 |
terminationGracePeriodSeconds | ポッドで実行されているプロセスに自動終了シグナルが送信された時点から、プロセスがkill(強制終了)シグナルで強制的に停止されるまでの期間。cleanup_grace_period_secondsとpod_termination_grace_period_secondsが優先され、これは非推奨になりました。 |
volumes | 設定ファイルで設定され、ビルドコンテナにマウントされるボリュームのリスト。ボリュームの使用についての詳細を参照してください。 |
pod_spec | これは実験的な設定です。Runnerマネージャーによって生成されるポッド仕様を、CIジョブの実行に使用されるポッドで設定された設定のリストで上書きします。Kubernetes Pod Specificationにリストされているすべてのプロパティを設定できます。詳細については、生成されたポッド仕様を上書きする(実験的機)を参照してください。 |
retry_limit | Kubernetes APIとの通信を試行する操作の最大回数。各試行の間の再試行間隔は、バックオフアルゴリズムに基づき、500ミリ秒から始まります。 |
retry_backoff_max | 各試行で到達する再試行間隔のカスタム最大バックオフ値(ミリ秒単位)。デフォルト値は2000ミリ秒で、500ミリ秒未満の値にすることはできません。各試行で到達するデフォルトの最大試行間隔は2秒です。これはretry_backoff_maxを使用してカスタマイズできます。 |
retry_limits | 各リクエストエラーの再試行回数。 |
logs_base_dir | ビルドログを保存するために生成されたパスの前に付加されるベースディレクトリ。詳細については、ビルドログとスクリプトのベースディレクトリを変更するを参照してください。 |
scripts_base_dir | ビルドスクリプトを保存するために生成されたパスの前に付加されるベースディレクトリ。詳細については、ビルドログとスクリプトのベースディレクトリを変更するを参照してください。 |
print_pod_warning_events | 有効にすると、ジョブ失敗時に、ポッドに関連付けられているすべての警告イベントがこの機能により取得されます。この機能はデフォルトで有効になっており、少なくともevents: listの権限を付与されたサービスアカウントが必要です。 |
pod_disruption_budget | 有効にすると、ジョブポッドごとにPodDisruptionBudgetが作成され、ノードのドレインやクラスターのアップグレードなどの自主的な中断中の退去を防ぎます。デフォルトでは無効になっています。poddisruptionbudgets権限を持つサービスアカウントが必要です。 |
設定例
次のサンプルは、Kubernetes executorの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" = ""executorサービスアカウントを設定する
executorサービスアカウントを設定するには、KUBERNETES_SERVICE_ACCOUNT環境変数を設定するか、--kubernetes-service-accountフラグを使用します。
ポッドとコンテナ
ジョブの実行方法を制御するようにポッドとコンテナを設定できます。
ジョブポッドのデフォルトのラベル
これらのラベルをRunnerの設定または.gitlab-ci.ymlファイルでオーバーライドすることはできません。runner.gitlab.comネームスペースでラベルを設定または変更する操作は無視され、デバッグメッセージとして記録されます。
| キー | 説明 |
|---|---|
project.runner.gitlab.com/id | プロジェクトのID。GitLabインスタンスのすべてのプロジェクトで一意のIDです。 |
project.runner.gitlab.com/name | プロジェクトの名前。 |
project.runner.gitlab.com/namespace-id | プロジェクトのネームスペースのID。 |
project.runner.gitlab.com/namespace | プロジェクトのネームスペースの名前。 |
project.runner.gitlab.com/root-namespace | プロジェクトのルートネームスペースのID。たとえば/gitlab-org/group-a/subgroup-a/projectの場合、ルートネームスペースはgitlab-orgです。 |
manager.runner.gitlab.com/name | このジョブを起動したRunner設定の名前。 |
manager.runner.gitlab.com/id-short | ジョブを起動したRunner設定のID。 |
job.runner.gitlab.com/pod | Kubernetes executorによって使用される内部ラベル。 |
ジョブポッドのデフォルトのアノテーション
ジョブを実行しているポッドには、デフォルトで次のアノテーションが追加されます。
| キー | 説明 |
|---|---|
job.runner.gitlab.com/id | ジョブの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 | ジョブの名前。 |
job.runner.gitlab.com/timeout | 時間の長さで指定する形式のジョブ実行タイムアウト。たとえば、2h3m0.5sなどです。 |
project.runner.gitlab.com/id | ジョブのプロジェクトID。 |
デフォルトのアノテーションを上書きするには、GitLab Runner設定でpod_annotationsを使用します。各CI/CDジョブのアノテーションは、.gitlab-ci.ymlファイルで上書きすることもできます。
ポッドのライフサイクル
ポッドのライフサイクルは、次の影響を受ける可能性があります。
TOML設定ファイルでのpod_termination_grace_period_secondsプロパティの設定。ポッドで実行されているプロセスは、TERMシグナルの送信後に指定された期間にわたって実行できます。この期間が経過してもポッドが正常に終了しない場合は、kill(強制終了)シグナルが送信されます。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をゼロ以外の値に設定した場合、CI/CDジョブポッドはすぐに終了しません。ポッドのterminationGracePeriodsにより、有効期限が切れた場合にのみポッドが終了するようになります。
ジョブポッドを退去から保護する
ノードドレインやクラスターアップグレードなどの自主的な中断からジョブポッドを保護するには、pod_disruption_budgetオプションを有効にします。
これを有効にすると、ジョブポッドごとにminAvailable: 1のPodDisruptionBudgetが作成されます。このアクションは、自主的な中断中にKubernetesの退去APIがポッドを退去させるのを防ぎます。
[runners.kubernetes]
pod_disruption_budget = truePodDisruptionBudget:
- Kubernetesオーナー参照によってジョブポッドが削除されると、自動的に削除されます。
- ノード障害やメモリ不足による強制終了などの偶発的な中断からは保護しません。
- 追加のRBAC権限が必要です。詳細については、Runner API権限の設定を参照してください。
PodDisruptionBudgetを有効にすると、ジョブの実行中にノードのドレインがハングする可能性があります。クラスターのアップグレード戦略が、潜在的なノードドレインの遅延を考慮しているか、またはジョブタイムアウトを使用してジョブの実行時間を制限するようにしてください。
ポッドのtolerationを上書きする
Kubernetesポッドのtolerationを上書きするには、次のようにします。
config.tomlファイルまたはHelmvalues.yamlファイルでCIジョブポッドのtolerationの上書きを有効にするには、node_tolerations_overwrite_allowedの正規表現を定義します。この正規表現は、名前がKUBERNETES_NODE_TOLERATIONS_で始まるCI変数の値を検証します。runners: ... config: | [[runners]] [runners.kubernetes] node_tolerations_overwrite_allowed = ".*"CIジョブポッドtolerationを上書きするため、
.gitlab-ci.ymlファイルで1つ以上の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: '' # tolerate all taints
ポッドラベルを上書きする
各CI/CDジョブのKubernetesポッドラベルを上書きするには、次の手順に従います。
.config.yamlファイルでpod_labels_overwrite_allowedの正規表現を定義します。.gitlab-ci.ymlファイルで、値key=valueを持つKUBERNETES_POD_LABELS_*変数を設定します。ポッドラベルはkey=valueで上書きされます。複数の値を適用できます。variables: KUBERNETES_POD_LABELS_1: "Key1=Val1" KUBERNETES_POD_LABELS_2: "Key2=Val2" KUBERNETES_POD_LABELS_3: "Key3=Val3"
runner.gitlab.comネームスペースのラベルは読み取り専用です。GitLabは、これらのGitLab内部ラベルの追加、変更、または削除の試行操作をすべて無視します。
ポッドアノテーションを上書きする
各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]]
# usual configuration
executor = "kubernetes"
[runners.kubernetes]
image = "alpine"
pod_annotations_overwrite_allowed = ".*"
[runners.kubernetes.pod_annotations]
"Key1" = "Val1"
"Key2" = "Val2"
"Key3" = "Val3"
"Key4" = "Val4"生成されたポッド仕様を上書きする
- ステータス: ベータ版
この機能はベータ版です。本番環境のクラスターで使用する前に、テストKubernetesクラスターでこの機能を使用することを強くお勧めします。この機能を使用するには、FF_USE_ADVANCED_POD_SPEC_CONFIGURATION機能フラグを有効にする必要があります。
機能が一般提供される前にフィードバックを追加するには、イシュー556286にコメントを残してください。
Runnerマネージャーによって生成されたPodSpecを変更するには、config.tomlファイルでpod_spec設定を使用します。
Runnerオペレーター固有の設定については、パッチ構造を参照してください。
pod_spec設定により次のようになります。
- 生成されたポッド仕様のフィールドを上書きして補完します。
config.tomlの[runners.kubernetes]で設定された可能性のある設定値を上書きします。
複数のpod_spec設定を指定できます。
| 設定 | 説明 |
|---|---|
name | カスタムpod_specに付けられた名前。 |
patch_path | 最終的なPodSpecオブジェクトの生成前に、このオブジェクトに適用する変更を定義するファイルのパス。このファイルはJSONまたはYAMLファイルである必要があります。 |
patch | 最終的なPodSpecオブジェクトの生成前にこのオブジェクトに適用する必要がある変更を記述するJSONまたはYAML形式の文字列。 |
patch_type | GitLab Runnerによって生成されたPodSpecオブジェクトに対して指定された変更を適用するためにRunnerが使用する戦略。指定できる値は、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には、2つの環境変数(env1とenv2)を持つ1つのコンテナ(build)のみが含まれています。上記の例では、次のようになるために関連するCIジョブが失敗します。
helperコンテナ仕様が削除されます。buildコンテナ仕様は、GitLab Runnerによって設定された必要なすべての設定を失います。
ジョブの失敗を防ぐために、この例では、GitLab Runnerによって生成された未変更のプロパティがpod_specに含まれている必要があります。
JSONパッチ戦略
jsonパッチ戦略は、JSONパッチ仕様を使用してPodSpecのオブジェクトと配列の更新を制御します。arrayプロパティではこの戦略を使用できません。
jsonパッチ戦略を使用するpod_spec設定の例を以下に示します。この設定では、新しいkey: value pairが既存のnodeSelectorに追加されます。既存の値は上書きされません。
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パッチ戦略
この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をテストします。 - GitLab Runnerによって生成された仕様に対し、
pod_spec設定が悪影響を与えないことを確認します。 - 複雑なポッド仕様の更新には、
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を作成する
各ビルドジョブのPersistentVolumeClaimを作成するには、ポッド仕様機能を有効にする方法を確認してください。
Kubernetesでは、ポッドのライフサイクルにアタッチされた一時的なPersistentVolumeClaimを作成できます。このアプローチは、Kubernetesクラスターで動的プロビジョニングが有効になっている場合に機能します。各PVCは、新しいボリュームをリクエストできます。ボリュームはポッドのライフサイクルにも関連付けられています。
動的プロビジョニングを有効にした後で、一時的なPVCを作成するためにconfig.tomlを次のように変更できます。
[[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: <The Storage Class that will dynamically provision a Volume>
accessModes: [ ReadWriteOnce ]
resources:
requests:
storage: 1Gi
'''ポッドのセキュリティポリシーを設定する
ビルドポッドのセキュリティポリシーを設定するには、config.tomlでセキュリティコンテキストを設定します。
次のオプションを使用します。
| オプション | 型 | 必須 | 説明 |
|---|---|---|---|
fs_group | int | いいえ | ポッド内のすべてのコンテナに適用される特別な追加グループ。 |
run_as_group | int | いいえ | コンテナプロセスのエントリポイントを実行するGID。 |
run_as_non_root | ブール値 | いいえ | コンテナを非rootユーザーとして実行する必要があることを示します。 |
run_as_user | int | いいえ | コンテナプロセスのエントリポイントを実行するUID。 |
supplemental_groups | intリスト | いいえ | コンテナのプライマリGIDに加えて、各コンテナで最初に実行されるプロセスに適用されるグループのリスト。 |
selinux_type | string | いいえ | ポッド内のすべてのコンテナに適用されるSELinuxタイプラベル。 |
config.tomlのポッドセキュリティコンテキストの例を以下に示します。
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古いRunnerポッドを削除する
古いRunnerポッドがクリアされないことがあります。これは、Runnerマネージャーが誤ってシャットダウンされた場合に発生する可能性があります。
この状況に対処するには、GitLab Runner Pod Cleanupアプリケーションを使用して、古いポッドのクリーンアップをスケジュールできます。詳細については、以下を参照してください。
コンテナのセキュリティポリシーを設定する
ビルドポッド、ヘルパーポッド、またはサービスポッドのコンテナセキュリティポリシーを設定するため、config.toml executorでコンテナセキュリティコンテキストを設定します。
次のオプションを使用します。
| オプション | 型 | 必須 | 説明 |
|---|---|---|---|
run_as_group | int | いいえ | コンテナプロセスのエントリポイントを実行するGID。 |
run_as_non_root | ブール値 | いいえ | コンテナを非rootユーザーとして実行する必要があることを示します。 |
run_as_user | int | いいえ | コンテナプロセスのエントリポイントを実行するUID。 |
capabilities.add | 文字列リスト | いいえ | コンテナの実行時に追加する機能。 |
capabilities.drop | 文字列リスト | いいえ | コンテナの実行時に削除する機能。 |
selinux_type | 文字列 | いいえ | コンテナプロセスに関連付けられている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パラメータを使用して、1つまたは複数のプルポリシーを指定します。このポリシーは、イメージのフェッチと更新の方法を制御します。ビルドイメージ、ヘルパーイメージ、およびすべてのサービスに適用されます。
使用するポリシーを決定するには、プルポリシーに関するKubernetesのドキュメントを参照してください。
1つのプルポリシーの場合は次のようになります。
[runners.kubernetes]
pull_policy = "never"複数のプルポリシーの場合は次のようになります。
[runners.kubernetes]
# use multiple pull policies
pull_policy = ["always", "if-not-present"]複数のポリシーを定義すると、イメージが正常に取得されるまで各ポリシーが試行されます。たとえば[ always, if-not-present ]を使用する場合、一時的なレジストリの問題が原因でalwaysポリシーが失敗すると、ポリシーif-not-presentが使用されます。
失敗したプルを再試行するには、次のようにします。
[runners.kubernetes]
pull_policy = ["always", "always"]GitLabの命名規則はKubernetesの命名規則とは異なります。
| Runnerのプルポリシー | Kubernetesのプルポリシー | 説明 |
|---|---|---|
| なし | なし | Kubernetesによって指定されたデフォルトポリシーを使用します。 |
if-not-present | IfNotPresent | ジョブを実行するノードにイメージがまだ存在しない場合にのみ、イメージがプルされます。このプルポリシーを使用する前に、セキュリティに関する考慮事項を確認してください。 |
always | Always | ジョブが実行されるたびにイメージがプルされます。 |
never | Never | イメージはプルされません。イメージがノードにすでに存在している必要があります。 |
コンテナ機能を指定する
コンテナで使用するKubernetes機能を指定できます。
コンテナ機能を指定するには、config.tomlでcap_addオプションとcap_dropオプションを使用します。コンテナランタイムは、Dockerまたはこのコンテナのように、機能のデフォルトリストを定義することもできます。
Runnerがデフォルトで削除する機能のリストがあります。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を定義できます。このポリシーでは、特定の機能をデフォルトで許可、制限、または追加できます。これらのルールは、すべてのユーザー定義設定よりも優先されます。
コンテナユーザーとグループの設定
Kubernetesセキュリティコンテキスト設定を使用して、コンテナで実行されるユーザーとグループを設定します。管理者はコンテナのセキュリティを制御し、ジョブが特定のコンテナタイプにユーザーを指定できるようにします。
Windowsのジョブ定義でrunAsUser、runAsGroup、またはimage:userを設定することはサポートされていません。代わりにrunAsUserNameをFF_USE_ADVANCED_POD_SPEC_CONFIGURATIONを介して設定することをお勧めします。
設定の優先順位
Runnerはユーザー設定を次の順序で適用します:
ビルドおよびサービスコンテナの場合:
- コンテナセキュリティコンテキスト (
run_as_user/run_as_group): 管理者がこの設定を制御します。 - ポッドセキュリティコンテキスト (
run_as_user/run_as_group): 管理者はポッドレベルのデフォルトを制御します。 - ジョブ設定 (
.gitlab-ci.yml): ユーザーがこの設定を制御します。
ヘルパーコンテナの場合:
- ヘルパーコンテナセキュリティコンテキスト (
run_as_user/run_as_group): 管理者がこの設定を制御します。 - ポッドセキュリティコンテキスト (
run_as_user/run_as_group): 管理者はポッドレベルのデフォルトを制御します。
ジョブ設定は、セキュリティ分離のためのヘルパーコンテナには適用されません。
管理者は、セキュリティコンプライアンスのためにユーザーが指定した値をオーバーライドできます。ヘルパーコンテナはジョブ仕様から分離されたままです。
Kubernetesの要件
Kubernetesでは、ユーザーIDとグループIDに数値が必要です:
- ユーザーIDとグループIDは整数である必要があります。
SecurityContextはrun_as_userとrun_as_groupを使用し、数値のみを受け入れます。- ジョブ設定では、ユーザーのみの場合は"1000"を、ユーザーとグループの場合は"1000:1001"を使用します。
ユーザーおよびグループ設定のオーバーライド
ポッドおよびコンテナ固有のセキュリティコンテキストを使用して、ユーザーおよびグループ設定をオーバーライドします:
[[runners]]
name = "k8s-runner"
url = "https://gitlab.example.com"
executor = "kubernetes"
[runners.kubernetes]
allowed_users = ["1000", "1001", "65534"]
allowed_groups = ["1001", "65534"]
# Pod security context - provides defaults for all containers
[runners.kubernetes.pod_security_context]
run_as_user = 1500
run_as_group = 1500
# Build container security context - overrides pod context
[runners.kubernetes.build_container_security_context]
run_as_user = 2000
run_as_group = 2001
# Helper container security context - overrides pod context
[runners.kubernetes.helper_container_security_context]
run_as_user = 3000
run_as_group = 3001
# Service container security context - overrides pod context
[runners.kubernetes.service_container_security_context]
run_as_user = 4000
run_as_group = 4001この例では:
- ポッドセキュリティコンテキストは、特定の設定がないコンテナにデフォルト (1500:1500) を設定します。
- コンテナセキュリティコンテキストは、ポッドのデフォルトをオーバーライドします。
- ユーザー1500、2000、3000、および4000は
allowed_usersリストに含まれていませんが、これらの値は許可リスト検証をバイパスするため、セキュリティコンテキストでそれらを使用できます。 - この機能により、管理者はポッドとコンテナの両方のレベルで無制限のオーバーライド制御が可能になります。
各コンテナタイプを個別に設定できます。セキュリティコンテキスト設定は、ジョブ設定におけるユーザーの仕様よりも優先されます。
ジョブ設定でユーザーを指定する
ジョブはイメージ設定でユーザーを指定できます:
# Job with custom user
job:
image:
name: alpine:latest
kubernetes:
user: "1000"
script:
- whoami
- id
# Job with user and group
job_with_group:
image:
name: alpine:latest
kubernetes:
user: "1000:1001"
script:
- whoami
- id
# Job using environment variable
job_dynamic:
image:
name: alpine:latest
kubernetes:
user: "${CUSTOM_USER_ID}"
variables:
CUSTOM_USER_ID: "1000"
script:
- whoamiセキュリティ検証
Runnerは、ジョブレベルの設定のみの許可リストに対してユーザーIDとグループIDを検証します:
- ルートユーザー/グループ (固有識別子/GID 0): ジョブ設定には常に明示的な許可リスト権限が必要です。
- 空の
allowed_users: 非ルートジョブユーザーはすべて許可されます。 - 指定された
allowed_users: リストされたジョブユーザーのみが許可されます。 - 空の
allowed_groups: 非ルートジョブグループはすべて許可されます。 - 指定された
allowed_groups: リストされたジョブグループのみが許可されます。 - セキュリティコンテキスト設定: 許可リストに対して検証されません (管理者オーバーライド)
[runners.kubernetes]
allowed_users = ["1000", "65534"]
allowed_groups = ["1001", "65534"]コンテナの動作と優先順位
セキュリティコンテキスト設定は、次の優先順位 (最高から最低) に従います:
- コンテナセキュリティコンテキスト
- ポッドセキュリティコンテキスト
- ジョブ設定
[runners.kubernetes]
# Pod-level defaults
[runners.kubernetes.pod_security_context]
run_as_user = 1500
run_as_group = 1500
# Container-specific overrides
[runners.kubernetes.build_container_security_context]
run_as_user = 1000
run_as_group = 1001
[runners.kubernetes.helper_container_security_context]
run_as_user = 1000
run_as_group = 1001job:
image:
name: alpine:latest
kubernetes:
user: "2000:2001" # Ignored - container security context uses 1000:1001各コンテナタイプは、ポッドレベルのフォールバックを持つセキュリティコンテキスト設定を使用します:
- ビルドコンテナ: 最初に
build_container_security_contextを使用し、次にpod_security_contextを使用し、その次に.gitlab-ci.ymlからのジョブレベルのユーザー設定を使用します。 - ヘルパーコンテナ: 最初に
helper_container_security_contextを使用し、次にpod_security_contextを使用します。ジョブレベルのユーザー設定は継承しません。 - サービスコンテナ: 最初に
service_container_security_contextを使用し、次にpod_security_contextを使用し、その次にジョブレベルのユーザー設定を使用します。
このアプローチにより、各コンテナタイプのセキュリティ設定を詳細に制御できると同時に、ヘルパーコンテナをジョブ仕様から分離できます。
Docker executorとの比較
| 機能 | Docker executor | Kubernetes executor |
|---|---|---|
| ユーザー形式 | ユーザー名または固有識別子 (rootまたは1000) | 数値固有識別子のみ (1000) |
| グループ形式 | ユーザーフィールドではサポートされていません。 | 数値GID (1000:1001) |
| 管理者オーバーライド方法 | Runnerのuserフィールド | コンテナおよびポッドセキュリティコンテキスト |
| 優先順位 | Runner > ジョブ | コンテナコンテキスト > ポッドコンテキスト > ジョブ |
| セキュリティ検証 | ユーザー名許可リスト | 数値固有識別子/GID許可リスト |
| 管理者オーバーライド | サポート対象 | サポートされています (ポッドおよびコンテナレベル) |
| ヘルパーコンテナユーザー | ビルドコンテナと同じ | 独自のhelper_container_security_contextを使用 |
| ポッドレベルのデフォルト | 利用不可 | pod_security_context |
ユーザーとグループ設定のトラブルシューティングを行う
エラー: failed to parse UIDまたはfailed to parse GID
- ユーザーIDが数値であることを確認します:
"1000"であって"user"ではありません。 - 形式を確認します: ユーザーとグループに
"1000:1001" - 負の値は許可されていません。
エラー: user "1000" is not in the allowed list
このエラーは、ジョブレベルのユーザー設定 (.gitlab-ci.yml) の場合にのみ発生します。ユーザーをRunner設定のallowed_usersに追加するか、allowed_usersを削除して非ルートジョブユーザーを許可します。セキュリティコンテキストとポッドセキュリティコンテキストのユーザーは、許可リストに対して検証されません。
エラー: group "1001" is not in the allowed list
このエラーは、ジョブレベルのグループ設定 (.gitlab-ci.yml) の場合にのみ発生します。グループをRunner設定のallowed_groupsに追加するか、allowed_groupsを削除して非ルートジョブグループを許可します。セキュリティコンテキストとポッドセキュリティコンテキストのグループは、許可リストに対して検証されません。
エラー: user "0" is not in the allowed list (ルートユーザーがブロックされています)
このエラーは、ジョブ設定 (.gitlab-ci.yml) でルートが指定されている場合にのみ発生します。ジョブ設定のルートユーザー (固有識別子0) には明示的な権限が必要です。"0"をallowed_usersに追加します。または、セキュリティコンテキストまたはポッドセキュリティコンテキストを使用してルートユーザーを設定します: run_as_user = 0 (許可リスト検証をバイパスする)
コンテナが予期しないユーザーとして実行される
Runnerの設定がセキュリティコンテキストでジョブ設定をオーバーライドするかどうかを確認します (セキュリティコンテキストが常に優先されます)。ジョブ設定のみを使用している場合は、allowed_usersに目的のユーザーIDが含まれているかどうかを検証します。セキュリティコンテキストの値は許可リストに対して検証されず、管理者オーバーライド機能を提供します。
コンテナリソースを上書きする
各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"サービスのリストの定義
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で指定されているコンテナリソースを上書きするには、各サービスでvariables属性を使用します。
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-accountCIの実行中に指定されたサービスアカウントのみが使用されるようにするには、次のいずれかの正規表現を定義します。
service_account_overwrite_allowed設定。KUBERNETES_SERVICE_ACCOUNT_OVERWRITE_ALLOWED環境変数。
どちらも設定しない場合、上書きは無効になります。
RuntimeClassを設定する
runtime_class_nameを使用して、各ジョブコンテナのRuntimeClassを設定します。
RuntimeClass名を指定したが、クラスターで設定しなかった場合、またはこの機能がサポートされていない場合、executorはジョブの作成に失敗します。
concurrent = 1
check_interval = 30
[[runners]]
name = "myRunner"
url = "gitlab.example.com"
executor = "kubernetes"
[runners.kubernetes]
runtime_class_name = "myclass"ビルドログとスクリプトのベースディレクトリを変更する
ビルドログとスクリプトのために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ボリュームがマウントされます。
- ビルドログの場合はデフォルトの
/logs-${CI_PROJECT_ID}-${CI_JOB_ID}ではなく/tmp/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 executorを使用するGitLab Runnerは、それらのオペレーティングシステムでビルドを実行できます。
システムはヘルパーイメージのオペレーティングシステム、アーキテクチャ、およびWindowsカーネルバージョン(該当する場合)を判別します。次にこれらのパラメータを、ビルドの他の側面(使用するコンテナやイメージなど)に利用します。
次の図は、システムがこれらの詳細を検出する仕組みを示しています。
%%|fig-align: center
flowchart TB
init[<b>Initial defaults</b>:<br/>OS: linux</br>Arch: amd64]
hasAutoset{Configuration<br/><tt><a href="https://docs.gitlab.com/runner/configuration/advanced-configuration/">helper_image_autoset_arch_and_os</a> == true</tt>?}
setArch[<b>Update</b>:<br/>Arch: <i>same as runner</i>]
isWin{GitLab Runner runs on Windows?}
setWin[<b>Update</b>:<br/>OS: windows<br/>KernelVersion: <i>same as runner</i>]
hasNodeSel{<a href="https://docs.gitlab.com/runner/configuration/advanced-configuration/"><tt>node_selector</tt></a> configured<br/>in <tt>runners.kubernetes</tt> section?}
hasNodeSelOverride{<tt>node_selector</tt> configured<br/><a href="https://docs.gitlab.com/runner/executors/kubernetes/#overwrite-the-node-selector">as overwrite</a>?}
updateNodeSel[<b>Update from <tt>node_selector</tt></b> if set:<br/>OS: from <tt>kubernetes.io/os</tt><br/>Arch: from <tt>kubernetes.io/arch</tt><br/>KernelVersion: from <tt>node.kubernetes.io/windows-build</tt>]
updateNodeSelOverride[<b>Update from <tt>node_selector</tt> overwrites</b> if set:</br>OS: from <tt>kubernetes.io/os</tt><br/>Arch: from <tt>kubernetes.io/arch</tt><br/>KernelVersion: from <tt>node.kubernetes.io/windows-build</tt>]
result[final <b>OS</b>, <b>Arch</b>, <b>kernelVersion</b>]
init --> hasAutoset
hasAutoset -->|false | hasNodeSel
hasAutoset -->|true | setArch
setArch --> isWin
isWin -->|false | hasNodeSel
isWin -->|true | setWin
setWin --> hasNodeSel
hasNodeSel -->|false | hasNodeSelOverride
hasNodeSel -->|true | updateNodeSel
updateNodeSel --> hasNodeSelOverride
hasNodeSelOverride -->|false | result
hasNodeSelOverride -->|true | updateNodeSelOverride
updateNodeSelOverride --> result
以下に、ビルドのオペレーティングシステム、アーキテクチャ、およびWindowsカーネルバージョンの選択に影響を与える唯一のパラメータを示します。
helper_image_autoset_arch_and_os設定- 次の
kubernetes.io/os、kubernetes.io/arch、およびnode.kubernetes.io/windows-buildラベルセレクター:node_selector設定node_selector上書き
他のパラメータは、上記で説明した選択プロセスに影響を与えません。ただし、affinityなどのパラメータを使用して、ビルドがスケジュールされるノードを細かく制限できます。
ノード
ビルドを実行するノードを指定する
Kubernetesクラスター内のどのノードをビルドの実行に使用できるかを指定するには、node_selectorオプションを使用します。これは、string=string形式(環境変数の場合はstring:string)のkey=valueペアです。
Runnerは提供された情報を使用して、ビルドのオペレーティングシステムとアーキテクチャを判別します。これにより、正しいヘルパーイメージが使用されるようになります。デフォルトのオペレーティングシステムとアーキテクチャは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の例
Kubernetes for Windowsには特定の制限があります。プロセス分離を使用している場合は、node.kubernetes.io/windows-buildラベルを使用して特定のWindowsビルドバージョンも指定する必要があります。
[[runners]]
name = "myRunner"
url = "gitlab.example.com"
executor = "kubernetes"
# The FF_USE_POWERSHELL_PATH_RESOLVER feature flag has to be enabled for PowerShell
# to resolve paths for Windows correctly when Runner is operating in a Linux environment
# but targeting Windows nodes.
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ファイルで指定されています。
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=.*" # <--- allows overwrite of the architecturejob:
image: IMAGE_NAME
variables:
KUBERNETES_NODE_SELECTOR_ARCH: 'kubernetes.io/arch=amd64' # <--- select the architectureノードの関連性のリストを定義する
ビルド時にポッド仕様に追加するノードアフィニティのリストを定義します。
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"
]ポッドがスケジュールされるノードを定義する
他のポッドのラベルに基づいてポッドをスケジュールできるノードを制約するには、ポッドアフィニティとアンチアフィニティを使用します。
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"]ネットワーキング
コンテナライフサイクルフックを設定する
コンテナライフサイクルフックを使用して、対応するライフサイクルフックの実行時にハンドラーに設定されているコードを実行します。
PreStopとPostStartの2種類のフックを設定できます。それぞれのフックでは1つのハンドラータイプのみを設定できます。
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 | 文字列 | いいえ | 接続先のホスト名。デフォルトはポッドIPです(オプション)。 |
path | 文字列 | いいえ | HTTPサーバーでアクセスするパス(オプション)。 |
scheme | 文字列 | いいえ | ホストへの接続に使用されるスキーム。デフォルトはHTTPです(オプション)。 |
http_headers | KubernetesLifecycleHTTPGetHeaderリスト | いいえ | リクエストで設定するカスタムヘッダー(オプション)。 |
KubernetesLifecycleHTTPGetHeader
| オプション | 型 | 必須 | 説明 |
|---|---|---|---|
name | 文字列 | はい | HTTPヘッダー名。 |
value | 文字列 | はい | HTTPヘッダー値。 |
KubernetesLifecycleTcpSocket
| オプション | 型 | 必須 | 説明 |
|---|---|---|---|
port | int | はい | コンテナでアクセスするポートの番号。 |
host | 文字列 | いいえ | 接続先のホスト名。デフォルトはポッドIPです(オプション)。 |
ポッドのDNS設定をする
ポッドのDNS設定をするには、次のオプションを使用します。
| オプション | 型 | 必須 | 説明 |
|---|---|---|---|
nameservers | stringリスト | いいえ | ポッドのDNSサーバーとして使用されるIPアドレスのリスト。 |
options | KubernetesDNSConfigOption | いいえ | nameプロパティ(必須)とvalueプロパティ(オプション)を含めることができるオブジェクトのリスト(オプション)。 |
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 | 文字列 | はい | 設定オプションの名前。 |
value | *string | いいえ | 設定オプションの値。 |
削除される機能のデフォルトリスト
GitLab Runnerは、デフォルトで次の機能を削除します。
ユーザー定義のcap_addは、削除される機能のデフォルトリストよりも優先されます。デフォルトで削除される機能を追加する場合は、cap_addに追加します。
NET_RAW
ホストエイリアスを追加する
この機能は、Kubernetes 1.7以降で使用できます。
ホストエイリアスを設定して、コンテナ内の/etc/hostsファイルにエントリを追加するようにKubernetesに指示します。
次のオプションを使用します。
| オプション | 型 | 必須 | 説明 |
|---|---|---|---|
IP | 文字列 | はい | ホストをアタッチするIPアドレス。 |
Hostnames | stringリスト | はい | IPにアタッチされているホスト名エイリアスのリスト。 |
config.tomlファイルの設定例を次に示します。
concurrent = 4
[[runners]]
# usual configuration
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"]コマンドラインパラメータ--kubernetes-host_aliasesとJSONインプットを使用して、ホストエイリアスを設定することもできます。例:
gitlab-runner register --kubernetes-host_aliases '[{"ip":"192.168.1.100","hostnames":["myservice.local"]},{"ip":"192.168.1.101","hostnames":["otherservice.local"]}]'ボリューム
Kubernetes executorでキャッシュを使用する
キャッシュがKubernetes executorで使用されている場合、/cacheという名前のボリュームがポッドにマウントされます。ジョブの実行中にキャッシュされたデータが必要になると、Runnerはキャッシュされたデータが利用可能かどうかを確認します。キャッシュボリュームで圧縮ファイルが利用可能な場合、キャッシュされたデータが利用可能です。
キャッシュボリュームを設定するには、config.tomlファイルでcache_dir設定を使用します。
- 圧縮ファイルが利用可能な場合、圧縮ファイルはビルドフォルダーに展開され、ジョブで使用できるようになります。
- 利用できない場合、キャッシュされたデータは設定されているストレージからダウンロードされ、圧縮ファイルとして
cache dirに保存されます。次に、圧縮ファイルがbuildフォルダーに解凍されます。
ボリュームタイプを設定する
次のボリュームタイプをマウントできます。
hostPathpersistentVolumeClaimconfigMapsecretemptyDircsi
複数のボリュームタイプを使用した設定の例を以下に示します。
concurrent = 4
[[runners]]
# usual configuration
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ボリューム
コンテナ内の指定されたホストパスをマウントするようにKubernetesに指示するには、hostPathボリュームを設定します。
config.tomlファイルで次のオプションを使用します。
| オプション | 型 | 必須 | 説明 |
|---|---|---|---|
name | 文字列 | はい | ボリュームの名前。 |
mount_path | 文字列 | はい | コンテナ内でボリュームがマウントされるパス。 |
sub_path | 文字列 | いいえ | マウントされるボリューム内のサブパス(ルートではありません)。 |
host_path | 文字列 | いいえ | ボリュームとしてマウントされるホスト上のパス。値を指定しない場合、デフォルトではmount_pathと同じパスになります。 |
read_only | ブール値 | いいえ | ボリュームを読み取り専用モードに設定します。falseがデフォルトです。 |
mount_propagation | 文字列 | いいえ | コンテナ間でマウントされたボリュームを共有します。詳細については、マウントの伝搬を参照してください。 |
persistentVolumeClaimボリューム
Kubernetesクラスターで定義されているpersistentVolumeClaimを使用してコンテナにマウントすることをKubernetesに指示するには、persistentVolumeClaimボリュームを設定します。
config.tomlファイルで次のオプションを使用します。
| オプション | 型 | 必須 | 説明 |
|---|---|---|---|
name | 文字列 | はい | ボリュームの名前であり、使用するPersistentVolumeClaimの名前。変数をサポートしています。詳細については、並行処理ごとの永続的ビルドボリュームを参照してください。 |
mount_path | 文字列 | はい | ボリュームがマウントされるコンテナ内のパス。 |
read_only | ブール値 | いいえ | ボリュームを読み取り専用モードに設定します(デフォルトではfalseに設定されます)。 |
sub_path | 文字列 | いいえ | ルートの代わりにボリューム内のサブパスをマウントします。 |
mount_propagation | 文字列 | いいえ | ボリュームのマウント伝播モードを設定します。詳細については、Kubernetesのマウント伝播を参照してください。 |
configMapボリューム
Kubernetesクラスターで定義されているconfigMapを使用してコンテナにマウントすることをKubernetesに指示するには、configMapボリュームを設定します。
config.tomlで次のオプションを使用します。
| オプション | 型 | 必須 | 説明 |
|---|---|---|---|
name | 文字列 | はい | ボリュームの名前であり、使用するconfigMapの名前。 |
mount_path | 文字列 | はい | ボリュームがマウントされるコンテナ内のパス。 |
read_only | ブール値 | いいえ | ボリュームを読み取り専用モードに設定します(デフォルトではfalseに設定されます)。 |
sub_path | 文字列 | いいえ | ルートの代わりにボリューム内のサブパスをマウントします。 |
items | map[string]string | いいえ | 使用するconfigMapのキーのキーからパスへのマッピング。 |
configMapの各キーはファイルに変更され、マウントパスに保存されます。デフォルトでは次のようになります。
- すべてのキーが含まれます。
configMapキーはファイル名として使用されます。- 値はファイルコンテンツに保存されます。
デフォルトのキーと値のストレージを変更するには、itemsオプションを使用します。itemsオプションを使用すると、指定されたキーのみがボリュームに追加され、他のキーはすべてスキップされます。
存在しないキーを使用すると、ポッド作成ステージでジョブが失敗します。
secretボリューム
Kubernetesクラスターで定義されているsecretを使用してコンテナにマウントすることをKubernetesに指示するには、secretボリュームを設定します。
config.tomlファイルで次のオプションを使用します。
| オプション | 型 | 必須 | 説明 |
|---|---|---|---|
name | 文字列 | はい | ボリュームの名前であり、使用する_シークレット_の名前。 |
mount_path | 文字列 | はい | ボリュームをマウントするコンテナ内のパス。 |
read_only | ブール値 | いいえ | ボリュームを読み取り専用モードに設定します(デフォルトはfalseです)。 |
sub_path | 文字列 | いいえ | ルートの代わりにボリューム内のサブパスをマウントします。 |
items | map[string]string | いいえ | 使用するconfigMapからのキーのキーからパスへのマッピング。 |
選択したsecretの各キーは、選択されているマウントパスに保存されているファイルに変更されます。デフォルトでは次のようになります。
- すべてのキーが含まれます。
configMapキーはファイル名として使用されます。- 値はファイルコンテンツに保存されます。
デフォルトのキーと値のストレージを変更するには、itemsオプションを使用します。itemsオプションを使用すると、指定されたキーのみがボリュームに追加され、他のキーはすべてスキップされます。
存在しないキーを使用すると、ポッド作成ステージでジョブが失敗します。
emptyDirボリューム
コンテナに空のディレクトリをマウントするようにKubernetesに指示するには、emptyDirボリュームを設定します。
config.tomlファイルで次のオプションを使用します。
| オプション | 型 | 必須 | 説明 |
|---|---|---|---|
name | 文字列 | はい | ボリュームの名前。 |
mount_path | 文字列 | はい | ボリュームをマウントするコンテナ内のパス。 |
sub_path | 文字列 | いいえ | ルートの代わりにボリューム内のサブパスをマウントします。 |
medium | 文字列 | いいえ | “Memory"を指定するとtmpfsが提供されます。それ以外の場合は、デフォルトでノードディスクストレージにデフォルト設定されます(デフォルトは”")。 |
size_limit | 文字列 | いいえ | emptyDirボリュームに必要なローカルストレージの合計量。 |
csiボリューム
コンテナに任意のストレージシステムをマウントするために、カスタムcsiドライバーを使用するようにKubernetesに指示するには、Container Storage Interface(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 executorでのみ使用可能)の代替として使用できます。
config.tomlファイルの設定例を次に示します。
[[runners]]
# usual configuration
executor = "kubernetes"
[runners.kubernetes]
[[runners.kubernetes.volumes.empty_dir]]
name = "mysql-tmpfs"
mount_path = "/var/lib/mysql"
medium = "Memory"カスタムボリュームマウント
ジョブのビルドディレクトリを保存するには、設定されているbuilds_dir(デフォルトでは/builds)へのカスタムボリュームマウントを定義します。pvcボリュームを使用する場合、アクセスモードに基づいて、ジョブを1つのノードで実行するように制限されることがあります。
config.tomlファイルの設定例を次に示します。
concurrent = 4
[[runners]]
# usual configuration
executor = "kubernetes"
builds_dir = "/builds"
[runners.kubernetes]
[[runners.kubernetes.volumes.empty_dir]]
name = "repo"
mount_path = "/builds"
medium = "Memory"並行処理ごとの永続ビルドボリューム
Kubernetes CIジョブのビルドディレクトリは、デフォルトでは一時的です。(GIT_STRATEGY=fetchを機能させるために)ジョブ間でGitクローンを永続化する場合は、ビルドフォルダーに対する永続ボリュームクレームをマウントする必要があります。複数のジョブを同時実行できるため、ReadWriteManyボリュームを使用するか、同じRunner上で発生する可能性がある同時実行ジョブごとに1つのボリュームを用意する必要があります。後者の方がパフォーマンの向上を見込めます。このような設定の例を以下に示します。
concurrent = 4
[[runners]]
executor = "kubernetes"
builds_dir = "/mnt/builds"
[runners.kubernetes]
[[runners.kubernetes.volumes.pvc]]
# CI_CONCURRENT_ID identifies parallel jobs of the same runner.
name = "build-pvc-$CI_CONCURRENT_ID"
mount_path = "/mnt/builds"この例では、build-pvc-3に対するbuild-pvc-0という名前の永続ボリュームクレームを自分自身で作成します。Runnerのconcurrent設定で指定されている数だけ作成します。
ヘルパーイメージを使用する
セキュリティポリシーを設定したら、ヘルパーイメージがポリシーに準拠している必要があります。イメージはルートグループから特権を受け取らないため、ユーザーIDがルートグループの一部であることを確認する必要があります。
nonroot環境のみが必要な場合は、ヘルパーイメージの代わりにGitLab Runner UBI OpenShiftコンテナプラットフォームイメージを使用できます。あるいはGitLab Runner Helper UBI OpenShift Container Platformイメージを使用することもできます。
次の例では、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の公開
runners.kubernetes.volumes.host_pathオプションを使用してホストの/var/run/docker.sockをビルドコンテナに公開する場合には、リスクが伴います。本番環境のコンテナと同じクラスターでビルドを実行する場合は注意してください。ノードのコンテナは、ビルドコンテナからアクセスできます。
docker:dindを使用する
docker:dind(docker-in-dockerイメージとも呼ばれる)を実行する場合、コンテナを特権モードで実行する必要があります。これには潜在的なリスクが伴い、さらに問題が発生する可能性があります。
Dockerデーモンは、通常は.gitlab-ci.ymlでserviceとして起動されるため、ポッド内で個別のコンテナとして実行されます。ポッド内のコンテナは、割り当てられたボリュームとIPアドレスのみを共有します。このIPアドレスは、localhostと相互に通信するときに使用されます。docker:dindコンテナは/var/run/docker.sockを共有せず、dockerバイナリはデフォルトでそれを使用しようとします。
クライアントがTCPを使用してDockerデーモンと通信するように設定するには、もう一方のコンテナで、ビルドコンテナの環境変数を含めます。
- 非TLS接続の場合は
DOCKER_HOST=tcp://docker:2375。 - TLS接続の場合は
DOCKER_HOST=tcp://docker:2376。
Docker 19.03以降では、TLSはデフォルトで有効になっていますが、クライアントに証明書をマップする必要があります。Docker-in-Dockerの非TLS接続を有効にするか、証明書をマウントできます。詳細については、Docker executorとDocker-in-Dockerの使用を参照してください。
ホストカーネルの公開を防ぐ
docker:dindまたは/var/run/docker.sockを使用する場合、Dockerデーモンはホストマシンの基盤となるカーネルにアクセスできます。つまり、ポッドで設定されたlimitsは、Dockerイメージがビルドされるときには機能しません。Dockerデーモンは、Kubernetesによって起動されたDockerビルドコンテナに課せられた制限に関係なく、ノードの全容量をレポートします。
ビルドコンテナを特権モードで実行する場合、または/var/run/docker.sockが公開されている場合、ホストカーネルがビルドコンテナに公開される可能性があります。公開を最小限に抑えるには、node_selectorオプションでラベルを指定します。これにより、ノードにコンテナをデプロイする前に、ノードがラベルと一致することが保証されます。たとえばラベルrole=ciを指定すると、ビルドコンテナはラベルrole=ciが付けられたノードでのみ実行され、他のすべての本番サービスは他のノードで実行されます。
ビルドコンテナをさらに分離するには、ノードtaintを使用します。taintは、他のポッドに追加の設定を行うことなく、他のポッドがビルドポッドと同じノードでスケジュールされることを防ぎます。
Dockerイメージとサービスを制限する
ジョブの実行に使用される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-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の両方に含まれているプルポリシーだけがジョブによって使用されます。有効なプルポリシーは、pull_policyキーワードに含まれるポリシーをallowed_pull_policiesと比較することによって決定されます。GitLabでは、これら2つのポリシーリストの共通部分が使用されます。たとえば、pull_policyが["always", "if-not-present"]、allowed_pull_policiesが["if-not-present"]の場合、ジョブでは、両方のリストで定義されている唯一のプルポリシーであるif-not-presentだけが使用されます。- 既存の
pull_policyキーワードには、allowed_pull_policiesで指定されているプルポリシーが少なくとも1つ含まれている必要があります。pull_policyの値の中にallowed_pull_policiesと一致するものがない場合、ジョブは失敗します。
ジョブの実行
GitLab Runnerは、デフォルトでkube execの代わりにkube attachを使用します。これにより、不安定なネットワーク環境でジョブが途中で成功とマークされるなどの問題を回避できます。
レガシー実行戦略の削除の進捗については、イシュー#27976を参照してください。
Kubernetes APIへのリクエスト試行回数を設定する
デフォルトでは、Kubernetes executorは、試行が5回失敗すると、Kubernetes APIへの特定のリクエストを再試行します。遅延は、500ミリ秒のフロアと、デフォルト値が2秒のカスタマイズ可能な上限が設定されたバックオフアルゴリズムによって制御されます。再試行回数を設定するには、config.tomlファイルでretry_limitオプションを使用します。同様に、バックオフ上限にはretry_backoff_maxオプションを使用します。次のエラーは自動的に再試行されます。
error dialing backendTLS handshake timeoutread: connection timed outconnect: connection timed outTimeout occurredhttp2: client connection lostconnection refusedtls: internal errorio.unexpected EOFsyscall.ECONNRESETsyscall.ECONNREFUSEDsyscall.ECONNABORTEDsyscall.EPIPE
各エラーの再試行回数を制御するには、retry_limitsオプションを使用します。rety_limitsは、各エラーの再試行回数を個別に指定するものであり、エラーメッセージと再試行回数のマップです。エラーメッセージは、Kubernetes APIから返されるエラーメッセージのサブ文字列であることがあります。retry_limitsオプションはretry_limitオプションよりも優先されます。
たとえば、環境内のTLS関連のエラーの再試行回数を、デフォルトの5回ではなく10回にするには、retry_limitsオプションを設定します。
[[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" = 10exceeded quotaなどのまったく異なるエラーを20回再試行するには、次のようにします。
[[runners]]
name = "myRunner"
url = "https://gitlab.example.com/"
executor = "kubernetes"
[runners.kubernetes]
retry_limit = 5
[runners.kubernetes.retry_limits]
"exceeded quota" = 20コンテナのエントリポイントに関する既知の問題
GitLab 15.1以降では、FF_KUBERNETES_HONOR_ENTRYPOINTが設定されている場合、Dockerイメージで定義されたエントリポイントがKubernetes executorとともに使用されます。
コンテナのエントリポイントには、次の既知の問題があります。
イメージのDockerfileにエントリポイントが定義されている場合、有効なShellを開く必要があります。このようにしないとジョブがハングします。
- Shellを開くために、システムはコマンドをビルドコンテナの
argsとして渡します。
- Shellを開くために、システムはコマンドをビルドコンテナの
ファイルタイプのCI/CD変数は、エントリポイントの実行時にディスクに書き込まれません。ファイルは、スクリプト実行中にジョブでのみアクセス可能です。
次のCI/CD変数は、エントリポイントではアクセスできません。
before_scriptを使用して、スクリプトコマンドを実行する前にセットアップに変更を加えることができます。
GitLab Runner 17.4より前では次のような状況でした。
- エントリポイントログは、ビルドのログに転送されませんでした。
- Kubernetes executorと
kube execを使用した場合、GitLab RunnerはエントリポイントがShellを開くのを待機しませんでした (このセクションの以前の項目を参照)。
GitLab Runner 17.4以降では、エントリポイントログが転送されるようになりました。システムは、エントリポイントが実行され、Shellが起動するまで待ちます。これにより次のような影響があります。
FF_KUBERNETES_HONOR_ENTRYPOINTが設定されていて、イメージのエントリポイントがpoll_timeout(デフォルトは180秒)より長くかかる場合、ビルドは失敗します。エントリポイントの実行時間が長いことが予想される場合は、poll_timeoutの値(および場合によってはpoll_intervalの値)を調整する必要があります。FF_KUBERNETES_HONOR_ENTRYPOINTとFF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGYが設定されている場合、システムはビルドコンテナに起動プローブを追加し、エントリポイントがShellを起動するタイミングを認識します。カスタムエントリポイントが、指定されたargsを使用して想定されるShellを起動する場合、スタートアッププローブは自動的に解決されます。ただしargsで渡されたコマンドを使用せずにコンテナイメージがShellを起動する場合、エントリポイントは、ビルドディレクトリのルート内に.gitlab-startup-markerという名前のファイルを作成して、スタートアッププローブ自体を解決する必要があります。スタートアッププローブは、poll_intervalごとに.gitlab-startup-markerファイルを確認します。poll_timeoutの間にファイルが存在しない場合、ポッドは異常とみなされ、システムはビルドを中断します。
ジョブ変数へのアクセスを制限する
Kubernetes executorを使用する場合、Kubernetesクラスターへのアクセス権を持つユーザーは、ジョブで使用される変数を読み取ることができます。デフォルトでは、ジョブ変数は以下に保存されます。
- ポッドの環境セクション
ジョブ変数データへのアクセスを制限するには、ロールベースのアクセス制御(RBAC)を使用する必要があります。RBACを使用する場合、GitLab Runnerによって使用されるネームスペースにアクセスできるのはGitLab管理者のみです。
他のユーザーがGitLab Runnerネームスペースにアクセスする必要がある場合は、以下のverbsを設定して、GitLab Runnerネームスペースのユーザーアクセスを制限します。
podsとconfigmapsの場合getwatchlist
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"]準備ステップでのリソースチェック
前提条件:
image_pull_secretsまたはservice_accountが設定されていること。resource_availability_check_max_attemptsがゼロより大きい数値に設定されていること。getおよびlist権限が付与されているKubernetesserviceAccountが使用されていること。
GitLab Runnerは、新しいサービスアカウントまたはシークレットが使用可能かどうかを確認します。この確認操作は5秒間隔で試行されます。
- この機能はデフォルトで無効になっています。この機能を有効にするには、
resource_availability_check_max_attemptsを0以外の任意の値に設定します。設定した値によって、Runnerがサービスアカウントまたはシークレットを確認する回数が定義されます。
Kubernetesネームスペースを上書きする
前提条件:
- GitLab Runner Helmチャートの
values.ymlファイルで、rbac.clusterWideAccessがtrueに設定されていること。 - Runnerに、コアAPIグループで設定された権限が付与されていること。
Kubernetesネームスペースを上書きして、CIの目的でネームスペースを指定し、ポッドのカスタムセットをこのネームスペースにデプロイできます。CIのステージでコンテナ間のアクセスを有効にするために、Runnerによって起動されたポッドは、上書きされたネームスペース内にあります。
各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-.*"