Kubernetes executorのトラブルシューティング
Kubernetes executorの使用時に発生する一般的なエラーを以下に示します。
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クラスターコンポーネントのmetricsを確認します:
- 応答latencyの増加。
- ポッド、シークレット、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 exceededDial tcp xxx.xx.x.x:xxx: i/o timeout
これはKubernetesのエラーであり、通常、RunnerマネージャーがKubernetes APIサーバーにアクセスできないことを示します。この問題を解決するには、以下を実行します:
- ネットワークセキュリティポリシーを使用する場合は、通常はポート443またはポート6443のいずれかまたは両方で、Kubernetes APIへのアクセスを許可します。
- Kubernetes APIが実行されていることを確認します。
Kubernetes APIとの通信を試みるときに接続が拒否されました
GitLab RunnerがKubernetes APIにリクエストを送信して失敗した場合、kube-apiserverがオーバーロードになり、APIリクエストを受信または処理できないことが原因である可能性があります。
Error cleaning up podとJob 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チャートvalues.yamlでpodAnnotationsまたはpodLabelsを構成して、GitLab Runnerポッドに除外ラベル/注釈を適用できます。
たとえば、DataDog Admission Controller WebhookがGitLab Runnerマネージャーポッドによって行われたAPIリクエストをインターセプトしないようにするには、次を追加します:
podLabels:
admission.datadoghq.com/enabled: falseKubernetesクラスターのアドミッションコントロール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
ヘルパーイメージのalpinealpineフレーバーを使用している場合、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
このエラーは、Docker-in-Dockerを使用している場合に、DINDの最大伝送ユニット(MTU)がKubernetesオーバーレイネットワークよりも大きい場合に発生する可能性があります。DINDはデフォルトのMTU 1500を使用しますが、これはデフォルトのオーバーレイネットワーク全体でルーティングするには大きすぎます。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この問題は、ノードセレクターを使用して、異なるオペレーティングシステムとアーキテクチャを持つノードでビルドを実行すると発生します。
この問題を修正するには、nodeSelectorを構成して、Runnerマネージャーポッドが常にLinuxノードでスケジュールされるようにします。たとえば、values.yamlファイルには、次のものが含まれている必要があります:
nodeSelector:
kubernetes.io/os: linuxビルドポッドに、Runner IAMロールの代わりにワーカーノードのIAMロールが割り当てられています
この問題は、ワーカーノードIAMロールに、正しいロールを引き受ける権限がない場合に発生します。これを修正するには、sts:AssumeRole権限をワーカーノードのIAMロールの信頼関係に追加します:
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<AWS_ACCOUNT_NUMBER>:role/<IAM_ROLE_NAME>"
},
"Action": "sts:AssumeRole"
}Preparation failed: invalid pull policy for image 'image-name:latest': pull_policy ([Always]) defined in GitLab pipeline config is not one of the allowed_pull_policies ([])
この問題は、pull_policyを.gitlab-ci.ymlで指定したが、Runnerのconfig fileにポリシーが構成されていない場合に発生します。これを修正するには、Dockerプルポリシーの制限に従って、allowed_pull_policiesを構成に追加します。
バックグラウンドプロセスにより、ジョブがハングアップし、タイムアウトします
ジョブの実行中に開始されたバックグラウンドプロセスは、ビルドジョブが終了するのを防ぐ可能性があります。これを回避するには、次の手順を実行します:
- プロセスをダブルフォークします。たとえば、
command_to_run < /dev/null &> /dev/null &などです。 - ジョブスクリプトを終了する前にプロセスを強制終了します。
キャッシュに関連するpermission deniedエラー
ジョブで生成されるファイルとフォルダーには、特定のUNIX所有権と権限があります。ファイルとフォルダーがアーカイブまたは抽出されると、UNIXの詳細が保持されます。ただし、ファイルとフォルダーは、ヘルパーイメージのUSER構成と一致しない場合があります。
Creating cache ...ステップで権限関連のエラーが発生した場合は、次の手順を実行できます:
- 解決策として、ソースデータが変更されているかどうかを調査します(たとえば、キャッシュされたファイルを作成するジョブスクリプトなど)。
- 回避策として、一致するchownコマンドとchmodコマンドを(
before_/after_)script:ディレクティブに追加します。
初期システムを備えたビルドコンテナ内の明らかに冗長なシェルプロセス
プロセスツリーには、次のいずれかの場合にシェルプロセスが含まれる場合があります:
FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGYがfalseで、FF_USE_DUMB_INIT_WITH_KUBERNETES_EXECUTORがtrueです。- ビルドイメージの
ENTRYPOINTは、(tini-initやdumb-initのような)初期システムです。
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 21:58 ? 00:00:00 /scripts-37474587-5556589047/dumb-init -- sh -c if [ -x /usr/local/bin/bash ]; then .exec /usr/local/bin/bash elif [ -x /usr/bin/bash ]; then .exec /usr/bin/bash elif [ -x /bin/bash ]; then .exec /bin/bash elif [ -x /usr/local/bin/sh ]; then .exec /usr/local/bin/sh elif [ -x /usr/bin/sh ]; then .exec /usr/bin/sh elif [ -x /bin/sh ]; then .exec /bin/sh elif [ -x /busybox/sh ]; then .exec /busybox/sh else .echo shell not found .exit 1 fi
root 7 1 0 21:58 ? 00:00:00 /usr/bin/bash <---------------- WHAT IS THIS???
root 26 1 0 21:58 ? 00:00:00 sh -c (/scripts-37474587-5556589047/detect_shell_script /scripts-37474587-5556589047/step_script 2>&1 | tee -a /logs-37474587-5556589047/output.log) &
root 27 26 0 21:58 ? 00:00:00 \_ /usr/bin/bash /scripts-37474587-5556589047/step_script
root 32 27 0 21:58 ? 00:00:00 | \_ /usr/bin/bash /scripts-37474587-5556589047/step_script
root 37 32 0 21:58 ? 00:00:00 | \_ ps -ef --forest
root 28 26 0 21:58 ? 00:00:00 \_ tee -a /logs-37474587-5556589047/output.logこのシェルプロセスは、sh、bash、またはbusyboxである可能性があり、PPIDが1で、PIDが6または7である場合、初期システム(上記のPID1)によって実行されるシェル検出スクリプトによって開始されるシェルです。このプロセスは冗長ではなく、ビルドコンテナが初期システムで実行される場合の一般的な操作です。
Runnerポッドはジョブの結果を実行できず、登録が成功したにもかかわらずタイムアウトします
RunnerポッドがGitLabに登録された後、ジョブを実行しようとしますが、実行されず、最終的にジョブはタイムアウトします。次のエラーがレポートされます:
There has been a timeout failure or the job got stuck. Check your timeout limits or try again.
This job does not have a trace.この場合、Runnerは次のエラーを受け取る可能性があります。
HTTP 204 No content response code when connecting to the `jobs/request` API.この問題をトラブルシューティングするには、手動でPOSTリクエストをAPIに送信して、TCP接続がハングしているかどうかを検証します。TCP接続がハングしている場合、RunnerはCIジョブペイロードをリクエストできない可能性があります。
failed to reserve container name(gcs-fuse-csi-driverを使用している場合)のinit-permissionsコンテナ
gcs-fuse-csi-driver csiドライバーは、初期コンテナのボリュームのマウントをサポートしていません。これにより、このドライバーを使用するときに初期コンテナの起動が失敗する可能性があります。Kubernetes 1.28で導入された機能は、このbugを解決するためにドライバーのプロジェクトでサポートされている必要があります。
エラー: only read-only root filesystem container is allowed
コンテナを読み取り専用でマウントされたルートfilesystemで実行するように強制するアドミッションポリシーを持つクラスターでは、このエラーは次の場合に表示されることがあります:
- GitLab Runnerをインストールするには、次の手順に従ってください。
- GitLab Runnerがビルドポッドをスケジュールしようとしています。
これらのアドミッションポリシーは通常、GatekeeperやKyvernoなどのアドミッションコントローラーによって適用されます。たとえば、コンテナを読み取り専用ルートfilesystemで実行するように強制するポリシーは、readOnlyRootFilesystem Gatekeeperポリシーです。
この問題を解決するには、以下を実行します:
- クラスターにデプロイされるすべてのポッドは、コンテナの
securityContext.readOnlyRootFilesystemをtrueに設定することにより、アドミッションポリシーに準拠する必要があります。これにより、アドミッションコントローラーがポッドをブロックしません。 - ルートfilesystemが読み取り専用でマウントされている場合でも、コンテナは正常に実行され、filesystemに書き込むことができる必要があります。
GitLab Runnerの場合
GitLab RunnerがGitLab Runner Helmチャートでデプロイされている場合は、GitLabチャート構成を更新して、次のようにする必要があります:
適切な
securityContext値:<...> securityContext: readOnlyRootFilesystem: true <...>ポッドが書き込むことができる、書き込み可能なfilesystemがマウントされています:
<...> volumeMounts: - name: tmp-dir mountPath: /tmp volumes: - name: tmp-dir emptyDir: medium: "Memory" <...>
ビルドポッドの場合
ビルドポッドを読み取り専用ルートfilesystemで実行するには、config.tomlで異なるコンテナのセキュリティコンテキストを構成します。GitLabチャートの変数runners.configを設定できます。これはビルドポッドに渡されます:
runners:
config: |
<...>
[[runners]]
[runners.kubernetes.build_container_security_context]
read_only_root_filesystem = true
[runners.kubernetes.init_permissions_container_security_context]
read_only_root_filesystem = true
[runners.kubernetes.helper_container_security_context,omitempty]
read_only_root_filesystem = true
# This section is only needed if jobs with services are used
[runners.kubernetes.service_container_security_context,omitempty]
read_only_root_filesystem = true
<...>ビルドポッドとそのコンテナを読み取り専用filesystemで正常に実行するには、ビルドポッドが書き込むことができる場所に書き込み可能なfilesystemが必要です。少なくとも、これらの場所はビルドおよびホームディレクトリです。必要に応じて、ビルドプロセスに他の場所への書き込みアクセス権があることを確認してください。
一般に、ホームディレクトリは、プログラムが正常な実行に必要な構成やその他のデータを格納できるように、書き込み可能である必要があります。git binaryは、ホームディレクトリに書き込むことができると予想されるプログラムの一例です。
異なるコンテナイメージのパスに関係なく、ホームディレクトリを書き込み可能にするには:
- (どのビルドイメージを使用する場合でも)安定したパスにボリュームをマウントします。
- すべてのビルドに対してグローバルに環境変数
$HOMEを設定して、ホームディレクトリを変更します。
GitLabチャートの変数runners.configの値を更新することにより、config.tomlでビルドポッドとそのコンテナを構成できます。
runners:
config: |
<...>
[[runners]]
environment = ["HOME=/build_home"]
[[runners.kubernetes.volumes.empty_dir]]
name = "repo"
mount_path = "/builds"
[[runners.kubernetes.volumes.empty_dir]]
name = "build-home"
mount_path = "/build_home"
<...>emptyDirの代わりに、他のサポートされているボリュームタイプを使用できます。明示的に処理され、ビルドアーティファクトとして保存されないすべてのファイルは通常一時的なため、ほとんどの場合、emptyDirが機能します。
AWS EKS: ポッドのクリーンアップ中にエラー: ポッド「Runner-**」が見つからないか、ステータスが「失敗」です
Amazon EKSゾーン再分散機能は、autoscalingグループ内の可用性ゾーンのバランスを取ります。この機能は、1つの可用性ゾーンのノードを停止し、別の可用性ゾーンに作成する可能性があります。
Runnerジョブを停止して別のノードに移動することはできません。このエラーを解決するには、Runnerジョブに対してこの機能を無効にします。