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 요청에 대해 시간 초과를 감지했음을 나타냅니다.

pods, secrets, ConfigMaps, 그리고 다른 핵심 (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: 내부 오류가 발생했습니다: 리소스 할당 시간 초과

이러한 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

Dial tcp xxx.xx.x.x:xxx: i/o timeout

이 오류는 Kubernetes API 서버가 러너 관리자에 의해 접근 불가능하다는 것을 일반적으로 나타냅니다. 이 문제를 해결하려면 다음을 수행하세요:

  • 네트워크 보안 정책을 사용하는 경우, 일반적으로 443포트 또는 6443포트, 또는 둘 다에 대한 Kubernetes API 액세스를 허용합니다.
  • Kubernetes API가 실행 중인지 확인합니다.

Connection refused when attempting to communicate with the Kubernetes API

GitLab Runner가 Kubernetes API로 요청을 보내고 실패하는 경우, 일반적으로 kube-apiserver가 과부화되어 API 요청을 받거나 처리할 수 없는 상황입니다.

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

위의 오류는 Kubernetes가 작업 파드를 제때 예약하지 못할 때 발생합니다. GitLab Runner는 파드가 준비될 때까지 기다리지만 실패한 후에 파드를 정리하려고 시도하며, 이 또한 실패할 수 있습니다.

이 문제를 해결하려면 GitLab Runner가 파드가 준비 상태에 도달하기를 기다리는 시간을 변경하려면 poll_timeout 설정을 사용합니다.

팟이 어떻게 예약되거나 제때 예약되지 않는지에 대해 자세히 이해하려면 Kubernetes Scheduler에 대해 읽어보세요.

request did not complete within requested timeout

빌드 파드 생성 중에 관찰된 request did not complete within requested timeout 메시지는 구성된 admission control webhook이 제한 시간 내에 작동하지 않을 때 발생합니다.

결제 제어 웹훅은 그들이 대상으로 하는 모든 API 요청에 대한 클러스터 수준의 관리적 제어로, 제한 시간 내에 실행되지 않는다면 오류를 발생시킬 수 있습니다.

결제 제어 웹훅은 API 요청 및 네임스페이스 원본을 세밀하게 제어할 수 있는 필터를 지원합니다. GitLab Runner의 Kubernetes API 호출이 결제 제어 웹훅을 통과할 필요가 없다면 웹훅의 선택기/필터 구성을 변경하여 GitLab Runner 네임스페이스를 무시하도록 하거나, GitLab Runner 파드에 구성을 적용하여 제외되는 레이블/주석을 적용할 수 있습니다. (values.yaml 파일 내에서 podAnnotations 또는 podLabels를 구성함으로써)

예를 들어, DataDog Admission Controller webhook이 GitLab Runner 관리자 파드에 의한 API 요청을 가로채지 않도록하려면 다음과 같이 추가할 수 있습니다: yaml podLabels: admission.datadoghq.com/enabled: false

Kubernetes 클러스터의 결제 제어 웹훅 목록을 확인하려면 다음 명령어를 실행하세요: shell kubectl get validatingwebhookconfiguration -o yaml kubectl get mutatingwebhookconfiguration -o yaml

결제 제어 웹훅의 제한 시간 초과로 인한 실패는 다음과 같은 로그 형태로 나타날 수 있습니다:

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

결제 제어 웹훅에서의 실패는 다음과 같이 나타날 수 있습니다: plaintext Job failed (system failure): prepare environment: setting up credentials: 내부 오류가 발생했습니다: "example.webhook.service" 호출 실패

fatal: unable to access 'https://gitlab-ci-token:token@example.com/repo/proj.git/': 호스트 example.com을(를) 찾을 수 없습니다

만약 도우미 이미지alpine 플레이버를 사용하는 경우, 알파인의 musl DNS 리졸버와 관련된 DNS 문제가 발생할 수 있습니다.

helper_image_flavor = "ubuntu" 옵션을 사용하면 이 문제를 해결할 수 있습니다.

docker: tcp://docker:2375에 있는 Docker 데몬에 연결할 수 없습니다. docker 데몬이 실행 중입니까?

만약 Docker-in-Docker를 사용할 때 DIND 서비스에 완전히 시작되기 전에 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을 구성하여 러너 관리자 파드가 항상 Linux 노드에 예약되도록합니다. 예를 들어, values.yaml 파일은 다음과 같아야 합니다:

nodeSelector:
  kubernetes.io/os: linux

빌드 파드에는 워커 노드의 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.yml에서 pull_policy를 지정하였지만 Runner의 구성 파일에 정책이 구성되지 않은 경우 발생합니다. 이를 해결하려면 Docker pull policies 제한에 따라 구성에 allowed_pull_policies를 추가하세요.

백그라운드 프로세스가 작업을 멈추게하고 타임아웃이 발생합니다

작업 실행 중에 시작된 백그라운드 프로세스는 빌드 작업이 종료되지 못하게 할 수 있습니다. 이를 피하려면 다음을 수행할 수 있습니다:

  • 프로세스를 이중으로 fork하세요. 예를 들어, command_to_run < /dev/null &> /dev/null &.
  • 작업 스크립트를 종료하기 전에 프로세스를 종료하세요.

캐시 관련 permission denied 오류

작업에서 생성된 파일 및 폴더에는 특정한 UNIX 소유권과 권한이 있습니다. 파일 및 폴더가 아카이브 또는 추출될 때 UNIX 세부 정보가 유지되지만, 파일과 폴더가 도우미 이미지USER 구성과 일치하지 않을 수 있습니다.

만약 Creating cache ... 단계에서 권한 관련 오류가 발생하면 다음을 수행할 수 있습니다:

  • 소스 데이터가 수정되었는지 조사해 보세요. 예를 들어, 캐시된 파일을 생성하는 작업 스크립트에서 확인하세요.
  • 해결책으로, (before_/after_)script: 지시문에 일치하는 chownchmod 명령을 추가하세요.

빌드 컨테이너 내에서 이니시스템(init system)을 사용할 때 나타나는 겉으로는 중복된 셸 프로세스

프로세스 트리에는 다음 중 하나의 경우에 셸 프로세스가 포함될 수 있습니다.

  • FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGYfalse이고 FF_USE_DUMB_INIT_WITH_KUBERNETES_EXECUTORtrue인 경우
  • 빌드 이미지의 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 <---------------- 이게 뭐죠???
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

이 이니시스템(init system)에 의해 실행된 셸 검출 스크립트에 의해 시작된 이 셸 프로세스(sh, bash, 또는 busybox일 수 있음)는 PPID가 1이고 PID가 6 또는 7인 경우가 있습니다. 이 프로세스는 중복된 것이 아니며, 빌드 컨테이너에서 이니시스템을 사용할 때의 전형적인 작업입니다.

실행자(runner) 파드가 성공적으로 등록되었음에도 작업 실행에 실패하고 제한 시간이 경과하는 문제

실행자(runner) 파드가 GitLab과 등록된 후 작업을 실행하려고 하지만 실행되지 않고 결국 작업이 시간 초과됩니다. 다음과 같은 오류가 보고됩니다.

시간 초과 실패 또는 작업이 멈춘 상태입니다. 시간 초과 제한을 확인하거나 다시 시도하세요.

이 작업에는 추적이 없습니다.

이 경우, 실행자가 다음과 같은 오류를 받을 수 있습니다.

`jobs/request` API에 연결할 때 HTTP 204 내용 없음 응답 코드.

이 문제를 해결하려면 수동으로 API에 POST 요청을 보내어 TCP 연결이 대기 중인지 확인하십시오. TCP 연결이 대기 중인 경우, 실행자는 CI 작업 페이로드를 요청하지 못할 수 있습니다.

gcs-fuse-csi-driver를 사용할 때 init-permissions 컨테이너의 이름을 예약하는 데 실패함

gcs-fuse-csi-driver csi 드라이버는 이니셜라이징(init) 컨테이너에 대한 볼륨을 마운트하는 것을 지원하지 않습니다. 이로 인해 이 드라이버를 사용할 때 이니셜라이징(init) 컨테이너를 시작하는 데 실패할 수 있습니다. 이 버그를 해결하려면 드라이버 프로젝트에서 Kubernetes 1.28에서 도입된 기능을 지원해야 합니다.