正式なドキュメントは英語版であり、この日本語訳はAI支援翻訳により作成された参考用のものです。日本語訳の一部の内容は人間によるレビューがまだ行われていないため、翻訳のタイミングにより英語版との間に差異が生じることがあります。最新かつ正確な情報については、英語版をご参照ください。

Kubernetes executor

  • プラン: Free、Premium、Ultimate
  • 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated

ビルドにKubernetesクラスターを使用する場合、Kubernetes executorを使用します。executorはKubernetesクラスターAPIを呼び出し、GitLab CIジョブごとにポッドを作成します。

Kubernetes executorは、ビルドを複数のステップに分割します:

  1. Prepare(準備): Kubernetesクラスターに対してポッドを作成します。これにより、ビルドに必要なコンテナと、実行するサービスが作成されます。
  2. Pre-build(ビルド前): クローン、キャッシュの復元、および前のステージからアーティファクトのダウンロードを実行します。このステップは、ポッドの一部である特別なコンテナで実行されます。
  3. ビルド: ユーザービルド。
  4. Post-build(ビルド後): キャッシュの作成、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オプションのKubernetesコンテキスト名。 kubectlの設定で使用します。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: thebearertokenfromanothernamespace

Runner APIの権限を設定する

コアAPIグループの権限を設定するには、GitLab Runner Helmチャートのvalues.ymlファイルを更新します。

次のいずれかの方法があります:

  • rbac.createtrueに設定します。
  • values.ymlファイルで、次の権限が付与されているサービスアカウントserviceAccount.name: <service_account_name>を指定します。
リソース動詞(オプションの機能/設定フラグ)
eventslist(print_pod_warning_events=true)、watch(FF_PRINT_POD_EVENTS=true
namespacescreate(kubernetes.NamespacePerJob=true)、delete(kubernetes.NamespacePerJob=true
podscreate、delete、get、list(Informerを使用 )、watch(Informerを使用FF_KUBERNETES_HONOR_ENTRYPOINT=trueFF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY=false
pods/attachcreate(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/execcreate、delete、get、patch
pods/logget(FF_KUBERNETES_HONOR_ENTRYPOINT=trueFF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY=falseFF_WAIT_FOR_POD_TO_BE_REACHABLE=true)、list(FF_KUBERNETES_HONOR_ENTRYPOINT=trueFF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGY=false
secretscreate、delete、get、update
serviceaccountsget
servicescreate、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: [""]
  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"

詳細情報:

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リクエスト上書き機能が無効になります。

メモリのリクエストと制限

設定説明
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サービスコンテナのメモリ割り当てリクエストを上書きできる最大量。空の場合、メモリリクエスト上書き機能が無効になります。

ヘルパーコンテナのメモリサイズに関する推奨事項

最適なパフォーマンスを得るには、ワークロードの要件に基づいてヘルパーコンテナのメモリ制限を設定します:

  • 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_escalationallowPrivilegeEscalationフラグを有効にしてすべてのコンテナを実行します。空の場合、コンテナSecurityContextallowPrivilegeEscalationフラグは定義されず、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が指定されている場合は無視されます。
contextkubectl設定で使用するKubernetesコンテキスト名(hostが指定されていない場合)。
dns_policyポッドの作成時に使用するDNSポリシー(nonedefaultcluster-firstcluster-first-with-host-net)を指定します。設定されていない場合は、Kubernetesのデフォルト(cluster-first)が使用されます。
dns_configポッドの作成時に使用するDNS設定を指定します。ポッドのDNS設定の使用についての詳細を参照してください。
helper_container_security_contextヘルパーコンテナのコンテナセキュリティコンテキストを設定します。セキュリティコンテキストの詳細を参照してください。
helper_image(上級者向け)リポジトリのクローンとアーティファクトのアップロードに使用されるデフォルトのヘルパーイメージを上書きします
helper_image_flavorヘルパーイメージのフレーバー (alpinealpine3.19alpine3.21、またはubuntu) を設定します。alpineがデフォルトです。alpineを使用する場合、これはalpine3.19と同じです。
host_aliasesすべてのコンテナに追加される追加のホスト名エイリアスのリスト。追加のホストエイリアスの使用についての詳細を参照してください。
image_pull_secretsプライベートレジストリからのDockerイメージのプルを認証するために使用されるKubernetes docker-registryシークレット名を含むアイテムの配列。
init_permissions_container_security_contextinit-permissionsコンテナのコンテナセキュリティコンテキストを設定します。セキュリティコンテキストの詳細を参照してください。
namespaceKubernetesポッドを実行するネームスペース。
namespace_per_jobジョブを個別のネームスペースに隔離します。有効にすると、namespacenamespace_overwrite_allowedは無視されます。
namespace_overwrite_allowedネームスペース上書き環境変数の内容を検証する正規表現(下記を参照)。空の場合、ネームスペース上書き機能が無効になります。
node_selectorstring=string(環境変数の場合はstring:string)形式のkey=valueペアのtable。これを設定すると、ポッドの作成は、すべてのkey=valueペアに一致するKubernetesノードに制限されます。ノードセレクターの使用についての詳細を参照してください。
node_tolerationsstring=string:string形式の"key=value" = "Effect"ペアのtable。これを設定すると、ポッドは、許容されるすべてのtaintまたはその一部を持つノードでスケジュールできます。環境変数設定では、1つのtolerationのみを指定できます。keyvalue、およびeffectは、Kubernetesポッドのtoleration設定の対応するフィールド名と一致します。
pod_annotationsstring=string形式のkey=valueペアのtable。このtableには、Runnerによって作成された各ビルドポッドに追加されるアノテーションのリストが含まれています。これらの値には、拡張用の環境変数を含めることができます。ポッドのアノテーションは、各ビルドで上書きできます。
pod_annotations_overwrite_allowedポッドアノテーション上書き環境変数の内容を検証する正規表現。空の場合、ポッドアノテーション上書き機能が無効になります。
pod_labelsstring=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_intervalRunnerがKubernetesポッドを作成した直後に、その状態を確認するためにポッドをポーリングする頻度(秒単位)(デフォルト= 3)。
poll_timeoutRunnerが作成したコンテナへの接続を試行する際に、タイムアウトになるまでの経過時間(秒単位)。クラスターが一度に処理できるビルドの数を上回るビルドをキューに入れる場合に、この設定を使用します(デフォルト= 180)。
cleanup_resources_timeoutジョブの完了後にKubernetesリソースをクリーンアップするための合計時間。サポートされている構文は1h30m300s10mです。デフォルトは5分(5m)です。
priority_class_nameポッドに設定する優先度クラスを指定します。設定されていない場合は、デフォルトの優先度クラスが使用されます。
privileged特権フラグを指定してコンテナを実行します。
pull_policyイメージプルポリシー(neverif-not-presentalways)を指定します。設定されていない場合は、クラスターのイメージのデフォルトプルポリシーが使用されます。複数のプルポリシーの設定方法と詳細については、プルポリシーの使用を参照してください。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_secondspod_termination_grace_period_secondsが優先され、これは非推奨になりました
volumes設定ファイルで設定され、ビルドコンテナにマウントされるボリュームのリスト。ボリュームの使用についての詳細を参照してください。
pod_specこれは実験的な設定です。Runnerマネージャーによって生成されるポッド仕様を、CIジョブの実行に使用されるポッドで設定された設定のリストで上書きします。Kubernetes Pod Specificationにリストされているすべてのプロパティを設定できます。詳細については、生成されたポッド仕様を上書きする(実験的機)を参照してください。
retry_limitKubernetes 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の権限を付与されたサービスアカウントが必要です。

設定例

次のサンプルは、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/podKubernetes 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でジョブをタイムアウトさせるには、activeDeadlineSecondsconfigured timeout + 1 secondに設定します。

FF_USE_POD_ACTIVE_DEADLINE_SECONDS機能フラグを有効にしてpod_termination_grace_period_secondsをゼロ以外の値に設定すると、CI/CDジョブポッドは即時に終了しません。ポッドのterminationGracePeriodsにより、有効期限が切れた場合にのみポッドが終了するようになります。

ポッドのtolerationを上書きする

Kubernetesポッドのtolerationを上書きするには、次のようにします:

  1. config.tomlファイルまたはHelm values.yamlファイルでCIジョブポッドのtolerationの上書きを有効にするには、node_tolerations_overwrite_allowedの正規表現を定義します。この正規表現は、名前がKUBERNETES_NODE_TOLERATIONS_で始まるCI変数の値を検証します。

    runners:
     ...
     config: |
       [[runners]]
         [runners.kubernetes]
           node_tolerations_overwrite_allowed = ".*"
  2. 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ポッドラベルを上書きするには、次の手順に従います:

  1. .config.yamlファイルでpod_labels_overwrite_allowedの正規表現を定義します。

  2. .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ポッドアノテーションを上書きするには、次の手順に従います:

  1. .config.yamlファイルでpod_annotations_overwrite_allowedの正規表現を定義します。

  2. .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_annotationspod_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_typeGitLab Runnerによって生成されたPodSpecオブジェクトに対して指定された変更を適用するためにRunnerが使用する戦略。指定できる値は、mergejsonstrategicです。

同じpod_spec設定でpatch_pathpatchを設定することはできません。このように設定するとエラーが発生します。

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.tomlpod_spec設定により、最終的なPodSpecオブジェクトの生成前に、このオブジェクトの値がoverwrites(上書き)されます。値が完全に上書きされるので、このパッチ戦略を使用する際には十分に注意してください。

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つの環境変数(env1env2)を持つ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_groupintいいえポッド内のすべてのコンテナに適用される特別な追加グループ。
run_as_groupintいいえコンテナプロセスのエントリポイントを実行するGID。
run_as_non_rootブール値いいえコンテナを非rootユーザーとして実行する必要があることを示します。
run_as_userintいいえコンテナプロセスのエントリポイントを実行するUID。
supplemental_groupsintリストいいえコンテナのプライマリGIDに加えて、各コンテナで最初に実行されるプロセスに適用されるグループのリスト。
selinux_typestringいいえポッド内のすべてのコンテナに適用される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_groupintいいえコンテナプロセスのエントリポイントを実行するGID。
run_as_non_rootブール値いいえコンテナを非rootユーザーとして実行する必要があることを示します。
run_as_userintいいえコンテナプロセスのエントリポイントを実行するUID。
capabilities.add文字列リストいいえコンテナの実行時に追加する機能。
capabilities.drop文字列リストいいえコンテナの実行時に削除する機能。
selinux_type文字列いいえコンテナプロセスに関連付けられているSELinuxタイプラベル。

次のconfig.tomlの例では、セキュリティコンテキスト設定により、次のようになります:

  • ポッドセキュリティコンテキストが設定されます。
  • ビルドコンテナとヘルパーコンテナのrun_as_userrun_as_groupが上書きされます。
  • すべてのサービスコンテナがポッドセキュリティコンテキストからrun_as_userrun_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-presentIfNotPresentジョブを実行するノードにイメージがまだ存在しない場合にのみ、イメージがプルされます。このプルポリシーを使用する前に、セキュリティに関する考慮事項を確認してください。
alwaysAlwaysジョブが実行されるたびにイメージがプルされます。
neverNeverイメージはプルされません。イメージがノードにすでに存在している必要があります。

コンテナ機能を指定する

コンテナで使用するKubernetes機能を指定できます。

コンテナ機能を指定するには、config.tomlcap_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のジョブ定義でrunAsUserrunAsGroup、またはimage:userを設定することはサポートされていません。代わりに、runAsUserNameFF_USE_ADVANCED_POD_SPEC_CONFIGURATIONを使用して設定することをお勧めします。

設定の優先順位

Runnerは、次の順序でユーザー設定を適用します:

ビルドおよびサービスコンテナの場合:

  1. コンテナセキュリティコンテキスト(run_as_user/run_as_group): 管理者がこの設定を制御します
  2. ポッドセキュリティコンテキスト(run_as_user/run_as_group): 管理者がポッドレベルのデフォルトを制御します
  3. ジョブ設定 (.gitlab-ci.yml): ユーザーがこの設定を制御します

ヘルパーコンテナの場合:

  1. ヘルパーコンテナセキュリティコンテキスト(run_as_user/run_as_group): 管理者がこの設定を制御します
  2. ポッドセキュリティコンテキスト(run_as_user/run_as_group): 管理者がポッドレベルのデフォルトを制御します

ジョブ設定は、セキュリティ分離のためにヘルパーコンテナには適用されません。

管理者は、セキュリティコンプライアンスのために、ユーザーが指定した値をオーバーライドできます。ヘルパーコンテナは、ジョブの仕様から分離されたままです。

Kubernetesの要件

Kubernetesには、ユーザーIDとグループIDに数値が必要です:

  • ユーザーIDとグループIDは整数である必要があります
  • SecurityContextrun_as_userrun_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を許可リストに対して検証します:

  • ルートユーザー/グループ(UID/GID 0): ジョブ設定には、常に明示的な許可リスト権限が必要です
  • 空 (allowed_users): ルート以外のジョブユーザーはすべて許可されます
  • 指定されたallowed_users: リストされているジョブユーザーのみが許可されます
  • 空 (allowed_groups): ルート以外のジョブグループはすべて許可されます
  • 指定されたallowed_groups: リストされているジョブグループのみが許可されます
  • セキュリティコンテキスト設定: 許可リストに対して検証されていません(管理者のオーバーライド)
[runners.kubernetes]
  allowed_users = ["1000", "65534"]
  allowed_groups = ["1001", "65534"]

コンテナの動作と優先順位

セキュリティコンテキスト設定は、次の優先順位(最高から最低)に従います:

  1. コンテナセキュリティコンテキスト
  2. ポッドセキュリティコンテキスト
  3. ジョブ設定
[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 = 1001
job:
  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エクゼキューターとの比較

機能Docker executorKubernetes executor
ユーザー形式ユーザー名またはUID(rootまたは1000数値のUIDのみ(1000
グループ形式ユーザーフィールドではサポートされていません数値GID(1000:1001
管理者のオーバーライド方法Runnerのuserフィールドコンテナとポッドのセキュリティコンテキスト
優先順位Runner > ジョブコンテナコンテキスト > ポッドコンテキスト > ジョブ
セキュリティ検証ユーザー名の許可リスト数値のUID/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)でルートが指定されている場合にのみ発生します。ジョブ設定からのルートユーザー(UID 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.ymlservicesセクションで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-account

CIの実行中に指定されたサービスアカウントのみが使用されるようにするには、次のいずれかの正規表現を定義します:

  • service_account_overwrite_allowed設定。
  • KUBERNETES_SERVICE_ACCOUNT_OVERWRITE_ALLOWED環境変数。

どちらも設定しない場合、上書きは無効になります。

RuntimeClassを設定します

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"

ビルドログとスクリプトのベースディレクトリを変更する

ビルドログとスクリプトのためにemptyDirボリュームがポッドにマウントされるディレクトリを変更できます。このディレクトリは次の操作に使用できます:

  • 変更されたイメージでジョブポッドを実行する。
  • 特権のないユーザーとして実行する。
  • SecurityContext設定をカスタマイズする。

ディレクトリを変更するには、次のようにします:

  • ビルドログの場合はlogs_base_dirを設定します。
  • ビルドスクリプトの場合はscripts_base_dirを設定します。

期待される値は、末尾のスラッシュがないベースディレクトリを表す文字列です(/tmp/mydir/exampleなど)。The directory must already exist(ディレクトリはすでに存在している必要があります)。

この値は、ビルドログおよびスクリプトのために生成されたパスの先頭に追加されます。次に例を示します:

  [[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/oskubernetes.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"

ノードセレクターの上書き

ノードセレクターを上書きするには、次の手順に従います:

  1. config.tomlファイルまたはHelm values.yamlファイルで、ノードセレクターの上書きを有効にします:

    runners:
     ...
     config: |
       [[runners]]
         [runners.kubernetes]
           node_selector_overwrite_allowed = ".*"
  2. .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 architecture
job:
  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"]

ネットワーキング

コンテナライフサイクルフックを設定する

コンテナライフサイクルフックを使用して、対応するライフサイクルフックの実行時にハンドラーに設定されているコードを実行します。

PreStopPostStartの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"

次の設定を使用して、各ライフサイクルフックを設定します:

オプション必須説明
execKubernetesLifecycleExecActionいいえExecは、実行するアクションを指定します。
http_getKubernetesLifecycleHTTPGetいいえHTTPGetは、実行するHTTPリクエストを指定します。
tcp_socketKubernetesLifecycleTcpSocketいいえTCPsocketは、TCPポートが関与するアクションを指定します。

KubernetesLifecycleExecAction

オプション必須説明
commandstringリストはいコンテナ内で実行するコマンドライン。

KubernetesLifecycleHTTPGet

オプション必須説明
portintはいコンテナでアクセスするポートの番号。
host文字列いいえ接続先のホスト名。デフォルトはポッドIPです(オプション)。
path文字列いいえHTTPサーバーでアクセスするパス(オプション)。
scheme文字列いいえホストへの接続に使用されるスキーム。デフォルトはHTTPです(オプション)。
http_headersKubernetesLifecycleHTTPGetHeaderリストいいえリクエストで設定するカスタムヘッダー(オプション)。

KubernetesLifecycleHTTPGetHeader

オプション必須説明
name文字列はいHTTPヘッダー名。
value文字列はいHTTPヘッダー値。

KubernetesLifecycleTcpSocket

オプション必須説明
portintはいコンテナでアクセスするポートの番号。
host文字列いいえ接続先のホスト名。デフォルトはポッドIPです(オプション)。

ポッドのDNS設定をする

ポッドのDNS設定をするには、次のオプションを使用します。

オプション必須説明
nameserversstringリストいいえポッドのDNSサーバーとして使用されるIPアドレスのリスト。
optionsKubernetesDNSConfigOptionいいえnameプロパティ(必須)とvalueプロパティ(オプション)を含めることができるオブジェクトのリスト(オプション)。
searchesstringリストいいえポッドでのホスト名検索に使用する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アドレス。
Hostnamesstringリストはい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フォルダーに解凍されます。

ボリュームタイプを設定する

次のボリュームタイプをマウントできます:

  • hostPath
  • persistentVolumeClaim
  • configMap
  • secret
  • emptyDir
  • csi

複数のボリュームタイプを使用した設定の例を以下に示します:

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文字列いいえルートの代わりにボリューム内のサブパスをマウントします。
itemsmap[string]stringいいえ使用するconfigMapのキーのキーからパスへのマッピング。

configMapの各キーはファイルに変更され、マウントパスに保存されます。デフォルトでは次のようになります:

  • すべてのキーが含まれます。
  • configMapキーはファイル名として使用されます。
  • 値はファイルコンテンツに保存されます。

デフォルトのキーと値のストレージを変更するには、itemsオプションを使用します。itemsオプションを使用すると、only specified keys(指定されたキーのみ)がボリュームに追加され、他のキーはすべてスキップされます。

存在しないキーを使用すると、ジョブはポッド作成ステージで失敗します。

secretボリューム

Kubernetesクラスターで定義されているsecretを使用してコンテナにマウントすることをKubernetesに指示するには、secretボリュームを設定します。

config.tomlファイルで次のオプションを使用します:

オプション必須説明
name文字列はいボリュームの名前であり、使用する_シークレット_の名前。
mount_path文字列はいボリュームをマウントするコンテナ内のパス。
read_onlyブール値いいえボリュームを読み取り専用モードに設定します(デフォルトはfalseです)。
sub_path文字列いいえルートの代わりにボリューム内のサブパスをマウントします。
itemsmap[string]stringいいえ使用するconfigMapからのキーのキーからパスへのマッピング。

選択したsecretの各キーは、選択されているマウントパスに保存されているファイルに変更されます。デフォルトでは次のようになります:

  • すべてのキーが含まれます。
  • configMapキーはファイル名として使用されます。
  • 値はファイルコンテンツに保存されます。

デフォルトのキーと値のストレージを変更するには、itemsオプションを使用します。itemsオプションを使用すると、only specified keys(指定されたキーのみ)がボリュームに追加され、他のキーはすべてスキップされます。

存在しないキーを使用すると、ジョブはポッド作成ステージで失敗します。

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文字列いいえファイルシステムのタイプの名前を指定する文字列値(ext4xfsntfsなど)。
volume_attributesmap[string]stringいいえcsiボリュームの属性のキー値ペアマッピング。
sub_path文字列いいえルートの代わりにボリューム内のサブパスをマウントします。
read_onlyブール値いいえボリュームを読み取り専用モードに設定します(デフォルトはfalseです)。

サービスコンテナにボリュームをマウントする

ビルドコンテナに対して定義されたボリュームは、すべてのサービスコンテナにも自動的にマウントされます。この機能は、テストにかかる時間を短縮する目的でデータベースストレージをRAMにマウントするために、services_tmpfsの代替として使用できます。

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 Container Platformイメージを使用できます。あるいは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:dinddocker-in-dockerイメージとも呼ばれる)を実行する場合、コンテナを特権モードで実行する必要があります。これには潜在的なリスクが伴い、さらに問題が発生する可能性があります。

Dockerデーモンは、通常は.gitlab-ci.ymlserviceとして起動されるため、ポッド内で個別のコンテナとして実行されます。ポッド内のコンテナは、割り当てられたボリュームと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エグゼキューターで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_policyallowed_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オプションを使用します。次のエラーは自動的に再試行されます:

各エラーの再試行回数を制御するには、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" = 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

コンテナのエントリポイントに関する既知の問題

GitLab 15.1以降では、FF_KUBERNETES_HONOR_ENTRYPOINTが設定されている場合、Dockerイメージで定義されているエントリポイントがKubernetes executorで使用されます。

コンテナのエントリポイントには、次の既知の問題があります:

  • イメージのDockerfileでエントリポイントが定義されている場合は、有効なShellを開く必要があります。このようにしないとジョブがハングします。

    • Shellを開くために、システムはコマンドをビルドコンテナのargsとして渡します。
  • ファイルタイプのCI/CD変数は、エントリポイントの実行時にディスクに書き込まれません。ファイルは、スクリプト実行中にジョブでのみアクセス可能です。

  • 次のCI/CD変数は、エントリポイントではアクセスできません。before_scriptを使用して、スクリプトコマンドを実行する前にセットアップに変更を加えることができます:

GitLab Runner 17.4より前では次のような状況でした:

  • エントリポイントログは、ビルドのログに転送されませんでした。
  • kube execでのKubernetes executorでは、GitLab RunnerはエントリポイントがShellを開くまで待機しませんでした(上記の説明を参照)。

GitLab Runner 17.4以降では、エントリポイントログが転送されるようになりました。システムは、エントリポイントが実行され、Shellが起動するまで待ちます。これにより次のような影響があります:

  • FF_KUBERNETES_HONOR_ENTRYPOINTが設定されていて、イメージのエントリポイントがpoll_timeout(デフォルトは: 180秒)より長くかかる場合、ビルドは失敗します。エントリポイントの実行時間が長いことが予想される場合は、poll_timeoutの値(および場合によってはpoll_intervalの値)を調整する必要があります。
  • FF_KUBERNETES_HONOR_ENTRYPOINTFF_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ネームスペースのユーザーアクセスを制限します:

  • podsconfigmapsの場合:
    • get
    • watch
    • list
  • pods/execpods/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権限が付与されているKubernetes serviceAccountが使用されていること。

GitLab Runnerは、新しいサービスアカウントまたはシークレットが使用可能かどうかを確認します。この確認操作は5秒間隔で試行されます。

  • この機能はデフォルトでは無効になっています。この機能を有効にするには、resource_availability_check_max_attempts0以外の任意の値に設定します。設定した値によって、Runnerがサービスアカウントまたはシークレットを確認する回数が定義されます。

Kubernetesネームスペースを上書きする

前提要件:

  • GitLab Runner Helmチャートのvalues.ymlファイルで、rbac.clusterWideAccesstrueに設定されていること。
  • 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-.*"