Kubernetesエクゼキュータ

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

ワークフロー

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

  1. 準備:Kubernetesクラスタに対してポッドを作成します。これにより、ビルドとサービスの実行に必要なコンテナが作成されます。
  2. プリビルド:クローン、キャッシュの復元、以前のステージからのアーティファクトのダウンロードを行います。このステップは、ポッドの一部として特別なコンテナ上で実行されます。
  3. ビルド:ユーザービルド。
  4. ポストビルド:キャッシュを作成し、アーティファクトをGitLabにアップロードします。このステップでは、ポッドの一部として特別なコンテナも使用します。

RunnerがKubernetesポッドを作成する方法

以下の図は、GitLabインスタンスとKubernetesクラスタ上でホストされたRunnerの間の相互作用を表しています。RunnerはKubernetes APIを呼び出してクラスター上にポッドを作成します。

ポッドは、.gitlab-ci.yml またはconfig.toml ファイルで定義されたservice ごとに、以下のコンテナで構成されます:

  • build として定義されたビルドコンテナ。
  • helper として定義されるヘルパーコンテナ。
  • svc-X として定義されるサービスコンテナ。X[0-9]+

サービスとコンテナは同じKubernetesポッドで実行され、同じローカルホストアドレスを共有します。以下の制限が適用されます:

  • GitLab Runner 12.8とKubernetes 1.7以降では、サービスは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クラスターでも有効です。例えば、主要な公開クラウドプロバイダーでホストされているターンキーソリューションや、自己管理型のKubernetesインストールなどです。

Kubernetes APIへの接続

以下のオプションを使用して、Kubernetes APIに接続します。指定するユーザーアカウントには、指定したネームスペースでポッドを作成、リストアップ、アタッチする権限が必要です。

オプション説明
hostオプションのKubernetes apiserverホストURL(指定しない場合は自動検出を試みます)。
cert_fileオプションのKubernetes apiserverユーザー認証証明書。
key_fileオプションのKubernetes apiserverユーザー認証秘密鍵。
ca_fileオプションのKubernetes apiserver ca証明書。

KubernetesクラスターでGitLab Runnerを実行している場合は、GitLab RunnerがKubernetes APIを自動検出するように、これらのフィールドをすべて省略する必要があります。

GitLab Runnerをクラスターの外部で実行している場合は、これらの設定をそれぞれ設定し、GitLab Runnerがクラスター上のKubernetes APIにアクセスできるようにする必要があります。

コンフィギュレーション設定

Kubernetesエクゼキュータを設定するには、config.toml ファイルで以下の設定を使用します。

CPUリクエストと制限

設定説明
cpu_limitビルドコンテナに与えられるCPU割り当て。
cpu_limit_overwrite_max_allowedビルドコンテナに書き込めるCPU割り当ての上限。空の場合、cpu limit overwrite 機能を無効にします。
cpu_requestビルドコンテナに要求されるCPU割り当て。
cpu_request_overwrite_max_allowedビルドコンテナに対して CPU 割り当て要求を書き込める最大量。空の場合、CPU割り当て要求の上書き機能を無効にします。
helper_cpu_limitビルドヘルパーコンテナに与えられるCPU割り当て。
helper_cpu_limit_overwrite_max_allowedヘルパーコンテナに書き込める CPU 割当量の上限。空の場合、cpu limit overwrite 機能を無効にします。
helper_cpu_requestビルドヘルパーコンテナに要求されるCPU割り当て。
helper_cpu_request_overwrite_max_allowedヘルパーコンテナに対して CPU 割り当て要求を書き込める最大量。空の場合は、CPU 割り当て要求の上書き機能を無効にします。
service_cpu_limitビルドサービスコンテナに与えられるCPU割り当て。
service_cpu_limit_overwrite_max_allowedサービスコンテナに書き込めるCPU割り当ての上限。空の場合は、CPU制限の上書き機能を無効にします。
service_cpu_requestビルドサービスコンテナに要求されるCPU割り当て。
service_cpu_request_overwrite_max_allowedサービスコンテナに対して CPU 割り当て要求を書き込める最大量。空の場合、CPU 割り当て要求の上書き機能を無効にします。

メモリ要求と制限

設定説明
memory_limitコンテナを構築するために割り当てられたメモリ量。
memory_limit_overwrite_max_allowedビルド・コンテナに割り当てられるメモリの最大書き込み量。空の場合は、メモリ制限の上書き機能を無効にします。
memory_requestビルドコンテナに要求するメモリ量。
memory_request_overwrite_max_allowedビルド・コンテナにメモリ割り当て要求を書き込める最大量。空の場合は、メモリ要求の上書き機能を無効にします。
helper_memory_limitビルドヘルパーコンテナに割り当てられるメモリ量。
helper_memory_limit_overwrite_max_allowedヘルパーコンテナに書き込めるメモリ割り当ての最大量。空の場合は、メモリ制限の上書き機能を無効にします。
helper_memory_requestビルドヘルパーコンテナに要求されるメモリ量。
helper_memory_request_overwrite_max_allowedヘルパーコンテナ用にメモリ割り当て要求を書き込める最大量。空の場合は、メモリ要求の上書き機能を無効にします。
service_memory_limitサービスコンテナを構築するために割り当てられるメモリ量。
service_memory_limit_overwrite_max_allowedサービスコンテナ用に割り当てられるメモリの最大書き込み量。空の場合、メモリ制限の上書き機能を無効にします。
service_memory_requestビルド・サービス・コンテナに要求されるメモリ量。
service_memory_request_overwrite_max_allowedサービスコンテナに対してメモリ割り当て要求を書き込める最大量。空の場合は、メモリ要求の上書き機能を無効にします。

ストレージ要求と制限

設定説明
ephemeral_storage_limitビルドコンテナのエフェメラルストレージの上限。
ephemeral_storage_limit_overwrite_max_allowedビルド・コンテナのエフェメラル・ストレージ上限を上書きできる最大量。空の場合、エフェメラル・ストレージ・リミットの上書き機能は無効になります。
ephemeral_storage_requestビルドコンテナに与えられるエフェメラルストレージリクエスト。
ephemeral_storage_request_overwrite_max_allowedビルド・コンテナに対してエフェメラル・ストレージ・リクエストを上書きできる最大量。空の場合は、エフェメラル・ストレージ・リクエストの上書き機能を無効にします。
helper_ephemeral_storage_limitヘルパーコンテナに与えられるエフェメラルストレージの上限。
helper_ephemeral_storage_limit_overwrite_max_allowedヘルパーコンテナに対してエフェメラルストレージリミットを上書きできる最大量。空の場合は、エフェメラルストレージリクエストの上書き機能を無効にします。
helper_ephemeral_storage_requestヘルパーコンテナに与えるエフェメラルストレージリクエスト。
helper_ephemeral_storage_request_overwrite_max_allowedヘルパーコンテナに対してエフェメラルストレージリクエストを上書きできる最大量。空の場合は、エフェメラルストレージリクエストの上書き機能を無効にします。
service_ephemeral_storage_limitサービスコンテナに与えられるエフェメラルストレージの上限。
service_ephemeral_storage_limit_overwrite_max_allowedサービスコンテナに対してエフェメラルストレージリミットを上書きできる最大量。空の場合、エフェメラルストレージリクエストの上書き機能を無効にします。
service_ephemeral_storage_requestサービスコンテナに与えられるエフェメラルストレージリクエスト。
service_ephemeral_storage_request_overwrite_max_allowedサービスコンテナに対してエフェメラルストレージリクエストを上書きできる最大量。空の場合は、エフェメラル・ストレージ・リクエストの上書き機能を無効にします。

その他の設定config.toml

設定説明
affinityビルドを実行するノードを決定するアフィニティ・ルールを指定します。アフィニティの詳細については、こちらをご覧ください。
allow_privilege_escalation allowPrivilegeEscalation フラグを有効にして allowPrivilegeEscalationすべてのコンテナを実行します。allowPrivilegeEscalation 空の場合、 allowPrivilegeEscalationコンテナSecurityContext でフラグallowPrivilegeEscalation を定義 allowPrivilegeEscalationせず、Kubernetes がデフォルトの特権昇格動作を使用できるようにします。
allowed_images .gitlab-ci.yml で指定可能なイメージのワイルドカードリスト。存在しない場合、すべてのイメージが許可されます(["*/*:*"] と同等)。詳細を表示します。
allowed_pull_policies .gitlab-ci.yml ファイルまたはconfig.toml ファイルで指定できるプルポリシーのリスト。
allowed_services .gitlab-ci.yml で指定できるサービスのワイルドカードリスト。存在しない場合、すべての画像が許可されます(["*/*:*"] と同等)。詳細を表示します。
bearer_tokenビルドポッドの起動に使用されるデフォルトのベアラートークン。
bearer_token_overwrite_allowedプロジェクトがビルドポッドを作成する際に使用するベアラートークンを指定できるようにします。
build_container_security_contextビルドコンテナのコンテナセキュリティコンテキストを設定します。セキュリティコンテキストについての詳細はこちら
cap_addジョブポッドコンテナに追加するLinux機能を指定します。Kubernetes Executorのcapabilities設定について詳しくはこちら。
cap_dropジョブポッドコンテナから削除するLinux機能を指定します。Kubernetes executorのcapabilities設定の詳細はこちら。
cleanup_grace_period_secondsジョブが完了したとき、ポッドが優雅に終了するまでの秒数。この期間が経過すると、killシグナルでプロセスが強制的に停止されます。terminationGracePeriodSeconds が指定されている場合は無視されます。
dns_policyポッドの構築時に使用する DNS ポリシーを指定します:none default,cluster-first,cluster-first-with-host-net.設定されていない場合は、Kubernetesのデフォルト(cluster-first )が使用されます。
dns_configポッドの構築時に使用するDNS設定を指定します。ポッドのDNS設定の使い方についてはこちらをご覧ください。
helper_container_security_contextヘルパーコンテナのコンテナセキュリティコンテキストを設定します。セキュリティコンテキストについての詳細はこちら。
helper_image(詳細) リポジトリのクローンやアーティファクトのアップロードに使用するデフォルトのヘルパーイメージを上書きします。
helper_image_flavorヘルパーイメージのフレーバー (alpine,alpine3.15,alpine3.16,alpine3.17,alpine3.18, またはubuntu) を設定します。デフォルトはalpine. 使用は alpine alpine3.18 と同じです。
host_aliasesすべてのコンテナに追加される追加のホスト名エイリアスのリスト。追加のホストエイリアスの使用については、こちらを参照してください。
image_pull_secrets非公開レジストリからのDockerイメージのプル認証に使用されるKubernetesdocker-registry シークレットネームを含むアイテムの配列。
init_permissions_container_security_contextinit-permissionsコンテナのコンテナセキュリティコンテキストを設定します。セキュリティコンテキストについてはこちらをご覧ください。
namespaceKubernetes ポッドを実行する名前空間。
namespace_overwrite_allowednamespace overwrite 環境変数の内容を検証するための正規表現です(以下で説明します)。空の場合、namespace overwrite 機能を無効にします。
node_selector string=string ( 環境変数の場合はstring:string ) の形式でkey=value ペアのtable を指定します。これを設定すると、すべてのkey=value ペアに一致するKubernetesノードにポッドの作成を制限します。ノードセレクタの使い方についてはこちらをご覧ください。
node_tolerations string=string:string の形式で"key=value" = "Effect" のペアのtable 。これを設定すると、ポッドは許容されるテイントのすべてまたはサブセットを持つノードにスケジュールできます。環境変数の設定で指定できる許容範囲は1つだけです。keyvalueeffect は、Kubernetesポッド許容設定の対応するフィールド名と一致します。
pod_annotations table key=value string=string 。これは、Runnerによって作成される各ビルドポッドに追加される注釈のリストです。これらの値には、拡張用の環境変数を含めることができます。ポッドの注釈はビルドごとに上書きできます。
pod_annotations_overwrite_allowedポッド注釈上書き環境変数の内容を検証する正規表現。空の場合、ポッド注釈の上書き機能を無効にします。
pod_labels string=string の形式でkey=value ペアのtable 。 これは、ランナーによって作成される各ビルドポッドに追加されるラベルのリストです。これらの値には、拡張用の環境変数を含めることができます。ポッドラベルは、pod_labels_overwrite_allowed を使用して各ビルドで上書きできます。
pod_labels_overwrite_allowed正規表現でポッドラベル上書き環境変数の内容を検証します。空の場合、ポッドラベルの上書き機能を無効にします。
pod_security_context設定ファイルを通して設定すると、ビルドポッドのポッドセキュリティコンテキストを設定します。セキュリティコンテキストについての詳細はこちらをご覧ください。
pod_termination_grace_period_secondsポッドレベルの設定で、ポッドが優雅に終了する時間を秒単位で決めます。これを過ぎると、killシグナルでプロセスが強制的に停止します。terminationGracePeriodSeconds が指定されている場合は無視されます。
poll_intervalRunnerが、作成したKubernetesポッドの状態を確認するためにポーリングする頻度を秒単位で指定します(デフォルト= 3)。
poll_timeoutRunnerが作成したコンテナへの接続をタイムアウトするまでに必要な時間を秒単位で指定します。クラスターが一度に処理できるより多くのビルドをキューに入れる場合に便利です (default = 180)。
priority_class_nameポッドに設定する優先クラスを指定します。設定しない場合はデフォルトのものが使用されます。
privileged特権フラグでコンテナを実行します。
pull_policyイメージのプルポリシーを指定します:never,if-not-present,always 。設定されていない場合は、クラスターのイメージのデフォルトのプルポリシーが使用されます。複数のプルポリシーを設定する方法の詳細および手順については、プルポリシーの使用を参照してください。if-not-present,never セキュリティに関する考慮事項も参照してください。プルポリシーを制限することもできます。
resource_availability_check_max_attempts設定されたリソース(サービスアカウントおよび/またはプルシークレット)が利用可能かどうかを確認するために、あきらめるまでの最大試行回数です。各試行の間隔は5秒です。GitLab 15.0で導入されました準備ステップ中のリソースチェックについてもっと読む.
runtime_class_name作成されたすべてのポッドに使用するランタイムクラス。この機能がクラスターでサポートされていない場合、ジョブは終了するか失敗します。
service_container_security_contextサービスコンテナのコンテナセキュリティコンテキストを設定します。セキュリティコンテキストについては、こちらを参照してください。
scheduler_nameビルドポッドのスケジューリングに使用するスケジューラ。
service_accountジョブ/ ExecutorポッドがKubernetes APIと通信するために使用するデフォルトのサービスアカウント。
service_account_overwrite_allowedservice account overwrite 環境変数の内容を検証するための正規表現。空の場合、サービスアカウントの上書き機能を無効にします。
services GitLab Runner 12.5以降サイドカーパターンを使用してビルドコンテナにアタッチされたサービスのリスト。サービスの使い方についてはこちらをご覧ください。
terminationGracePeriodSecondsポッド内で実行されているプロセスが終了シグナルを送られた後、killシグナルでプロセスが強制的に停止されるまでの時間。 cleanup_grace_period_secondspod_termination_grace_period_seconds に取って代わられ、非推奨となりました。
volumesビルドコンテナにマウントされるボリュームのリスト。ボリュームの使用については、こちらをお読みください。
pod_specこの設定はAlpha版です。Runner Manager によって生成されたポッドの仕様を、CI ジョブの実行に使用するポッドに設定された設定のリストで上書きします。Kubernetes Pod Specification に記載されているすべてのプロパティを設定できます。詳細については、生成されたポッド仕様を上書きする(Alpha)を参照してください。

生成されたポッド仕様の上書き(Alpha)

GitLab Runner 15.10 で導入されました

この機能はアルファ版です。本番クラスターで使用する前に、テスト用のKubernetesクラスターでこの機能を使用することを強くお勧めします。この機能を使うには、FF_USE_ADVANCED_POD_SPEC_CONFIGURATION 機能フラグを有効にする必要があります。

この機能が一般的に利用可能になる前に改善のフィードバックを追加するには、このイシューを使用してください。

Runner Managerによって生成されたPodSpec を変更するには、config.toml ファイルのpod_spec 設定を使用してください。

この設定は、pod_spec 生成されたポッド仕様にフィールドを上書きして補完 pod_specします。pod_spec 複数の pod_spec設定を行うことができます。

設定説明
nameカスタムpod_spec に付けられる名前。
patch_path最終的なPodSpec オブジェクトを生成する前に適用する変更を定義するファイルへのパス。ファイルは JSON または YAML ファイルでなければなりません。
patch最終的なPodSpec オブジェクトが生成される前に適用されなければならない変更を記述する JSON または YAML 形式の文字列。
patch_typeGitLab Runner が生成したPodSpec オブジェクトに指定した変更を適用するために Runner が使用するストラテジー。指定できる値はmerge,json,strategic です。

同じpod_spec 設定にpatch_pathpatch を設定することはできません。

config.tomlpod_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 オブジェクトの値を上書きします。値は完全に上書きされるため、このパッチストラテジーの使用には注意が必要です。

merge パッチ・ストラテジーを使用したpod_spec の設定例:

concurrent = 1
check_interval = 1
log_level = "debug"
shutdown_timeout = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = ""
  url = "https://gitlab.example.com"
  id = 0
  token = "__REDACTED__"
  token_obtained_at = 0001-01-01T00:00:00Z
  token_expires_at = 0001-01-01T00:00:00Z
  executor = "kubernetes"
  shell = "bash"
  environment = ["FF_USE_ADVANCED_POD_SPEC_CONFIGURATION=true", "CUSTOM_VAR=value"]
  [runners.kubernetes]
    image = "alpine"
    ...
    [[runners.kubernetes.pod_spec]]
      name = "build envvars"
      patch = '''
        containers:
        - env:
          - name: env1
            value: "value1"
          - name: env2
            value: "value2"
          name: build
      '''
      patch_type = "merge"

この設定により、最終的なPodSpec にはbuild というコンテナが1つだけ存在し、2つの環境変数env1env2 が存在します。上記の例では、関連するCIジョブが失敗しました:

  • helper コンテナの指定が削除されました。
  • build コンテナ仕様は、GitLab Runner によって設定されたすべての必要な設定を失いました。

ジョブが失敗しないように、この例では、pod_spec 、GitLab Runnerによって生成されたプロパティがそのまま含まれていなければなりません。

JSONパッチ戦略

json パッチ・ストラテジーはJSON パッチ仕様を使用して、PodSpec オブジェクトと配列を更新するように制御します。このストラテジーはarray プロパティには使用できません。

json パッチ・ストラテジーを使ったpod_spec の設定例。こ の設定では、 既存のnodeSelector に新 し いkey: value pair が追加 さ れます。既存の値は上書き さ れません。

concurrent = 1
check_interval = 1
log_level = "debug"
shutdown_timeout = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = ""
  url = "https://gitlab.example.com"
  id = 0
  token = "__REDACTED__"
  token_obtained_at = 0001-01-01T00:00:00Z
  token_expires_at = 0001-01-01T00:00:00Z
  executor = "kubernetes"
  shell = "bash"
  environment = ["FF_USE_ADVANCED_POD_SPEC_CONFIGURATION=true", "CUSTOM_VAR=value"]
  [runners.kubernetes]
    image = "alpine"
    ...
    [[runners.kubernetes.pod_spec]]
      name = "val1 node"
      patch = '''
        { "op": "add", "path": "/nodeSelector", "value": { key1: "val1" } }
      '''
      patch_type = "json"

戦略的パッチ戦略

このstrategic パッチ戦略は、PodSpec オブジェクトの各フィールドに適用されている既存のpatchStrategy を使用します。

strategic パッチ戦略を使ったpod_spec の設定例。この設定では、resource request がビルドコンテナに設定されています。

concurrent = 1
check_interval = 1
log_level = "debug"
shutdown_timeout = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = ""
  url = "https://gitlab.example.com"
  id = 0
  token = "__REDACTED__"
  token_obtained_at = 0001-01-01T00:00:00Z
  token_expires_at = 0001-01-01T00:00:00Z
  executor = "kubernetes"
  shell = "bash"
  environment = ["FF_USE_ADVANCED_POD_SPEC_CONFIGURATION=true", "CUSTOM_VAR=value"]
  [runners.kubernetes]
    image = "alpine"
    ...
    [[runners.kubernetes.pod_spec]]
      name = "cpu request 500m"
      patch = '''
        containers:
        - name: build
          resources:
            requests:
              cpu: "500m"
      '''
      patch_type = "strategic"

この設定では、resource request がビルドコンテナに設定されています。

ベストプラクティス

  • 本番環境にデプロイする前に、テスト環境で追加したpod_spec をテストしてください。
  • pod_spec の設定が GitLab Runner が生成する仕様に悪影響を与えないことを確認してください。
  • 複雑なポッド仕様の更新には、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を作成するには、Pod Spec機能を有効にする方法を確認してください。

Kubernetesでは、PodのライフサイクルにアタッチされたエフェメラルなPersistentVolumeClaimを作成できます。これは、Kubernetesクラスターでダイナミックプロビジョニングが有効になっている場合に機能し、PVC 、新しいVolumeを要求することができます。

動的プロビジョニングを有効にした後、config.toml を以下のように変更すると、エフェメラルなPVC を作成できます:

[[runners.kubernetes.pod_spec]]
  name = "ephemeral-pvc"
  patch = '''
    containers:
    - name: build
      volumeMounts:
      - name: builds
        mountPath: /builds
    - name: helper
      volumeMounts:
      - name: builds
        mountPath: /builds
    volumes:
    - name: builds
      ephemeral:
        volumeClaimTemplate:
          spec:
            storageClassName: <The Storage Class that will dynamically provision a Volume>
            accessModes: [ ReadWriteOnce ]
            resources:
              requests:
                storage: 1Gi
  '''

ポッドのライフサイクル

ポッドのライフサイクルは次のような影響を受けます:

  • TOML 設定ファイルでpod_termination_grace_period_seconds プロパティを設定します。ポッド上で実行されているプロセスは、TERM シグナルが送信された後、指定された期間実行できます。この期間が経過してもポッドが正常に終了しない場合は、killシグナルが送信されます。
  • FF_USE_POD_ACTIVE_DEADLINE_SECONDS 機能フラグを有効にします。有効にしてジョブがタイムアウトすると、CI/CD ジョブを実行しているポッドは失敗したものとしてマークされ、関連するすべてのコンテナが強制終了されます。最初に GitLab 上でジョブがタイムアウトするようにするには、activeDeadlineSecondsconfigured timeout + 1 second に設定します。
note
FF_USE_POD_ACTIVE_DEADLINE_SECONDS 機能フラグが有効でpod_termination_grace_period_seconds がゼロ以外の値で設定されている場合、ジョブがタイムアウトしても CI ジョブのポッドは直ちに終了しません。ポッドterminationGracePeriods は、ポッドがタイムアウトしたときにのみポッドが終了するようにします。

ジョブポッドのデフォルトアノテーション

GitLab Runner 15.9 で導入されました

ジョブを実行するポッドにはデフォルトで以下のアノテーションが追加されます:

キー説明
job.runner.gitlab.com/idジョブのID。GitLabインスタンス内のすべてのジョブで一意です。
job.runner.gitlab.com/urlジョブの詳細のURL。
job.runner.gitlab.com/shaプロジェクトがビルドされるコミットリビジョン。
job.runner.gitlab.com/before_shaブランチやタグに存在する、直前の最新コミット。
job.runner.gitlab.com/refプロジェクトをビルドするブランチ名あるいはタグ名。
job.runner.gitlab.com/nameジョブの名前。
project.runner.gitlab.com/idジョブのプロジェクトID。

デフォルトのアノテーションを上書きするには、GitLab Runner設定のpod_annotations 。また、.gitlab-ci.yml ファイルで各 CI/CD ジョブのアノテーションを上書きすることもできます。

Executor サービスアカウントの設定

Executor サービスアカウントを設定するには、KUBERNETES_SERVICE_ACCOUNT 環境変数を設定するか、--kubernetes-service-account フラグを使用します。

Kubernetes名前空間の上書き

前提条件:

  • GitLab Runner Helm チャートのvalues.yml ファイルで、rbac.clusterWideAccesstrue に設定されています。
  • Runner の権限はcore API グループに設定されています。

Kubernetesの名前空間を上書きしてCI用の名前空間を指定し、そこにカスタムセットのポッドをデプロイできます。Runnerによってスポーンされたポッドは、CIステージ中にコンテナ間のアクセスを可能にするために上書きされたネームスペースにあります。

CI/CDジョブごとにKubernetes名前空間を上書きするには、.gitlab-ci.yml ファイルにKUBERNETES_NAMESPACE_OVERWRITE 変数を設定します。

variables:
  KUBERNETES_NAMESPACE_OVERWRITE: ci-${CI_COMMIT_REF_SLUG}
note
この変数はクラスター上に名前空間を作成しません。ジョブを実行する前に名前空間が存在することを確認してください。

CIの実行時に指定された名前空間のみを使用するには、config.toml ファイルで、namespace_overwrite_allowed

[runners.kubernetes]
    ...
    namespace_overwrite_allowed = "ci-.*"

ランナーのAPI権限の設定

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

以下のどちらかを行います:

  • rbac.createtrueに設定します。
  • values.yml ファイルに以下の権限を持つサービスアカウントrbac.serviceAccountName: <service_account_name> を指定します。

    • exec strategy の場合:

      リソース権限
      ポッド/exec作成、パッチ、削除
      ポッド取得、リスト、監視、作成、パッチ、削除
      サービス取得、リスト、監視、作成、パッチ、削除
      シークレット取得、リスト、監視、作成、更新、パッチ、削除
      サービスアカウント取得 (1)
      イベントゲット、リスト (1)
    • attach strategy の場合:

      リソース権限
      ポッド/アタッチ作成、パッチ、削除
      ポッド/exec作成、パッチ、削除
      ポッド取得、監視、作成、削除
      サービス取得、監視、作成、削除
      シークレット取得、作成、更新、削除
      サービスアカウント取得 (1)
      コンフィグマップ取得、作成、更新、削除 (2)
      イベント取得、リスト (3)

(1)serviceAccount の権限のみが必要です:

  • GitLab 15.0と15.1の場合。
  • GitLab 15.0.1、15.1.1、15.2の場合、resource_availability_check_max_attempts が0より大きい値に設定されている場合。

(2) GitLab 15.8 からconfigmaps 権限は不要になりました。

(3)event 権限のみが必要です:

  • GitLab 16.2.0の場合
  • GitLab 16.2.1以降でFF_RETRIEVE_POD_WARNING_EVENTS

Kubernetesデフォルトのサービスアカウントを上書きします。

.gitlab-ci.yml ファイルの各 CI/CD ジョブの Kubernetes サービスアカウントを上書きするには、変数KUBERNETES_SERVICE_ACCOUNT_OVERWRITE を設定します。

この変数を使用して、ネームスペースにアタッチされたサービスアカウントを指定することができます。

variables:
  KUBERNETES_SERVICE_ACCOUNT_OVERWRITE: ci-service-account

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

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

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

Kubernetes API呼び出し用のベアラートークンの設定

ポッドを作成するAPIコールのベアラートークンを設定するには、KUBERNETES_BEARER_TOKEN 変数を使用します。これにより、プロジェクトオーナーはプロジェクトの秘密変数を使ってベアラートークンを指定できます。

ベアラートークンを指定するときは、Host 設定を設定する必要があります。

variables:
  KUBERNETES_BEARER_TOKEN: thebearertokenfromanothernamespace

ポッドラベルの上書き

CI/CDジョブごとにKubernetesのポッドラベルを上書きします:

  1. .config.yaml ファイルで、pod_labels_overwrite_allowed に対する正規表現を定義します。
  2. .gitlab-ci.yml ファイルで、KUBERNETES_POD_LABELS_* の変数に値を設定しますkey=value。 ポッドのラベルは、.Pod に上書きさ key=valueれます。 複数の値を適用できます:

    variables:
      KUBERNETES_POD_LABELS_1: "Key1=Val1"
      KUBERNETES_POD_LABELS_2: "Key2=Val2"
      KUBERNETES_POD_LABELS_3: "Key3=Val3"
    

ポッド注釈の上書き

CI/CDジョブごとにKubernetesのポッドアノテーションを上書きします:

  1. .config.yaml ファイルで、pod_annotations_overwrite_allowed に対する正規表現を定義します。
  2. .gitlab-ci.yml ファイルで、KUBERNETES_POD_ANNOTATIONS_* 変数を設定し、値に使用しますkey=value 。ポッド注釈は、.Pod注釈に上書きさ key=valueれます。 複数の注釈を指定できます:

    variables:
      KUBERNETES_POD_ANNOTATIONS_1: "Key1=Val1"
      KUBERNETES_POD_ANNOTATIONS_2: "Key2=Val2"
      KUBERNETES_POD_ANNOTATIONS_3: "Key3=Val3"
    

コンテナリソースの上書き

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"

設定例

以下のサンプルは、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"
    [runners.kubernetes.node_selector]
      gitlab = "true"
    [runners.kubernetes.node_tolerations]
      "node-role.kubernetes.io/master" = "NoSchedule"
      "custom.toleration=value" = "NoSchedule"
      "empty.value=" = "PreferNoSchedule"
      "onlyKey" = ""

準備ステップでのリソースチェック

前提条件:

  • image_pull_secrets またはservice_account
  • resource_availability_check_max_attempts にはゼロ以上の数値が設定されます。
  • KubernetesserviceAccount get およびlist 権限で使用されます。

GitLab Runnerは、新しいサービスアカウントやシークレットが利用可能かどうかを5秒間隔でチェックします。

  • GitLab 15.0と15.1では、この機能を無効にすることはできず、負の値が設定されるとデフォルトで5
  • GitLab 15.0.1、15.1.1、15.2以降では、この機能はデフォルトで無効になっています。この機能を有効にするには、resource_availability_check_max_attempts0 以外の値に設定します。設定した値は、Runner がサービスアカウントやシークレットをチェックする回数を定義します。

Kubernetesエクゼキュータでのキャッシュの使用

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 ボリューム

hostPath ボリューム を設定し、コンテナ内に指定したホストパスをマウントするようKubernetesに指示します。

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

オプション種類必須説明
name文字列です。はいボリュームの名前。
mount_path文字列です。はいボリュームがマウントされているコンテナ内のパス。
sub_path文字列です。なしボリュームのルートではなくサブパスをマウントします。
host_path文字列です。なしボリュームとしてマウントするホスト・パス。指定しない場合は、mount_path と同じパスに設定されます。
read_onlybooleanなしボリュームを読み取り専用モードに設定します(デフォルトはfalse)。

persistentVolumeClaim ボリューム

persistentVolumeClaim ボリューム を設定し、Kubernetes クラスターで定義されたpersistentVolumeClaim を使用するよう Kubernetes に指示し、コンテナにマウントします。

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

オプション種類必須説明
name文字列です。はいボリューム名と同時に使用するPersistentVolumeClaim の名前。変数に対応。詳細については、「持続的な通貨ごとのビルド・ボリューム」を参照してください。
mount_path文字列です。はいボリュームがマウントされているコンテナ内のパス。
read_onlybooleanなしボリュームを読み取り専用モードに設定します(デフォルトはfalse)。
sub_path文字列です。なしボリュームのルートではなくサブパスをマウントします。

configMap ボリューム

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

config.toml で以下のオプションを使用します:

オプション種類必須説明
name文字列です。はいボリューム名と同時に使用する_configMapの_名前。
mount_path文字列です。はいボリュームがマウントされているコンテナ内のパス。
read_onlybooleanなしボリュームを読み取り専用モードに設定します(デフォルトはfalse)。
sub_path文字列です。なしボリュームのルートではなくサブパスをマウントします。
itemsmap[string]stringいいえ使用する_configMapの_キーとパスのマッピング。

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

  • すべてのキーが含まれます。
  • configMap キーがファイル名として使用されます。
  • 値はファイルの内容に格納されます。

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

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

secret ボリューム

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

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

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

選択されたsecret の各キーは、選択されたマウントパスに保存されたファイルに変更されます。デフォルトでは

  • すべてのキーが含まれます。
  • configMap キーがファイル名として使用されます。
  • 値はファイルの内容に格納されます。

デフォルトのキーと値の格納を変更するには、items オプションを items使用します。オプションをitems 使用 itemsすると、指定したキーのみがボリュームに追加され、それ以外のキーはスキップされます。

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

emptyDir ボリューム

emptyDir ボリューム を設定して、コンテナ内に空のディレクトリをマウントするよう Kubernetes に指示します。

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

オプション種類必須説明
name文字列です。はいボリュームの名前。
mount_path文字列です。はいボリュームをマウントするコンテナ内のパス。
sub_path文字列です。なしボリュームのルートではなくサブパスをマウントします。
medium文字列です。なし“メモリ” はtmpfs を提供します。そうでない場合は、ノードのディスク・ストレージ(デフォルトは “” )になります。

csi ボリューム

Container Storage Interface (csi) ボリューム を設定して、Kubernetes にカスタムcsi ドライバを使用してコンテナ内の任意のストレージシステムをマウントするように指示します。

config.toml で以下のオプションを使用します:

オプション種類必須説明
name文字列です。はいボリュームの名前。
mount_path文字列です。はいボリュームをマウントするコンテナ内のパス。
driver文字列です。はい使用するボリューム・ドライバの名前を指定する文字列値。
fs_type文字列です。なしファイル・システム・タイプの名前を指定する文字列値(例:”ext4”、”xfs”、”ntfs”)。
volume_attributesmap[string]stringなしCSIボリュームの属性のキーと値のペアマッピング。
sub_path文字列です。なしルートの代わりにボリューム内のサブパスをマウントします。
read_onlybooleanなしボリュームを読み取り専用モードに設定します(デフォルトはfalse)。

サービスコンテナへのボリュームのマウント

ビルドコンテナ用に定義されたボリュームは、すべてのサービスコンテナに対しても自動的にマウントされます。services_tmpfs (Docker Executorでのみ利用可能)の代替としてこの機能を使用し、テストを高速化するためにデータベースストレージをRAMにマウントすることができます。

config.toml ファイルの設定例:

[[runners]]
  # usual configuration
  executor = "kubernetes"
  [runners.kubernetes]
    [[runners.kubernetes.volumes.empty_dir]]
      name = "mysql-tmpfs"
      mount_path = "/var/lib/mysql"
      medium = "Memory"

カスタム・ボリューム・マウント

GitLab Runner 13.12で導入されました

ジョブのビルドディレクトリを保存するには、設定された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"

持続的な通貨ごとのビルド・ボリューム

GitLab 16.3 で導入された pvc.name への変数インジェクションをサポート。

Kubernetes CIジョブのビルドディレクトリはデフォルトではエフェメラルです。ジョブをまたいでGitクローンを永続化したい場合(GIT_STRATEGY=fetch を機能させるため)、ビルドフォルダ用に永続ボリュームクレームをマウントする必要があります。複数のジョブが同時に実行される可能性があるため、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-0 からbuild-pvc-3 という永続ボリュームのクレームを自分で作成します。この例では、concurrent から という永続ボリューム・クレームを自分で作成します。Runnerの 設定が指示する数だけ作成します。

ポッドのセキュリティポリシーを設定します。

config.tomlセキュリティコンテキストを設定して、ビルドポッドのセキュリティポリシーを設定します。

以下のオプションを使用します:

オプション種類必須説明
fs_groupintなしポッド内のすべてのコンテナに適用される特別な補足グループ。
run_as_groupintなしコンテナ・プロセスのエントリ・ポイントを実行するGID。
run_as_non_rootbooleanなしコンテナを非 root ユーザーとして実行する必要があることを示します。
run_as_userintなしコンテナプロセスのエントリポイントを実行するUID。
supplemental_groups int リストなしコンテナのプライマリ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

ヘルパーイメージを使う

セキュリティポリシーを設定したら、ヘルパーイメージをそのポリシーに適合させる必要があります。イメージはルートグループから特権を受け取らないので、ユーザーIDがルートグループの一部であることを確認する必要があります。

note
nonroot 環境のみが必要な場合は、ヘルパーイメージの代わりにGitLab Runner UBIGitLab Runner Helper UBIOpenShift(OCP) イメージを使用できます。

以下の例では、nonroot というユーザーとグループを作成し、ヘルパーイメージをそのユーザーとして実行するように設定しています。

ARG tag
FROM registry.gitlab.com/gitlab-org/ci-cd/gitlab-runner-ubi-images/gitlab-runner-helper-ocp:${tag}
USER root
RUN groupadd -g 59417 nonroot && \
    useradd -u 59417 nonroot -g nonroot
WORKDIR /home/nonroot
USER 59417:59417

コンテナのセキュリティ・ポリシーを設定します。

GitLab Runner 14.5 で導入されました

config.toml Executor でコンテナセキュリティコンテキストを設定し、ビルド、ヘルパー、またはサービスポッドにコンテナセキュリティポリシーを設定します。

以下のオプションを使用します:

オプション種類必須説明
run_as_groupintなしコンテナ・プロセスのエントリ・ポイントを実行するGID。
run_as_non_rootbooleanなしコンテナを非 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サービスのリストを定義します。

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"]

プルポリシーの設定

GitLab 13.11で導入された複数のプルポリシーをサポートしました。

config.toml ファイルのpull_policy パラメータを使って、単一または複数のプルポリシーを指定します。ポリシーはイメージの取得と更新を制御し、ビルドイメージ、ヘルパーイメージ、あらゆるサービスに適用されます。

どのポリシーを使用するかについては、プルポリシーに関するKubernetesのドキュメントを参照してください。

単一のプルポリシーの場合

[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クラスタ内のどのノードでビルドを実行するかを指定するには、node_selector オプションを使用します。これは、string=string ( 環境変数の場合はstring:string ) の形式で、key=value ペアのテーブルです。

Runnerは提供された情報を使用して、ビルドのOSとアーキテクチャを決定します。これにより、正しいヘルパーイメージが使用されるようになります。デフォルトでは、OSとアーキテクチャはlinux/amd64

特定のラベルを使用して、異なるOSとアーキテクチャのノードをスケジュールすることができます。

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=1"]

    [runners.kubernetes.node_selector]
      "kubernetes.io/arch" = "amd64"
      "kubernetes.io/os" = "windows"
      "node.kubernetes.io/windows-build" = "10.0.20348"

ノードアフィニティのリストの定義

GitLab Runner 13.4で導入されました

ビルド時にポッド仕様に追加するノードアフィニティのリストを定義します。

config.toml の設定例:

concurrent = 1
[[runners]]
  name = "myRunner"
  url = "gitlab.example.com"
  executor = "kubernetes"
  [runners.kubernetes]
    [runners.kubernetes.affinity]
      [runners.kubernetes.affinity.node_affinity]
        [[runners.kubernetes.affinity.node_affinity.preferred_during_scheduling_ignored_during_execution]]
          weight = 100
          [runners.kubernetes.affinity.node_affinity.preferred_during_scheduling_ignored_during_execution.preference]
            [[runners.kubernetes.affinity.node_affinity.preferred_during_scheduling_ignored_during_execution.preference.match_expressions]]
              key = "cpu_speed"
              operator = "In"
              values = ["fast"]
            [[runners.kubernetes.affinity.node_affinity.preferred_during_scheduling_ignored_during_execution.preference.match_expressions]]
              key = "mem_speed"
              operator = "In"
              values = ["fast"]
        [[runners.kubernetes.affinity.node_affinity.preferred_during_scheduling_ignored_during_execution]]
          weight = 50
          [runners.kubernetes.affinity.node_affinity.preferred_during_scheduling_ignored_during_execution.preference]
            [[runners.kubernetes.affinity.node_affinity.preferred_during_scheduling_ignored_during_execution.preference.match_expressions]]
              key = "core_count"
              operator = "In"
              values = ["high", "32"]
            [[runners.kubernetes.affinity.node_affinity.preferred_during_scheduling_ignored_during_execution.preference.match_fields]]
              key = "cpu_type"
              operator = "In"
              values = ["arm64"]
      [runners.kubernetes.affinity.node_affinity.required_during_scheduling_ignored_during_execution]
        [[runners.kubernetes.affinity.node_affinity.required_during_scheduling_ignored_during_execution.node_selector_terms]]
          [[runners.kubernetes.affinity.node_affinity.required_during_scheduling_ignored_during_execution.node_selector_terms.match_expressions]]
            key = "kubernetes.io/e2e-az-name"
            operator = "In"
            values = [
              "e2e-az1",
              "e2e-az2"
            ]

ポッドがスケジュールされるノードの定義

GitLab Runner 14.3 で導入されました

ポッドアフィニティとアンチアフィニティを使って、他のポッドのラベルに基づいて、あなたのポッドがスケジューリングされるノードを制限します。

config.tomlの設定例:

concurrent = 1
[[runners]]
  name = "myRunner"
  url = "gitlab.example.com"
  executor = "kubernetes"
  [runners.kubernetes]
    [runners.kubernetes.affinity]
      [runners.kubernetes.affinity.pod_affinity]
        [[runners.kubernetes.affinity.pod_affinity.required_during_scheduling_ignored_during_execution]]
          topology_key = "failure-domain.beta.kubernetes.io/zone"
          namespaces = ["namespace_1", "namespace_2"]
          [runners.kubernetes.affinity.pod_affinity.required_during_scheduling_ignored_during_execution.label_selector]
            [[runners.kubernetes.affinity.pod_affinity.required_during_scheduling_ignored_during_execution.label_selector.match_expressions]]
              key = "security"
              operator = "In"
              values = ["S1"]
        [[runners.kubernetes.affinity.pod_affinity.preferred_during_scheduling_ignored_during_execution]]
        weight = 100
        [runners.kubernetes.affinity.pod_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term]
          topology_key = "failure-domain.beta.kubernetes.io/zone"
          [runners.kubernetes.affinity.pod_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.label_selector]
            [[runners.kubernetes.affinity.pod_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.label_selector.match_expressions]]
              key = "security_2"
              operator = "In"
              values = ["S2"]
      [runners.kubernetes.affinity.pod_anti_affinity]
        [[runners.kubernetes.affinity.pod_anti_affinity.required_during_scheduling_ignored_during_execution]]
          topology_key = "failure-domain.beta.kubernetes.io/zone"
          namespaces = ["namespace_1", "namespace_2"]
          [runners.kubernetes.affinity.pod_anti_affinity.required_during_scheduling_ignored_during_execution.label_selector]
            [[runners.kubernetes.affinity.pod_anti_affinity.required_during_scheduling_ignored_during_execution.label_selector.match_expressions]]
              key = "security"
              operator = "In"
              values = ["S1"]
          [runners.kubernetes.affinity.pod_anti_affinity.required_during_scheduling_ignored_during_execution.namespace_selector]
            [[runners.kubernetes.affinity.pod_anti_affinity.required_during_scheduling_ignored_during_execution.namespace_selector.match_expressions]]
              key = "security"
              operator = "In"
              values = ["S1"]
        [[runners.kubernetes.affinity.pod_anti_affinity.preferred_during_scheduling_ignored_during_execution]]
        weight = 100
        [runners.kubernetes.affinity.pod_anti_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term]
          topology_key = "failure-domain.beta.kubernetes.io/zone"
          [runners.kubernetes.affinity.pod_anti_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.label_selector]
            [[runners.kubernetes.affinity.pod_anti_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.label_selector.match_expressions]]
              key = "security_2"
              operator = "In"
              values = ["S2"]
          [runners.kubernetes.affinity.pod_anti_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.namespace_selector]
            [[runners.kubernetes.affinity.pod_anti_affinity.preferred_during_scheduling_ignored_during_execution.pod_affinity_term.namespace_selector.match_expressions]]
              key = "security_2"
              operator = "In"
              values = ["S2"]

追加のホストエイリアスを追加

GitLab Runner 13.7で導入されました

この機能は 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"]

コンテナライフサイクルフックの設定

GitLab Runner 14.2 で導入されました

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

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

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

KubernetesLifecycleHTTPGet

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

KubernetesLifecycleHTTPGetHeader

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

KubernetesLifecycleTcpSocket

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

ポッドのDNS設定

GitLab Runner 13.7で導入されました

以下のオプションを使用して、ポッドのDNS設定を行います。

オプション種類必須説明
nameservers string リストなしポッドのDNSサーバーとして使用されるIPアドレスのリスト。
optionsKubernetesDNSConfigOptionなし各オブジェクトは 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なし設定オプションの値。

コンテナ機能の指定

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

コンテナ機能を指定するには、config.tomlcap_add およびcap_drop オプションを使用します。コンテナランタイムは、Dockerコンテナのようなデフォルトの機能リストを定義することもできます。

ランナーがデフォルトで落とす能力のリストがあります。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を定義できます。これらのルールは、ユーザー定義の設定よりも優先されます。

ドロップされる機能のデフォルトリスト

GitLab Runnerはデフォルトで以下のケイパビリティをドロップします。

ユーザー定義の方がcap_add デフォルトでドロップされるケイパビリティよりも優先さ cap_addれます。デフォルトでドロップされるcap_add ケイパビリティを追加したい場合は、. cap_add

  • NET_RAW

RuntimeClassの設定

GitLab Runner 14.9 で導入されました

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"

ビルドでのDockerの使用

ビルドでDockerを使用する場合、注意すべき点がいくつかあります。

露出した/var/run/docker.sock

runners.kubernetes.volumes.host_path オプションを使用してホストの/var/run/docker.sock をビルドコンテナに公開すると、一定のリスクがあります。ノードのコンテナにはビルドコンテナからアクセスできるため、本番コンテナと同じクラスターでビルドを実行しているかどうかによっては、そのようなことをするのは賢明ではないかもしれません。

テストの拡張docker:dind

docker-in-docker イメージとも呼ばれるdocker:dind を実行する場合、コンテナは特権モードで実行する必要があります。これには潜在的なリスクがあり、さらなるイシューが発生する可能性があります。

Dockerデーモンは、service 、通常は.gitlab-ci.yml として起動されるため、ポッド内の別のコンテナとして実行されます。ポッド内のコンテナは、それらに割り当てられたボリュームと、localhost で互いに通信するために使用するIPアドレスのみを共有します。docker:dind コンテナは/var/run/docker.sock を共有せず、docker バイナリはデフォルトでこれを使用しようとします。

クライアントを設定するには、TCPを使用してDockerデーモンと連絡し、もう一方のコンテナでは、ビルド・コンテナの環境変数を含めます:

  • DOCKER_HOST=tcp://<hostname>:2375 TLS接続を使用しない場合。
  • DOCKER_HOST=tcp://<hostname>:2376 TLS 接続の場合。

hostname の場合は次のように設定します:

  • localhost GitLab Runner 12.7以前、Kubernetes 1.6以前の場合。
  • docker GitLab Runner 12.8以降、Kubernetes 1.7以降用。

Docker 19.03以降では、TLSはデフォルトで有効になっていますが、証明書をクライアントにマッピングする必要があります。DINDまたはマウント証明書の非TLS接続を有効にすることができます。詳細については DockerワークフローでDocker Executorを使用します。.

ホストカーネルの露出を防ぐ

docker:dind または/var/run/docker.sock を使用すると、Dockerデーモンはホストマシンの内部カーネルにアクセスできるようになります。これは、Dockerイメージがビルドされるときに、ポッドで設定されたlimits が機能しないことを意味します。Dockerデーモンは、Kubernetesによって生成されたDockerビルドコンテナに課された制限に関係なく、ノードの全容量をレポーターします。

特権モードでビルドコンテナを実行する場合、または/var/run/docker.sock が公開されている場合、ホストカーネルがビルドコンテナに公開される可能性があります。露出を最小限に抑えるには、node_selector オプションにラベルを指定します。これにより、コンテナをノードにデプロイする前に、ノードがラベルに一致するようになります。たとえば、ラベルrole=ci, を role=ci指定すると、role=ciビルド・コンテナはラベル , の付いたノードでのみ実行さ role=ciれ、他のすべてのプロダクション・サービスは他のノードで実行されます。

ビルドコンテナをさらに分離するには、ノードテイントを使用できます。テイントは、ビルドポッドと同じノードで他のポッドがスケジューリングできないようにします。

Dockerイメージのビルドにkanikoを使用します。

Kubernetesクラスター内でDockerイメージを構築するためにkanikoを使用することができます。

kanikoはDockerデーモンなしで動作し、特権アクセスなしでイメージをビルドします。

詳しくはkanikoとGitLab CI/CDによるイメージのビルドをご覧ください。

kaniko を使用して_マルチステージ_ Dockerfiles をビルドする際に、既知のイシューがあります。パイプラインジョブにafter_script セクションが after_script含まれている場合、そのセクションを実行すると以下のエラーメッセージが表示されて失敗します。ジョブは正常に完了します。

OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: chdir to cwd
("/workspace") set in config.json failed: no such file or directory: unknown

このセクションが失敗するのは、kaniko がマルチステージDockerfileを構築する際に、そのコンテナのWORKDIR を削除するためです。これにより、kubectl exec (および類似の SDK API) がコンテナにアタッチできなくなります。

このイシューには2つの回避策があります:

  • kaniko Executor の呼び出しに--ignore-path /workspace を追加します。
  • mkdir -p /workspace kaniko executorの呼び出しの_後に_、ジョブのscript

詳細はイシュー30769を参照してください。

Dockerイメージとサービスの制限

GitLab Runner 14.2のKubernetes Executor用に追加されました。

ジョブの実行に使用するDockerイメージを制限することができます。これを行うには、ワイルドカードパターンを指定します。例えば、非公開のDockerレジストリからのイメージのみを許可することができます:

[[runners]]
  (...)
  executor = "kubernetes"
  [runners.kubernetes]
    (...)
    allowed_images = ["my.registry.tld:5000/*:*"]
    allowed_services = ["my.registry.tld:5000/*:*"]

または、このレジストリからのイメージの特定のリストに制限します:

[[runners]]
  (...)
  executor = "kubernetes"
  [runners.kubernetes]
    (...)
    allowed_images = ["my.registry.tld:5000/ruby:*", "my.registry.tld:5000/node:*"]
    allowed_services = ["postgres:9.4", "postgres:latest"]

Dockerプルポリシーの制限

GitLab 15.1で導入されました

.gitlab-ci.yml ファイルで、プルポリシーを指定することができます。このポリシーは、CI/CDジョブがどのようにイメージをフェッチするかを決定します。

.gitlab-ci.yml ファイルで使用できるプルポリシーを制限するには、allowed_pull_policies を使用します。

例えば、alwaysif-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 で指定されていないプル・ポリシーを含めてはなりません。含めると、ジョブはエラーを返します。

ジョブの実行

GitLab Runner はデフォルトでkube exec の代わりにkube attach を使用します。これにより、ネットワークが不安定な環境でジョブが途中で成功したことになってしまうような問題を避けることができます。

GitLab Runner 14.0にアップデートした後に問題が発生した場合は、機能フラグFF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGYtrue に切り替えてイシューを提出してください。

レガシー実行ストラテジーの削除についてはイシュー #27976をご覧ください。

コンテナエントリーポイントに関する既知のイシュー

note
GitLab 14.5から15.0では、GitLab Runnerはkube attach が設定されたKubernetes Executorで使用された場合、Dockerイメージで定義されたエントリポイントを使用します。 GitLab 15.1以降では、FF_KUBERNETES_HONOR_ENTRYPOINT が設定された場合、Dockerイメージで定義されたエントリポイントがKubernetes Executorで使用されます。

コンテナエントリーポイントには以下の既知のイシューがあります:

  • イメージの Dockerfile にエントリポイントが定義されている場合、有効なシェルを開く必要があります。そうでない場合、ジョブはハングします。
  • ファイルタイプのCI/CD変数は、エントリポイントの実行時にはディスクに書き込まれません。ファイルはスクリプト実行中のジョブでのみアクセス可能です。
  • 以下のCI/CD変数はエントリーポイントではアクセスできません。スクリプトコマンドを実行する前に、before_script を使用して設定を変更することができます:

古いランナーポッドの削除

GitLab Runner 14.6 で導入されました

古い Runner ポッドがクリアされないことがあります。これは、Runner Manager が誤ってシャットダウンされた場合に発生する可能性があります。

この状況に対処するには、GitLab Runner Pod Cleanup アプリケーションを使って古いポッドのクリーンアップをスケジュールすることができます。詳しくは

トラブルシューティング

Kubernetesエクゼキュータを使用する際によく遭遇するエラーは以下の通りです。

Job failed (system failure): timed out waiting for pod to start

poll_timeout で定義されたタイムアウトまでにクラスターがビルドポッドをスケジュールできない場合、ビルドポッドはエラーを返します。Kubernetes Schedulerで削除できるはずです。

このイシューを修正するには、config.toml ファイルでpoll_timeout の値を増やします。

context deadline exceeded

ジョブログのcontext deadline exceeded エラーは通常、Kubernetes APIクライアントが特定のクラスターAPIリクエストのタイムアウトにヒットしたことを示しています。

kube-apiserver クラスターコンポーネント](https://kubernetes.io/docs/concepts/cluster-administration/system-metrics/) の[メトリクスを確認してください:

  • 応答待ち時間の増加。
  • ポッド、シークレット、ConfigMap、およびその他のコア(v1)リソースに対する一般的な作成または削除オペレーションのエラー率。

kube-apiserver オペレーションのタイムアウトによるエラーのログは次のように表示されます:

Job failed (system failure): prepare environment: context deadline exceeded
Job failed (system failure): prepare environment: setting up build pod: context deadline exceeded

場合によっては、kube-apiserver のエラーレスポンスに、失敗したサブコンポーネント(Kubernetesクラスターのetcdserver など)の詳細が追加されることがあります:

Job failed (system failure): prepare environment: etcdserver: request timed out
Job failed (system failure): prepare environment: etcdserver: leader changed
Job failed (system failure): prepare environment: Internal error occurred: resource quota evaluates timeout

これらのkube-apiserver サービス障害は、ビルドポッドの作成中や、完了後のクリーンアップの試行中に発生する可能性があります:

Error cleaning up secrets: etcdserver: request timed out
Error cleaning up secrets: etcdserver: leader changed

Error cleaning up pod: etcdserver: request timed out, possibly due to previous leader failure
Error cleaning up pod: etcdserver: request timed out
Error cleaning up pod: context deadline exceeded

Kubernetes APIと通信しようとすると、接続が拒否されました。

GitLab RunnerがKubernetes APIにリクエストして失敗する場合、kube-apiserver が過負荷でAPIリクエストを受け付けない、または処理できないことが考えられます。

Error cleaning up podJob failed (system failure): prepare environment: waiting for pod running

以下のエラーは、Kubernetesが適時にジョブポッドのスケジューリングに失敗した場合に発生します。GitLab Runnerはポッドの準備ができるのを待ちますが、失敗し、その後ポッドをクリーンアップしようとしますが、これも失敗することがあります。

Error: Error cleaning up pod: Delete "https://xx.xx.xx.x:443/api/v1/namespaces/gitlab-runner/runner-0001": dial tcp xx.xx.xx.x:443 connect: connection refused

Error: Job failed (system failure): prepare environment: waiting for pod running: Get "https://xx.xx.xx.x:443/api/v1/namespaces/gitlab-runner/runner-0001": dial tcp xx.xx.xx.x:443 connect: connection refused

トラブルシューティングを行うには、Kubernetesのプライマリノードと、kube-apiserver インスタンスを実行しているすべてのノードを確認します。クラスターでスケールアップしたい目標数のポッドを管理するのに必要なリソースがすべてあることを確認してください。

GitLab RunnerがポッドがReady ステータスに達するのを待つ時間を変更するには、poll_timeout 設定を使用します。

ポッドがどのようにスケジューリングされるのか、あるいはなぜ時間通りにスケジューリングされないのかをよりよく理解するには、Kubernetes Schedulerについて読んでください。

request did not complete within requested timeout

ビルドポッド作成中に観測されたメッセージrequest did not complete within requested timeout は、Kubernetesクラスタ上で設定されたアドミッションコントロールWebhookがタイムアウトしていることを示しています。

アドミッションコントロールWebhookは、それらがスコープされているすべてのAPIリクエストに対するクラスターレベルの管理制御インターセプトであり、時間内に実行されないと障害を引き起こす可能性があります。

アドミッションコントロールWebhookは、どのAPIリクエストとネームスペースソースをインターセプトするかを細かく制御できるフィルターをサポートしています。GitLab RunnerからのKubernetes APIコールがアドミッション・コントロールWebhookを通過する必要がない場合は、Webhookのセレクタ/フィルタ設定を変更してGitLab Runnerの名前空間を無視するか、GitLab Runner Helm Chartvalues.yamlpodAnnotations またはpodLabels を設定することで、GitLab Runnerポッド上に除外ラベル/注釈を適用することができます。

例えば、DataDog Admission ControllerのWebhookがGitLab Runner managerポッドからのAPIリクエストを傍受しないようにするには、以下を追加します:

podLabels:
  admission.datadoghq.com/enabled: false

KubernetesクラスターのアドミッションコントロールWebhookを一覧表示するには、以下を実行します:

kubectl get validatingwebhookconfiguration -o yaml
kubectl get mutatingwebhookconfiguration -o yaml

アドミッションコントロールWebhookがタイムアウトすると、次のような形式のログが観測されます:

Job failed (system failure): prepare environment: Timeout: request did not complete within requested timeout
Job failed (system failure): prepare environment: setting up credentials: Timeout: request did not complete within requested timeout

アドミッションコントロール Webhook がタイムアウトすると、次のようなログが記録されます:

Job failed (system failure): prepare environment: setting up credentials: Internal error occurred: failed calling webhook "example.webhook.service"

fatal: unable to access 'https://gitlab-ci-token:token@example.com/repo/proj.git/': Could not resolve host: example.com

ヘルパーイメージの alpine を使用している場合、Alpine のmuslの DNS リゾルバに関連するDNS のイシューが発生する可能性があります。

helper_image_flavor = "ubuntu"

docker: Cannot connect to the Docker daemon at tcp://docker:2375. Is the docker daemon running?

このエラーは、Docker-in-Dockerを使用している場合に、DINDサービスが完全に起動する前にアクセスしようとすると発生する可能性があります。詳細については、このイシューを参照してください。

curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443

DIND Maximum Transmission Unit(MTU) がKubernetesオーバーレイネットワークより大きい場合、Docker-in-Docker使用時にこのエラーが発生することがあります。DINDはデフォルトで1500のMTUを使用しますが、これはデフォルトのオーバーレイネットワークを経由するには大きすぎます。DIND MTUはサービス定義内で変更できます:

services:
  - name: docker:dind
    command: ["--mtu=1450"]

MountVolume.SetUp failed for volume "kube-api-access-xxxxx" : chown is not supported by windows

CI/CDジョブを実行すると、次のようなエラーが表示されることがあります:

MountVolume.SetUp failed for volume "kube-api-access-xxxxx" : chown c:\var\lib\kubelet\pods\xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\volumes\kubernetes.io~projected\kube-api-access-xxxxx\..2022_07_07_20_52_19.102630072\token: not supported by windows

このイシューは、ノードセレクタを使用して異なるオペレーティングシステムやアーキテクチャのノードでビルドを実行した場合に発生します。

このイシューを修正するには、ランナーマネージャーポッドが常にLinuxノードでスケジュールされるようにnodeSelector 。たとえば、values.yaml ファイル には以下を記述します:

nodeSelector:
  kubernetes.io/os: linux

ビルドポッドには、Runner IAMロールの代わりにワーカーノードのIAMロールが割り当てられます。

このイシューは、ワーカーノードの IAM ロールに正しいロールを引き受ける権限がない場合に発生します。これを解決するには、ワーカーノードの IAM ロールの信頼関係にsts:AssumeRole 権限を追加します:

{
    "Effect": "Allow",
    "Principal": {
        "AWS": "arn:aws:iam::<AWS_ACCOUNT_NUMBER>:role/<IAM_ROLE_NAME>"
    },
    "Action": "sts:AssumeRole"
}

Preparation failed: failed to pull image 'image-name:latest': pull_policy ([Always]) defined in GitLab pipeline config is not one of the allowed_pull_policies ([])

このイシューは、.gitlab-ci.ymlpull_policy を指定したが、Runner の設定ファイルにポリシーが設定されていない場合に発生します。これを解決するには、Restrict Docker pull policiesに従ってallowed_pull_policies を設定に追加します。

バックグラウンドプロセスによってジョブがハングアップしたりタイムアウトしたりします。

ジョブの実行中にバックグラウンドプロセスが開始されると、ビルドジョブが終了できなくなることがあります。これを避けるには

  • プロセスをダブルフォークします。例えば、command_to_run < /dev/null &> /dev/null &.
  • ジョブスクリプトを終了する前にプロセスを終了します。

ジョブで生成されるファイルとフォルダには、特定の UNIX 所有者と権限があります。ファイルやフォルダがアーカイブまたは抽出されるとき、UNIX の詳細は保持されます。ただし、ファイルやフォルダーがヘルパーイメージの USER 設定と不一致になることがあります。

Creating cache ... ステップで権限関連のエラーが発生した場合は、次のことができます:

  • 解決策として、キャッシュ・ファイルを作成するジョブ・スクリプトなどで、ソース・データが変更され ていないかどうかを調査します。
  • 回避策として、(before_/after_)script: ディレクティブに一致するchownおよびchmodコマンドを追加します。

ジョブ変数へのアクセスの制限

Kubernetes Executorを使用する場合、Kubernetesクラスターにアクセスできるユーザーはジョブで使用される変数を読むことができます。デフォルトでは、ジョブ変数は

ジョブ変数データへのアクセスを制限するために、ロールベースのアクセス制御(RBAC) 、GitLab Runnerが使用するネームスペースにGitLab管理者だけがアクセスできるようにする必要があります。

他のユーザーがGitLab Runnerネームスペースにアクセスする必要がある場合は、GitLab Runnerネームスペースでユーザーが持つアクセスの種類を制限するために次のverbs

  • podsconfigmaps の場合:
    • get
    • watch
    • list
  • pods/exec およびpods/attach については、create を使用してください。

作成者の RBAC 定義例:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: gitlab-runner-authorized-users
rules:
- apiGroups: [""]
  resources: ["configmaps", "pods"]
  verbs: ["get", "watch", "list"]
- apiGroups: [""]
  resources: ["pods/exec", "pods/attach"]
  verbs: ["create"]