Kubernetes executor 문제 해결

Kubernetes executor를 사용할 때 일반적으로 발생하는 다음과 같은 오류들이 있습니다.

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

poll_timeout로 정의된 시간 내에 빌드 pod를 예약할 수 없으면 빌드 pod가 오류를 반환합니다. Kubernetes 스케줄러가 삭제할 수 있어야 합니다.

이 문제를 해결하려면 config.toml 파일에서 poll_timeout 값을 늘리세요.

context deadline exceeded

작업 로그에서의 context deadline exceeded 오류는 일반적으로 특정 클러스터 API 요청에 대해 Kubernetes API 클라이언트가 시간 초과에 걸린 것을 나타냅니다.

kube-apiserver 클러스터 컴포넌트의 메트릭를 확인하여 다음과 같은 증상이 있는지 확인하세요:

  • 응답 대기 시간이 증가함.
  • pod, 시크릿(Secrets), ConfigMaps 및 다른 코어(v1) 자원에 대한 일반 create 또는 delete 작업의 오류율.

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 오류 응답이 하위 컴포넌트의 실패에 대한 추가 세부 정보를 제공할 수 있습니다 (etcdserver와 같은 Kubernetes 클러스터의) 경우.:

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 서비스 실패는 빌드 pod를 생성하는 동안 또는 완료 후의 정리 시도 중에 발생할 수 있습니다:

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 서버가 러너 관리자에 의해 접근할 수 없을 때 발생하는 Kubernetes 오류입니다. 이 문제를 해결하려면:

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

Kubernetes API와의 통신 시 연결 거부

GitLab Runner가 Kubernetes API에 요청을 보내고 실패할 때, 일반적으로 kube-apiserver가 과부하되어 API 요청을 수락하거나 처리할 수 없을 수 있습니다.

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

이러한 오류는 Kubernetes가 작업 pod를 적시에 예약하지 못하는 경우에 발생합니다. GitLab Runner는 pod가 준비 상태가 될 때까지 기다리지만 실패하고 pod를 정리하려고 하지만 그것 역시 실패할 수 있습니다.

request did not complete within requested timeout

request did not complete within requested timeout 메시지는 빌드 pod 생성 중에 구성된 admission control webhook이 시간 초과되었음을 나타냅니다.

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

[alpine flavor의 helper image를 사용하는 경우 Alpine의 musl의 DNS resolver와 관련된 DNS 문제가 발생할 수 있습니다.

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

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는 서비스 정의 내에서 변경할 수 있습니다.

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

이 문제는 노드 셀렉터를 사용하여 다른 운영 체제 및 아키텍처를 갖는 노드에서 빌드를 실행할 때 발생합니다.

문제를 해결하려면러너(runner) 매니저 파드가 항상 Linux 노드에 예약되도록 nodeSelector를 구성하세요. 예를 들어, values.yaml 파일에 다음을 추가해야 합니다.

nodeSelector:
  kubernetes.io/os: linux

Build pods are assigned the worker node’s IAM role instead of Runner IAM role

작업 노드 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 정책 제한에 따라 구성에 allowed_pull_policies를 추가하세요.

백그라운드 프로세스로 인해 작업이 멈추고 시간이 초과됨

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

  • 프로세스를 두 번 포크합니다. 예를 들어, command_to_run < /dev/null &> /dev/null &.
  • 작업 스크립트를 종료하기 전에 프로세스를 중지합니다.

캐시 관련 permission denied 오류

작업에서 생성된 파일 및 폴더는 특정한 UNIX 소유권 및 권한을 가집니다. 파일 및 폴더가 보관되거나 추출될 때 UNIX 세부 정보가 유지됩니다. 그러나 파일 및 폴더는 도우미 이미지USER 구성과 일치하지 않을 수 있습니다.

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

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

init 시스템이 있는 빌드 컨테이너의 불필요한 쉘 프로세스

프로세스 트리에 불필요한 쉘 프로세스가 포함될 수 있습니다.

  • FF_USE_LEGACY_KUBERNETES_EXECUTION_STRATEGYfalse이고 FF_USE_DUMB_INIT_WITH_KUBERNETES_EXECUTORtrue인 경우.
  • 빌드 이미지의 ENTRYPOINT가 init 시스템(예: 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

초기화 시스템(PID 1 위)에서 실행된 쉘 감지 스크립트에 의해 시작된 쉘 프로세스로, sh, bash, 또는 busybox일 수 있으며, PPID가 1이고 PID가 6 또는 7입니다. 이 프로세스는 불필요하지 않으며, 빌드 컨테이너가 초기화 시스템과 함께 실행될 때 일반적인 동작입니다.

러너 파드가 작업 실행에 실패하고 시간이 초과되지만 등록은 성공한 경우

러너 파드가 GitLab에 등록한 후 작업을 실행을 시도하지만 실행되지 않고 작업이 최종적으로 시간 초과됩니다. 다음과 같은 오류가 보고됩니다.

작업 시간 초과 또는 작업이 멈춘 경우 타임아웃 제한을 확인하거나 다시 시도하세요.

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

이 경우 러너가 다음과 같은 오류를 받을 수 있습니다.

`jobs/request` API에 연결할 때 HTTP 204 콘텐츠 없음 응답 코드가 발생했습니다.

이 문제를 해결하려면 TCP 연결이 매달리는지 확인하려면 API에 매뉴얼으로 POST 요청을 보내서 확인하세요. TCP 연결이 매달리는 경우 러너가 CI 잡 payload를 요청할 수 없을 수 있습니다.

failed to reserve container name for init-permissions container when gcs-fuse-csi-driver is used

gcs-fuse-csi-driver csi 드라이버가 이 드라이버를 사용할 때 init 컨테이너에 볼륨을 마운트하는 것을 지원하지 않습니다. 이로 인해이 드라이버를 사용할 때 init 컨테이너 시작 시 failed to reserve container name 오류가 발생할 수 있습니다. 이 버그를 해결하려면 드라이버의 프로젝트에서 Kubernetes 1.28에서 도입된 기능을 지원해야 합니다.