Autopilot 클러스터 문제 해결


이 페이지에서는 Google Kubernetes Engine(GKE) Autopilot 클러스터의 문제를 해결하는 방법을 설명합니다.

추가 지원이 필요하면 Cloud Customer Care에 연락합니다.

클러스터 문제

클러스터를 만들 수 없음: 등록된 노드 0개

다음 문제는 사용 중지되었거나 필요한 권한이 없는 IAM 서비스 계정으로 Autopilot 클러스터를 만들려고 할 때 발생합니다. 다음 오류 메시지와 함께 클러스터 만들기가 실패합니다.

All cluster resources were brought up, but: only 0 nodes out of 2 have registered.

문제를 해결하려면 다음 단계를 따르세요.

  1. 기본 Compute Engine 서비스 계정 또는 사용하려는 커스텀 IAM 서비스 계정이 사용 중지되었는지 확인합니다.

    gcloud iam service-accounts describe SERVICE_ACCOUNT
    

    SERVICE_ACCOUNTmy-iam-account@my-first-project.iam.gserviceaccount.com과 같은 서비스 계정 이메일 주소로 바꿉니다.

    서비스 계정이 사용 중지되면 출력이 다음과 비슷하게 표시됩니다.

    disabled: true
    displayName: my-service-account
    email: my-service-account@my-project.iam.gserviceaccount.com
    ...
    
  2. 서비스 계정이 사용 중지된 경우 사용 설정합니다.

    gcloud iam service-accounts enable SERVICE_ACCOUNT
    

서비스 계정을 사용 설정했지만 오류가 지속되면 서비스 계정에 GKE에 필요한 최소 사용 권한을 부여합니다:

gcloud projects add-iam-policy-binding PROJECT_ID \
    --member "serviceAccount:SERVICE_ACCOUNT" \
    --role roles/container.nodeServiceAccount

클러스터에 노드가 0개 있을 때 종료 중 네임스페이스가 종료 중 상태로 멈춤

클러스터가 0개 노드로 축소된 후 클러스터에서 네임스페이스를 삭제하면 다음 문제가 발생합니다. metrics-server 구성요소에 복제본이 없으므로 네임스페이스 삭제 요청을 수락할 수 없습니다.

이 문제를 진단하려면 다음 명령어를 실행하세요.

kubectl describe ns/NAMESPACE_NAME

NAMESPACE_NAME를 네임스페이스 이름으로 바꿉니다.

출력은 다음과 같습니다.

Discovery failed for some groups, 1 failing: unable to retrieve the complete
list of server APIs: metrics.k8s.io/v1beta1: the server is currently unable to
handle the request

이 문제를 해결하려면 GKE를 트리거하여 새 노드를 만들도록 워크로드를 확장합니다. 노드가 준비되면 네임스페이스 삭제 요청이 자동으로 완료됩니다. GKE가 네임스페이스를 삭제한 후 워크로드를 다시 축소합니다.

확장 문제

노드 확장 실패: 포드가 예약되지 않을 위험이 있습니다.

Google Cloud 프로젝트에서 직렬 포트 로깅이 사용 중지되었으면 다음 문제가 발생합니다. 노드 문제를 효율적으로 디버깅하려면 GKE Autopilot 클러스터에 직렬 포트 로깅이 필요합니다. 직렬 포트 로깅이 사용 중지되었으면 Autopilot가 워크로드를 실행할 노드를 프로비저닝할 수 없습니다.

Kubernetes 이벤트 로그의 오류 메시지는 다음과 비슷합니다.

LAST SEEN   TYPE      REASON          OBJECT                          MESSAGE
12s         Warning   FailedScaleUp   pod/pod-test-5b97f7c978-h9lvl   Node scale up in zones associated with this pod failed: Internal error. Pod is at risk of not being scheduled

compute.disableSerialPortLogging 제약조건을 적용하는 조직 정책을 통해 조직 수준에서 직렬 포트 로깅을 사용 중지할 수 있습니다. 프로젝트 또는 가상 머신(VM) 인스턴스 수준에서 직렬 포트 로깅이 사용 중지될 수도 있습니다.

이 문제를 해결하려면 다음 단계를 따르세요.

  1. Google Cloud 조직 정책 관리자에게 Autopilot 클러스터가 있는 프로젝트에서 compute.disableSerialPortLogging 제약조건을 삭제하도록 요청합니다.
  2. 이 제약조건을 적용하는 조직 정책이 없으면 프로젝트 메타데이터에서 직렬 포트 로깅을 사용 설정해보세요. 이 작업에는 compute.projects.setCommonInstanceMetadata IAM 권한이 필요합니다.

노드 수직 확장 실패: GCE 리소스 부족

워크로드가 Compute Engine 리전 또는 영역에서 사용 가능한 것보다 많은 리소스를 요청할 때 다음 문제가 발생합니다. 포드가 Pending 상태로 유지될 수 있습니다.

  • 포드 이벤트를 확인합니다.

    kubectl events --for='pod/POD_NAME' --types=Warning
    

    RESOURCE_NAME을 보류 중인 Kubernetes 리소스 이름으로 바꿉니다. 예를 들면 pod/example-pod입니다.

    출력은 다음과 비슷합니다.

    LAST SEEN         TYPE            REASON                  OBJECT                   Message
    19m               Warning         FailedScheduling        pod/example-pod          gke.io/optimize-utilization-scheduler  0/2 nodes are available: 2 node(s) didn't match Pod's node affinity/selector. preemption: 0/2 nodes are available: 2 Preemption is not helpful for scheduling.
    14m               Warning         FailedScheduling        pod/example-pod          gke.io/optimize-utilization-scheduler  0/2 nodes are available: 2 node(s) didn't match Pod's node affinity/selector. preemption: 0/2 nodes are available: 2 Preemption is not helpful for scheduling.
    12m (x2 over 18m) Warning         FailedScaleUp           cluster-autoscaler       Node scale up in zones us-central1-f associated with this pod failed: GCE out of resources. Pod is at risk of not being scheduled.
    34s (x3 over 17m) Warning         FailedScaleUp           cluster-autoscaler       Node scale up in zones us-central1-b associated with this pod failed: GCE out of resources. Pod is at risk of not being scheduled.
    

이 문제를 해결하려면 다음을 시도해 보세요.

  • 포드를 다른 리전 또는 영역에 배포합니다. 포드에 토폴로지 선택기와 같은 영역 제한이 있으면 가능한 경우 해당 제한을 삭제합니다. 자세한 내용은 특정 영역에 GKE 포드 배치를 참조하세요.
  • 다른 리전에 클러스터를 만들고 배포를 다시 시도합니다.
  • 다른 컴퓨팅 클래스를 사용해 봅니다. 더 작은 Compute Engine 머신 유형으로 지원되는 컴퓨팅 클래스는 사용 가능한 리소스가 포함될 가능성이 더 높습니다. 예를 들어 Autopilot의 기본 머신 유형은 가용성이 가장 좋습니다. 컴퓨팅 클래스 및 해당 머신 유형 목록은 특정 컴퓨팅 클래스를 사용해야 하는 경우를 참조하세요.
  • GPU 워크로드를 실행할 때 노드 위치에서 요청된 GPU를 사용하지 못할 수 있습니다. 다른 위치에 워크로드를 배포하거나 다른 유형의 GPU를 요청해 보세요.

이후 리소스 가용성으로 인한 수직 확장 문제를 방지하려면 다음 접근 방법을 고려하세요.

노드 확장 실패: 포드 영역 리소스 초과

새 노드가 리소스 한도를 위반하여 Autopilot이 특정 영역의 포드에 대해 새 노드를 프로비저닝하지 않으면 다음 문제가 발생합니다.

로그의 오류 메시지는 다음과 비슷합니다.

    "napFailureReasons": [
            {
              "messageId": "no.scale.up.nap.pod.zonal.resources.exceeded",
              ...

이 오류는 노드 자동 프로비저닝이 영역 내 포드의 노드 그룹을 프로비저닝하지 않았을 때의 noScaleUp 이벤트를 나타냅니다.

이 오류가 발생하면 다음을 확인하세요.

워크로드 문제

임시 스토리지 오류로 워크로드 중단

포드 임시 스토리지 요청이 GKE 버전 1.28.6-gke.1317000 이상에서 Autopilot 최댓값인 10GiB를 초과하면 GKE가 포드를 만들지 않습니다.

이 문제를 진단하려면 배포 또는 작업과 같은 워크로드 컨트롤러를 설명합니다.

kubectl describe CONTROLLER_TYPE/CONTROLLER_NAME

다음을 바꿉니다.

  • CONTROLLER_TYPE: 워크로드 컨트롤러의 유형(예: replicaset 또는 daemonset)입니다. 컨트롤러 유형 목록은 워크로드 관리를 참조하세요.
  • CONTROLLER_NAME: 중단된 워크로드의 이름입니다.

임시 스토리지 요청이 최댓값을 초과하여 포드가 생성되지 않은 경우 출력은 다음과 비슷합니다.

# lines omitted for clarity

Events:

{"[denied by autogke-pod-limit-constraints]":["Max ephemeral-storage requested by init containers for workload '' is higher than the Autopilot maximum of '10Gi'.","Total ephemeral-storage requested by containers for workload '' is higher than the Autopilot maximum of '10Gi'."]}

이 문제를 해결하려면 워크로드 컨테이너와 웹훅이 삽입하는 컨테이너에서 요청한 총 임시 스토리지가 허용된 최댓값보다 작거나 같도록 임시 스토리지 요청을 업데이트합니다. 최댓값에 대한 자세한 내용은 워크로드 구성에 대한 Autopilot의 리소스 요청을 참조하세요.

포드가 대기중 상태로 멈춰 있음

포드에 사용할 특정 노드를 선택하면 포드가 Pending 상태로 멈춰 있을 수 있지만 노드에서 실행해야 하는 포드 및 DaemonSets의 리소스 요청 합계가 노드의 최대 할당 가능 용량을 초과합니다. 이로 인해 포드가 Pending 상태가 되고 예약되지 않은 상태로 유지될 수 있습니다.

이 문제를 방지하려면 배포된 워크로드 크기가 Autopilot에 대해 지원되는 최대 리소스 요청 이내인지 확인합니다.

일반 워크로드 포드를 예약하기 전에 DaemonSet를 예약해 볼 수도 있습니다.

종료 또는 생성 중에 포드가 멈춤

알려진 문제로 인해 간혹 포드가 다음 상태 중 하나로 중단됩니다.

  • Terminating
  • CreateContainerError

GKE 환경에서 다음 조건을 모두 충족하는 버스팅 가능한 포드를 사용할 때는 이 문제가 발생할 가능성이 거의 없습니다.

  1. 노드는 1.29.2-gke.1060000부터 1.30.2-gke.1394000 이전까지의 GKE 버전을 실행합니다.
  2. 포드에서 다음 컴퓨팅 클래스 중 하나를 사용합니다.
    • 기본 범용 컴퓨팅 클래스
    • Balanced 컴퓨팅 클래스
    • Scale-Out 컴퓨팅 클래스

이 문제를 완화하려면 컨트롤 플레인을 GKE 버전 1.30.2-gke.1394000 이상으로 업그레이드합니다. 이미 Terminating 상태 또는 CreateContainerError 상태로 중단된 포드는 GKE에서 고정된 버전을 실행하는 노드에서 포드를 다시 만든 후에 올바르게 배포됩니다.

Autopilot 클러스터를 업그레이드하면 GKE는 시간 경과에 따라 컨트롤 플레인 버전과 일치하도록 워커 노드를 업그레이드합니다. 버스팅을 사용 설정하려면 컨트롤 플레인을 다시 시작해야 하며 모든 노드가 지원되는 버전을 실행한 후에 진행되어야 합니다. 확장, 업그레이드 또는 유지보수와 같은 작업 중에는 컨트롤 플레인이 일주일에 한 번 정도 자동으로 다시 시작됩니다.

컨트롤 플레인 재시작을 수동으로 트리거하려면 다음을 수행합니다.

  1. 모든 노드에서 버전 1.30.2-gke.1349000 이상을 실행하는지 확인합니다.

    kubectl get nodes
    

    출력은 다음과 비슷합니다.

    NAME                                          STATUS   ROLES    AGE     VERSION
    gk3-ap-cluster-1-default-pool-18092e49-mllk   Ready    <none>   4m26s   v1.30.2-gke.1349000
    

    출력의 모든 노드는 필수 버전 이상을 표시해야 합니다.

  2. 클러스터에서 이미 사용 중인 버전과 동일한 버전으로 컨트롤 플레인 업그레이드를 수동으로 시작합니다. 자세한 내용은 컨트롤 플레인 수동 업그레이드를 참조하세요.

특정 노드에서 지속적으로 신뢰할 수 없는 워크로드 성능

GKE 버전 1.24 이상에서 특정 노드의 워크로드에 중단, 비정상 종료 또는 이와 유사한 신뢰할 수 없는 동작이 지속적으로 발생하는 경우 다음 명령어를 사용하여 문제가 있는 노드를 차단하고 이를 GKE에 알릴 수 있습니다.

kubectl drain NODE_NAME --ignore-daemonsets

NODE_NAME을 문제가 있는 노드의 이름으로 바꿉니다. kubectl get nodes를 실행하면 멤버십 이름을 찾을 수 있습니다.

GKE는 다음을 수행합니다.

  • 노드에서 기존 워크로드를 제거하고 해당 노드에서 워크로드 예약을 중지합니다.
  • 배포 또는 StatefulSet와 같은 컨트롤러에서 관리하는 제거된 워크로드를 다른 노드에서 자동으로 다시 만듭니다.
  • 노드에 남아 있는 모든 워크로드를 종료하고 향후 노드를 복구하거나 다시 만듭니다.
  • Autopilot을 사용하면 GKE는 노드를 즉시 종료하고 교체하며 구성된 모든 PodDisruptionBudgets을 무시합니다.

포드를 빈 클러스터에서 예약하는 데 예상보다 오래 걸림

이 이벤트는 다른 워크로드가 없는 Autopilot 클러스터에 워크로드를 배포할 때 발생합니다. Autopilot 클러스터는 사용 가능한 노드가 0개인 상태로 시작하고 클러스터가 비어 있는 경우 클러스터에서 컴퓨팅 리소스가 사용되지 않도록 노드가 0개로 조정됩니다. 노드가 0개인 클러스터에 워크로드를 배포하면 확장 이벤트가 트리거됩니다.

이 이벤트가 발생하면 Autopilot이 의도한 대로 작동한 것이며 별도의 조치가 필요하지 않습니다. 새 노드가 부팅된 후 워크로드가 예상대로 배포됩니다.

포드가 새 노드를 기다리는지 확인합니다.

  1. 대기 중인 포드를 설명합니다.

    kubectl describe pod POD_NAME
    

    POD_NAME을 대기 중인 포드의 이름으로 바꿉니다.

  2. 출력의 Events 섹션을 확인합니다. 포드가 새 노드를 기다리는 경우 출력은 다음과 비슷합니다.

    Events:
      Type     Reason            Age   From                                   Message
      ----     ------            ----  ----                                   -------
      Warning  FailedScheduling  11s   gke.io/optimize-utilization-scheduler  no nodes available to schedule pods
      Normal   TriggeredScaleUp  4s    cluster-autoscaler                     pod triggered scale-up: [{https://www.googleapis.com/compute/v1/projects/example-project/zones/example-zone/instanceGroups/gk3-example-cluster-pool-2-9293c6db-grp 0->1 (max: 1000)} {https://www.googleapis.com/compute/v1/projects/example-project/zones/example-zone/instanceGroups/gk3-example-cluster-pool-2-d99371e7-grp 0->1 (max: 1000)}]
    

    TriggeredScaleUp 이벤트는 클러스터가 배포된 워크로드를 실행하는 데 필요한 노드 수만큼 클러스터가 노드 0개에서 확장되고 있음을 보여줍니다.

GKE Autopilot 클러스터에서는 기본 노드에 대한 액세스가 금지됩니다. 따라서 포드 내에서 tcpdump 유틸리티를 실행한 다음 kubectl cp 명령어를 사용하여 이를 복사해야 합니다. 일반적으로 GKE Autopilot 클러스터의 포드 내에서 tcpdump 유틸리티를 실행하는 경우 다음 오류가 표시될 수 있습니다.

    tcpdump: eth0: You don't have permission to perform this capture on that device
    (socket: Operation not permitted)

이는 기본적으로 GKE Autopilot이 잠재적인 취약점을 완화하기 위해 NET_RAW 기능을 삭제하는 보안 컨텍스트를 모든 포드에 적용하기 때문에 발생합니다. 예를 들면 다음과 같습니다.

apiVersion: v1
kind: Pod
metadata:
  labels:
    app: tcpdump
  name: tcpdump
spec:
  containers:
  - image: nginx
    name: nginx
    resources:
      limits:
        cpu: 500m
        ephemeral-storage: 1Gi
        memory: 2Gi
      requests:
        cpu: 500m
        ephemeral-storage: 1Gi
        memory: 2Gi
    securityContext:
      capabilities:
        drop:
        - NET_RAW

해결 방법으로, 워크로드에 NET_RAW 기능이 필요한 경우 다시 사용 설정할 수 있습니다.

  1. 포드 YAML 사양의 securityContext 섹션에 NET_RAW 기능을 추가합니다.

    securityContext:
      capabilities:
        add:
        - NET_RAW
    
  2. 포드 내에서 tcpdump를 실행합니다.

    tcpdump port 53 -w packetcap.pcap
    tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
    
  3. kubectl cp 명령어를 사용하여 추가 분석을 위해 로컬 머신에 복사합니다.

    kubectl cp POD_NAME:/PATH_TO_FILE/FILE_NAME/PATH_TO_FILE/FILE_NAME
    
  4. kubectl exec를 사용해서 네트워크 패킷 캡처를 수행하고 출력을 리디렉션하도록 tcpdump 명령어를 실행합니다.

    kubectl exec -it POD_NAME -- bash -c "tcpdump port 53 -w -" > packet-new.pcap
    

다음 단계

추가 지원이 필요하면 Cloud Customer Care에 문의하세요.