GKE에서 NotReady 상태의 노드 문제 해결

Google Kubernetes Engine (GKE)의 NotReady 상태는 노드의 kubelet이 제어 영역에 올바르게 보고하지 않음을 의미합니다. Kubernetes는 NotReady 노드에 새 포드를 예약하지 않으므로 이 문제로 인해 애플리케이션 용량이 줄어들고 다운타임이 발생할 수 있습니다.

이 문서를 사용하여 예상되는 NotReady 상태와 실제 문제를 구분하고, 근본 원인을 진단하고, 리소스 소진, 네트워크 문제, 컨테이너 런타임 실패와 같은 일반적인 문제의 해결 방법을 찾으세요.

이 정보는 클러스터 안정성을 담당하는 플랫폼 관리자 및 운영자와 인프라 관련 애플리케이션 동작을 이해하려는 애플리케이션 개발자를 위한 것입니다. Google Cloud 콘텐츠에서 참조하는 일반적인 역할과 예시 태스크에 대한 자세한 내용은 일반 GKE 사용자 역할 및 태스크를 참고하세요.

시작하기 전에

  • 이 문서의 태스크를 수행하는 데 필요한 권한을 얻으려면 관리자에게 프로젝트에 대한 다음 IAM 역할을 부여해 달라고 요청하세요. Google Cloud

    역할 부여에 대한 자세한 내용은 프로젝트, 폴더, 조직에 대한 액세스 관리를 참조하세요.

    커스텀 역할이나 다른 사전 정의된 역할을 통해 필요한 권한을 얻을 수도 있습니다.

  • GKE 클러스터와 통신하도록 kubectl 명령줄 도구를 구성합니다.

    gcloud container clusters get-credentials CLUSTER_NAME \
        --location LOCATION \
        --project PROJECT_ID
    

    다음을 바꿉니다.

    • CLUSTER_NAME: 클러스터 이름입니다.
    • LOCATION: 클러스터의 Compute Engine 리전 또는 영역(예: us-central1 또는 us-central1-a)
    • PROJECT_ID: Google Cloud 프로젝트 ID입니다.

노드의 상태 및 조건 확인

노드의 상태가 NotReady인지 확인하고 근본 원인을 진단하려면 다음 단계에 따라 노드의 조건, 이벤트, 로그, 리소스 측정항목을 검사하세요.

  1. 노드의 상태를 확인합니다. 진단에 유용한 IP 주소 및 커널 버전과 같은 추가 세부정보를 확인하려면 -o wide 플래그를 사용하세요.

    kubectl get nodes -o wide
    

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

    NAME                                STATUS     ROLES    AGE   VERSION               INTERNAL-IP  EXTERNAL-IP  OS-IMAGE                             KERNEL-VERSION   CONTAINER-RUNTIME
    gke-cluster-pool-1-node-abc1        Ready      <none>   94d   v1.32.3-gke.1785003   10.128.0.1   1.2.3.4      Container-Optimized OS from Google   6.6.72+          containerd://1.7.24
    gke-cluster-pool-1-node-def2        Ready      <none>   94d   v1.32.3-gke.1785003   10.128.0.2   5.6.7.8      Container-Optimized OS from Google   6.6.72+          containerd://1.7.24
    gke-cluster-pool-1-node-ghi3        NotReady   <none>   94d   v1.32.3-gke.1785003   10.128.0.3   9.10.11.12   Container-Optimized OS from Google   6.6.72+          containerd://1.7.24
    

    출력에서 STATUS 열의 값이 NotReady인 노드를 찾아 이름을 기록해 둡니다.

  2. 조건 및 최근 Kubernetes 이벤트를 비롯하여 NotReady 상태의 특정 노드에 관한 자세한 정보를 확인합니다.

    kubectl describe node NODE_NAME
    

    NODE_NAMENotReady 상태의 노드 이름으로 바꿉니다.

    출력에서 Conditions 섹션을 통해 노드의 상태를 파악하고 Events 섹션을 통해 최근 문제의 기록을 확인합니다. 예를 들면 다음과 같습니다.

    Name:                   gke-cluster-pool-1-node-ghi3
    ...
    Conditions:
    Type                          Status    LastHeartbeatTime                 LastTransitionTime                Reason                   Message
    ----                          ------    -----------------                 ------------------                ------                   -------
    NetworkUnavailable            False     Wed, 01 Oct 2025 10:29:19 +0100   Wed, 01 Oct 2025 10:29:19 +0100   RouteCreated             RouteController created a route
    MemoryPressure                Unknown   Wed, 01 Oct 2025 10:31:06 +0100   Wed, 01 Oct 2025 10:31:51 +0100   NodeStatusUnknown        Kubelet stopped posting node status.
    DiskPressure                  Unknown   Wed, 01 Oct 2025 10:31:06 +0100   Wed, 01 Oct 2025 10:31:51 +0100   NodeStatusUnknown        Kubelet stopped posting node status.
    PIDPressure                   False     Wed, 01 Oct 2025 10:31:06 +0100   Wed, 01 Oct 2025 10:29:00 +0100   KubeletHasSufficientPID  kubelet has sufficient PID available
    Ready                         Unknown   Wed, 01 Oct 2025 10:31:06 +0100   Wed, 01 Oct 2025 10:31:51 +0100   NodeStatusUnknown        Kubelet stopped posting node status.
    Events:
    Type     Reason                   Age                  From                                   Message
    ----     ------                   ----                 ----                                   -------
    Normal   Starting                 32m                  kubelet, gke-cluster-pool-1-node-ghi3  Starting kubelet.
    Warning  PLEGIsNotHealthy         5m1s (x15 over 29m)  kubelet, gke-cluster-pool-1-node-ghi3  PLEG is not healthy: pleg was last seen active 5m1.123456789s ago; threshold is 3m0s
    Normal   NodeHasSufficientMemory  5m1s (x16 over 31m)  kubelet, gke-cluster-pool-1-node-ghi3  Node gke-cluster-pool-1-node-ghi3 status is now: NodeHasSufficientMemory
    

    Conditions 섹션에서 부정적인 조건의 상태가 True이거나 Ready 조건의 상태가 Unknown이면 문제가 있음을 나타냅니다. 이러한 조건의 ReasonMessage 필드는 문제의 원인을 설명하므로 주의 깊게 살펴보세요.

    각 조건 유형의 의미는 다음과 같습니다.

    • KernelDeadlock: 노드의 운영체제 커널에서 교착 상태를 감지한 경우 True입니다. 교착 상태는 노드를 정지시킬 수 있는 심각한 오류입니다.
    • FrequentUnregisterNetDevice: 노드가 네트워크 기기를 자주 등록 해제하는 경우 True입니다. 이는 드라이버 또는 하드웨어 문제의 신호일 수 있습니다.
    • NetworkUnavailable: 노드의 네트워킹이 올바르게 구성되지 않은 경우 True
    • OutOfDisk: 사용 가능한 디스크 공간이 완전히 소진된 경우 True입니다. 이 조건은 DiskPressure보다 심각합니다.
    • MemoryPressure: 노드 메모리가 부족한 경우 True
    • DiskPressure: 노드의 디스크 공간이 부족한 경우 True입니다.
    • PIDPressure: 노드에서 프로세스 ID (PID) 소진이 발생하는 경우 True
    • Ready: 노드가 정상이고 포드를 수락할 준비가 되었는지 나타냅니다.
      • 노드가 정상인 경우 True
      • False 노드가 비정상이고 포드를 수락하지 않는 경우
      • 노드 컨트롤러가 유예 기간 (기본값은 50초) 동안 노드로부터 소식을 듣지 못했고 노드 상태가 알 수 없는 경우 Unknown

    다음으로 노드에 관한 작업 및 관찰의 시간순 로그를 제공하는 Events 섹션을 살펴봅니다. 이 타임라인은 노드가 NotReady가 되기 직전에 발생한 상황을 이해하는 데 중요합니다. 제거 경고 (리소스 압력을 나타냄), 실패한 상태 점검 또는 수리를 위한 격리와 같은 노드 수명 주기 이벤트와 같이 원인을 찾는 데 도움이 되는 특정 메시지를 찾습니다.

  3. 노드의 상태가 NotReady인 이유를 자세히 알아보려면 노드 및 구성요소의 로그를 확인하세요.

    1. kubelet 로그에서 NotReady 상태를 확인합니다.

      kubelet는 노드의 상태를 컨트롤 플레인에 보고하는 기본 에이전트이므로 로그에서 NotReady 메시지를 찾을 가능성이 가장 높습니다. 이러한 로그는 포드 수명 주기 이벤트, 리소스 압력 조건 (예: MemoryPressure 또는 DiskPressure), Kubernetes 컨트롤 플레인에 대한 노드의 연결 문제를 진단하는 데 사용되는 공신력 있는 소스입니다.

    2. Google Cloud 콘솔에서 로그 탐색기 페이지로 이동합니다.

      로그 탐색기로 이동

    3. 쿼리 창에 다음 쿼리를 입력합니다.

      resource.type="k8s_node"
      resource.labels.node_name="NODE_NAME"
      resource.labels.cluster_name="CLUSTER_NAME"
      resource.labels.location="LOCATION"
      log_id("kubelet")
      textPayload=~"(?i)NotReady"
      

      다음을 바꿉니다.

      • NODE_NAME: 조사 중인 노드의 이름
      • CLUSTER_NAME: 클러스터 이름입니다.
      • LOCATION: 클러스터의 Compute Engine 리전 또는 영역입니다 (예: us-central1 또는 us-central1-a).
    4. 쿼리 실행을 클릭하고 결과를 검토합니다.

    5. kubelet 로그에 근본 원인이 표시되지 않으면 container-runtimenode-problem-detector 로그를 확인합니다. 이러한 구성요소는 NotReady 상태를 직접 로깅하지 않을 수 있지만 문제를 일으킨 기본 문제 (예: 런타임 실패 또는 커널 패닉)를 로깅하는 경우가 많습니다.

    6. 로그 탐색기 쿼리 창에 다음 쿼리를 입력합니다.

      resource.type="k8s_node"
      resource.labels.node_name="NODE_NAME"
      resource.labels.cluster_name="CLUSTER_NAME"
      resource.labels.location="LOCATION"
      log_id("COMPONENT_NAME")
      

      COMPONENT_NAME을 다음 값 중 하나로 바꿉니다.

      • container-runtime: 이미지 가져오기 및 컨테이너 실행 관리를 비롯한 전체 컨테이너 수명 주기를 담당하는 런타임 (containerd)입니다. container-runtime 로그를 검토하는 것은 컨테이너 인스턴스화, 런타임 서비스 오류 또는 런타임의 구성으로 인해 발생하는 문제와 관련된 실패를 해결하는 데 필수적입니다.
      • node-problem-detector: 다양한 노드 수준 문제를 컨트롤 플레인에 사전 모니터링하고 보고하는 유틸리티입니다. 이 구성요소의 로그는 다른 Kubernetes 구성요소에서 포착되지 않을 수 있는 커널 교착 상태, 파일 시스템 손상, 하드웨어 장애와 같은 노드 불안정을 유발할 수 있는 기본 시스템 문제를 식별하는 데 중요합니다.
    7. 쿼리 실행을 클릭하고 결과를 검토합니다.

  4. 측정항목 탐색기를 사용하여 노드가 NotReady가 된 시점의 리소스 소진을 확인합니다.

    1. Google Cloud 콘솔에서 측정항목 탐색기 페이지로 이동합니다.

      측정항목 탐색기로 이동

    2. 측정항목 탐색기에서 노드의 기본 Compute Engine 인스턴스에 리소스 소진이 있는지 확인합니다. CPU, 메모리, 디스크 I/O 측정항목과 관련된 측정항목에 집중합니다. 예를 들면 다음과 같습니다.

      • GKE 노드 측정항목: kubernetes.io/node/ 프리픽스가 지정된 측정항목(예: kubernetes.io/node/cpu/allocatable_utilization 또는 kubernetes.io/node/memory/allocatable_utilization)으로 시작합니다. 이러한 측정항목은 노드의 사용 가능한 리소스 중 포드에서 사용 중인 리소스의 양을 보여줍니다. 사용 가능한 양에는 Kubernetes가 시스템 오버헤드를 위해 예약한 리소스가 포함되지 않습니다.
      • 게스트 OS 측정항목: 노드의 운영체제 내부에서 보려면 compute.googleapis.com/guest/로 시작하는 측정항목(예: compute.googleapis.com/guest/cpu/usage 또는 compute.googleapis.com/guest/memory/bytes_used)을 사용합니다.
      • 하이퍼바이저 측정항목: 하이퍼바이저 수준에서 VM의 성능을 확인하려면 compute.googleapis.com/instance/로 시작하는 측정항목(예: compute.googleapis.com/instance/cpu/utilization 또는 디스크 I/O 측정항목(예: compute.googleapis.com/instance/disk/read_bytes_count))을 사용합니다.

      게스트 OS 및 하이퍼바이저 측정항목을 사용하려면 Kubernetes 노드 이름이 아닌 기본 Compute Engine 인스턴스 이름으로 필터링해야 합니다. kubectl describe node NODE_NAME 명령어를 실행하고 출력에서 ProviderID 필드를 찾으면 노드의 인스턴스 이름을 확인할 수 있습니다. 인스턴스 이름은 해당 값의 마지막 부분입니다. 예를 들면 다음과 같습니다.

      ...
      Spec:
      ProviderID: gce://my-gcp-project-123/us-central1-a/gke-my-cluster-default-pool-1234abcd-5678
      ...
      

      이 예에서 인스턴스 이름은 gke-my-cluster-default-pool-1234abcd-5678입니다.

증상별 원인 파악

로그 메시지, 노드 조건, 클러스터 이벤트와 같은 특정 증상을 확인한 경우 다음 표를 사용하여 문제 해결 안내를 확인하세요.

카테고리 증상 또는 로그 메시지 잠재적 원인 문제 해결 단계
노드 조건 NetworkUnavailable: True 노드-제어 영역 연결 문제 또는 컨테이너 네트워크 인터페이스 (CNI) 플러그인 실패 네트워크 연결 문제 해결
MemoryPressure: True 노드의 메모리가 부족합니다. 노드 리소스 부족 문제 해결
DiskPressure: True 노드의 디스크 공간이 부족합니다. 노드 리소스 부족 문제 해결
PIDPressure: True 노드에 사용 가능한 프로세스 ID가 부족합니다. 노드 리소스 부족 문제 해결
이벤트 및 로그 메시지 PLEG is not healthy CPU/IO가 높거나 Pod가 너무 많아 Kubelet에 과부하가 걸렸습니다. PLEG 문제 해결하기
Out of memory: Kill process
sys oom event
노드 메모리가 완전히 소진되었습니다. 시스템 수준 OOM 이벤트 해결
leases.coordination.k8s.io...is forbidden kube-node-lease 네임스페이스가 종료 상태로 멈춰 있습니다. kube-node-lease 네임스페이스 관련 문제 해결하기
Container runtime not ready
runtime is down
/run/containerd/containerd.sock 또는 docker.sock을 참조하는 오류
Containerd 또는 Docker 서비스가 실패했거나 잘못 구성되었습니다. 컨테이너 런타임 문제 해결
포드가 Terminating 상태로 멈춤
Kubelet 로그에 컨테이너 종료를 위한 DeadlineExceeded가 표시됨
containerd 로그에 Kill container 메시지가 반복적으로 표시됨
무중단 디스크 절전 모드 (D 상태)에서 멈춘 프로세스입니다. I/O와 관련이 있는 경우가 많습니다. D 상태에서 멈춘 프로세스 해결
클러스터 수준 증상 DaemonSet 출시 후 여러 노드가 실패합니다. DaemonSet이 노드 작업을 방해합니다. 서드 파티 DaemonSet으로 인한 문제 해결하기
compute.instances.preempted에 표시됩니다. 스팟 VM이 선점되었습니다. 이는 예상된 동작입니다. 노드 선점 확인
kube-system 포드가 Pending 상태로 멈춰 있음 허용 웹훅이 중요한 구성요소를 차단하고 있습니다. 허용 웹훅으로 인한 문제 해결
exceeded quota: gcp-critical-pods 할당량이 잘못 구성되어 시스템 포드가 차단되었습니다. 리소스 할당량으로 인한 문제 해결하기

예상되는 NotReady 이벤트 확인

NotReady 상태가 항상 문제를 나타내는 것은 아닙니다. 노드 풀 업그레이드와 같은 계획된 작업 중에 발생할 수 있으며 특정 유형의 가상 머신을 사용하는 경우에도 발생할 수 있습니다.

노드 수명 주기 작업 확인

증상:

특정 수명 주기 이벤트 중에 노드에 일시적으로 NotReady 상태가 표시됩니다.

원인:

일반적인 여러 수명 주기 이벤트 중에 노드의 상태가 일시적으로 NotReady가 됩니다. 이 동작은 다음 시나리오와 같이 노드가 생성되거나 다시 생성될 때마다 예상됩니다.

  • 노드 풀 업그레이드: 업그레이드 중에 각 노드가 드레인되고 교체됩니다. 새로 업그레이드된 노드는 초기화가 완료되고 클러스터에 참여할 때까지 NotReady 상태입니다.
  • 노드 자동 복구: GKE가 오작동하는 노드를 교체할 때 교체 노드는 프로비저닝되는 동안 NotReady 상태로 유지됩니다.
  • 클러스터 자동 확장 처리 스케일 업: 새 노드가 추가되면 NotReady 상태로 시작되고 완전히 프로비저닝되고 클러스터에 참여한 후에만 Ready가 됩니다.
  • 수동 인스턴스 템플릿 변경: 템플릿 변경사항을 적용하면 GKE에서 노드를 다시 만듭니다. 새 노드의 시작 단계에서는 NotReady 상태가 됩니다.

해결 방법:

노드는 NotReady 상태를 잠시만 유지해야 합니다. 상태가 10분 이상 지속되면 다른 원인을 조사합니다.

노드 선점 확인

노드가 스팟 VM 또는 선점형 VM에서 실행되는 경우 Compute Engine에서 리소스를 회수하기 위해 갑자기 종료할 수 있습니다. 이는 이러한 유형의 단기 가상 머신에서 예상되는 동작이며 오류가 아닙니다.

증상:

다음 증상이 나타나면 예상되는 스팟 VM 선점으로 인해 노드의 NotReady 상태가 발생했을 수 있습니다.

  • 노드가 클러스터 자동 확장 처리기에 의해 삭제되고 다시 생성되기 전에 예기치 않게 NotReady 상태가 됩니다.
  • Cloud 감사 로그에 기본 VM 인스턴스의 compute.instances.preempted 이벤트가 표시됩니다.

원인:

노드가 스팟 VM 또는 선점형 VM 인스턴스에서 실행되고 있었으며 Compute Engine이 다른 작업을 위해 해당 컴퓨팅 리소스를 회수했습니다. 스팟 VM은 언제든지 중단될 수 있지만 일반적으로 30초 종료 알림이 제공됩니다.

해결 방법:

빈번한 종료를 원활하게 처리하도록 설계된 내결함성, 스테이트리스(Stateless) 또는 일괄 워크로드에만 스팟 VM 또는 선점형 VM을 사용하세요. 갑작스러운 중단을 허용할 수 없는 프로덕션 또는 스테이트풀(Stateful) 워크로드의 경우 표준 주문형 VM을 사용하여 노드 풀을 프로비저닝하세요.

노드 리소스 부족 문제 해결

노드는 CPU, 메모리, 디스크 공간과 같은 필수 리소스가 부족하여 NotReady가 되는 경우가 많습니다. 노드에 이러한 리소스가 충분하지 않으면 중요한 구성요소가 올바르게 작동하지 않아 애플리케이션이 불안정해지고 노드가 응답하지 않을 수 있습니다. 다음 섹션에서는 일반적인 압력 조건부터 더 심각한 시스템 전체 이벤트까지 이러한 부족이 나타날 수 있는 다양한 방법을 다룹니다.

노드 리소스 압력 해결

리소스 소진은 노드에 워크로드를 실행하기에 충분한 CPU, 메모리, 디스크 공간 또는 프로세스 ID (PID)가 부족할 때 발생합니다. 이 문제로 인해 NotReady 상태가 될 수 있습니다.

증상:

다음 노드 조건과 로그가 관찰되면 리소스 소진이 노드의 NotReady 상태의 원인일 수 있습니다.

  • kubectl describe node 명령어의 출력에서 OutOfDisk, MemoryPressure, DiskPressure 또는 PIDPressure과 같은 조건의 상태가 True로 표시됩니다.
  • kubelet 로그에는 메모리 부족 (OOM) 이벤트가 포함될 수 있으며, 이는 시스템의 OOM Killer가 호출되었음을 나타냅니다.

원인:

노드의 워크로드가 노드에서 제공할 수 있는 것보다 더 많은 리소스를 요구합니다.

해결 방법:

Standard 클러스터의 경우 다음 해결 방법을 시도해 보세요.

  • 워크로드 수요 감소:
    • 배포의 복제본 수를 축소하여 영향을 받는 노드에서 실행되는 포드 수를 줄입니다. 자세한 내용은 애플리케이션 확장을 참고하세요.
    • 애플리케이션을 검토하고 최적화하여 리소스 소비를 줄입니다.
  • 노드 용량 늘리기:

Autopilot 클러스터의 경우 노드 머신 유형이나 부팅 디스크 크기를 직접 제어할 수 없습니다. 노드 용량은 포드 요청에 따라 자동으로 관리됩니다. 워크로드 리소스 요청이 Autopilot 한도 내에 있고 애플리케이션의 요구사항을 정확하게 반영하는지 확인합니다. 지속적인 리소스 문제는 포드 요청을 최적화해야 함을 나타내거나 드물지만 Cloud Customer Care의 지원이 필요한 플랫폼 문제를 나타낼 수 있습니다.

시스템 수준 OOM 이벤트 해결

시스템 수준 메모리 부족 (OOM) 이벤트는 노드의 총 메모리가 소진될 때 발생하며, 이로 인해 Linux 커널이 리소스를 확보하기 위해 프로세스를 종료합니다. 이 이벤트는 단일 포드가 메모리 한도를 초과하는 컨테이너 수준 OOM 이벤트와는 다릅니다.

증상:

다음 증상이 나타나면 시스템 수준 OOM 이벤트가 노드 불안정의 원인일 수 있습니다.

  • 노드의 직렬 콘솔 로그에 Out of memory: Kill process 메시지가 표시됩니다.
  • kubelet 로그에는 kubelet이 시스템 수준 OOM 이벤트를 감지했음을 나타내는 oom_watcher 이벤트가 포함되어 있습니다.
  • 가장 많은 메모리를 소비하지는 않지만 잠재적으로 중요한 시스템 데몬이나 워크로드 포드를 비롯한 다양한 프로세스가 예기치 않게 종료됩니다.

원인:

노드의 전체 메모리가 소진되었습니다. 이 문제는 시스템 서비스의 버그, 과도한 메모리를 소비하는 잘못 구성된 워크로드 또는 실행 중인 모든 포드의 집단적 메모리 요구사항에 비해 너무 작은 노드로 인해 발생할 수 있습니다.

해결 방법:

시스템 수준 OOM 이벤트를 해결하려면 원인을 진단한 다음 메모리 요구사항을 줄이거나 노드 용량을 늘립니다. 자세한 내용은 OOM 이벤트 문제 해결을 참고하세요.

PLEG 문제 해결

포드 수명 주기 이벤트 생성기 (PLEG)는 kubelet 내의 구성요소입니다. 노드에 있는 모든 컨테이너의 상태를 주기적으로 확인하고 변경사항을 kubelet에 다시 보고합니다.

PLEG에 성능 문제가 발생하면 kubelet에 적시에 업데이트를 제공할 수 없으므로 노드가 불안정해질 수 있습니다.

증상:

다음과 같은 증상이 나타나면 PLEG가 제대로 작동하지 않을 수 있습니다.

  • 노드의 kubelet 로그에는 PLEG is not healthy와 유사한 메시지가 포함되어 있습니다.
  • 노드의 상태가 ReadyNotReady 사이에서 자주 변경됩니다.

원인:

PLEG 문제는 일반적으로 kubelet이 컨테이너 런타임에서 적시에 업데이트를 수신하지 못하도록 하는 성능 문제로 인해 발생합니다. 일반적인 원인은 다음과 같습니다.

  • 높은 CPU 부하: 노드의 CPU가 포화 상태이므로 kubelet과 컨테이너 런타임에 필요한 처리 능력이 없습니다.
  • I/O 제한: 노드의 부팅 디스크에서 과도한 I/O 작업이 발생하여 모든 디스크 관련 작업이 느려질 수 있습니다.
  • 과도한 포드: 단일 노드에 포드가 너무 많으면 kubelet과 컨테이너 런타임에 과부하가 걸려 리소스 경합이 발생할 수 있습니다.

해결 방법:

Standard 클러스터의 경우 노드 리소스의 부담을 줄입니다.

  • 노드 부하 감소: 배포를 축소하여 노드의 전체 워크로드를 줄입니다. taint 및 허용, 노드 어피니티 또는 포드 토폴로지 분산 제약조건을 사용하여 예약을 제어함으로써 클러스터의 다른 노드에 포드를 더 고르게 분산할 수도 있습니다.
  • CPU 한도 설정: 단일 워크로드가 사용 가능한 모든 CPU 리소스를 소비하지 않도록 포드에 CPU 한도를 적용합니다. 자세한 내용은 Kubernetes 문서의 포드 및 컨테이너의 리소스 관리를 참고하세요.
  • 노드 용량 늘리기: 워크로드를 처리하기 위해 CPU와 메모리가 더 많은 큰 노드를 사용하는 것이 좋습니다. 자세한 내용은 노드 머신 속성을 변경하여 수직 확장을 참고하세요.
  • 디스크 성능 개선: 문제가 I/O 제한과 관련된 경우 더 큰 부팅 디스크를 사용하거나 SSD 부팅 디스크로 업그레이드합니다. 이 변경사항은 디스크 성능을 크게 개선할 수 있습니다. 자세한 내용은 디스크 성능 문제 해결을 참고하세요.

Autopilot 클러스터의 경우 기존 노드의 크기나 디스크 유형을 직접 변경할 수는 없지만 맞춤 ComputeClass를 사용하여 워크로드가 실행되는 하드웨어에 영향을 줄 수 있습니다. 이 기능을 사용하면 워크로드 매니페스트에서 최소 CPU 및 메모리 양 또는 특정 머신 시리즈와 같은 요구사항을 지정하여 포드가 예약되는 위치를 안내할 수 있습니다.

ComputeClass를 사용하지 않는 경우 워크로드 배포 (예: 복제본 수, 리소스 요청 또는 한도)를 조정하고 Autopilot 제약 조건 내에 있는지 확인합니다. 워크로드를 최적화한 후에도 PLEG 문제가 지속되면 Cloud Customer Care에 문의하세요.

D 상태에서 멈춘 프로세스 해결

무중단 디스크 절전 모드 (D 상태)에서 멈춘 프로세스로 인해 노드가 응답하지 않을 수 있습니다. 이 문제로 인해 포드가 종료되지 않고 containerd와 같은 중요한 구성요소가 실패하여 NotReady 상태가 될 수 있습니다.

증상:

  • 특히 NFS와 같은 네트워크 스토리지를 사용하는 포드가 Terminating 상태에서 오랫동안 멈춰 있습니다.
  • 컨테이너를 중지하려고 하면 Kubelet 로그에 DeadlineExceeded 오류가 표시됩니다.
  • 노드의 직렬 콘솔 로그에 hung tasks 또는 120초 이상 차단된 작업에 관한 커널 메시지가 표시될 수 있습니다.

원인:

프로세스는 I/O 작업이 완료되기를 기다리는 동안 D 상태가 되며 중단할 수 없습니다. 일반적인 원인은 다음과 같습니다.

  • 잘못 구성되었거나 과부하된 NFS 공유와 같이 느리거나 응답하지 않는 원격 파일 시스템
  • 노드의 로컬 디스크에서 심각한 디스크 성능 저하 또는 하드웨어 I/O 오류가 발생합니다.

해결 방법:

D 상태 프로세스 문제를 해결하려면 I/O 소스를 식별한 다음 다음 옵션 중 하나를 선택하여 상태를 지우세요.

Standard 클러스터

  1. 중단된 프로세스를 찾아 기다리는 항목을 확인합니다.

    1. SSH를 사용하여 영향을 받는 노드에 연결합니다.

      gcloud compute ssh NODE_NAME \
          --zone ZONE \
          --project PROJECT_ID
      

      다음을 바꿉니다.

      • NODE_NAME: 연결할 노드의 이름
      • ZONE: 노드의 Compute Engine 영역입니다.
      • PROJECT_ID: 프로젝트 ID입니다.
    2. D 상태의 프로세스를 찾습니다.

      ps -eo state,pid,comm,wchan | grep '^D'
      

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

      D  12345  my-app      nfs_wait
      D  54321  data-writer io_schedule
      

      출력에는 헤더가 없습니다. 열은 순서대로 다음을 나타냅니다.

      • 프로세스 ID (PID)
      • 명령어
      • 대기 채널 (wchan)
    3. wchan 열을 검사하여 I/O 소스를 식별합니다.

      • wchan 열에 nfs 또는 rpc와 같은 용어가 포함된 경우 프로세스가 NFS 공유를 기다리고 있는 것입니다.
      • wchan 열에 io_schedule, jbd2, ext4와 같은 용어가 포함된 경우 프로세스가 노드의 로컬 부팅 디스크에서 대기 중입니다.
    4. 프로세스가 대기 중인 커널 함수에 관한 자세한 내용은 프로세스의 커널 호출 스택을 확인하세요.

      cat /proc/PID/stack
      

      PID를 이전 단계에서 찾은 프로세스 ID로 바꿉니다.

  2. 노드를 재부팅합니다. 재부팅은 D 상태에서 멈춘 프로세스를 정리하는 가장 효과적인 방법인 경우가 많습니다.

    1. 노드를 드레이닝합니다.
    2. 기본 VM 인스턴스를 삭제합니다. 일반적으로 GKE는 이를 대체하기 위해 새 VM을 만듭니다.
  3. 즉각적인 문제를 해결한 후 기본 스토리지 시스템을 조사하여 재발을 방지합니다.

    • 네트워크 스토리지 (NFS) 문제: 스토리지 제공업체의 모니터링 도구를 사용하여 GKE 노드와 NFS 서버 간의 긴 지연 시간, 서버 측 오류 또는 네트워크 문제를 확인합니다.

    • 로컬 디스크 문제: Compute Engine 인스턴스의 compute.googleapis.com/instance/disk/throttled_read_ops_countcompute.googleapis.com/instance/disk/throttled_write_ops_count 측정항목을 확인하여 Cloud Monitoring에서 I/O 제한을 확인합니다.

Autopilot 클러스터

  1. 차단의 원인 파악 시도:

    Autopilot 클러스터에서는 노드에 대한 직접 SSH 액세스와 ps 또는 cat /proc과 같은 명령어 실행이 지원되지 않습니다. 로그와 측정항목을 사용해야 합니다.

    1. 노드 로그 확인: Cloud Logging에서 영향을 받는 노드의 로그를 분석합니다. 노드 이름과 문제 기간으로 필터링합니다. I/O 오류, 스토리지 시간 초과 (예: 디스크 또는 NFS) 또는 CSI 드라이버의 메시지를 나타내는 커널 메시지를 찾습니다.
    2. 워크로드 로그 확인: 영향을 받는 노드에서 실행 중인 포드의 로그를 검사합니다. 애플리케이션 로그에는 파일 작업, 데이터베이스 호출 또는 네트워크 스토리지 액세스와 관련된 오류가 표시될 수 있습니다.
    3. Cloud Monitoring 사용: 프로세스 수준 세부정보는 확인할 수 없지만 노드 수준 I/O 문제를 확인합니다.
  2. 노드 교체를 트리거하여 상태를 지웁니다.

    기본 VM은 수동으로 삭제할 수 없습니다. 교체를 트리거하려면 노드를 드레인합니다. 이 작업은 노드를 차단하고 포드를 제거합니다.

    GKE는 비정상 노드를 자동으로 감지하고 일반적으로 기본 VM을 교체하여 복구를 시작합니다.

    드레인 후에도 노드가 멈춰 있고 자동으로 교체되지 않으면 Cloud Customer Care에 문의하세요.

  3. 즉각적인 문제를 해결한 후 기본 스토리지 시스템을 조사하여 재발을 방지합니다.

    • 로컬 디스크 문제: compute.googleapis.com/instance/disk/throttled_read_ops_countcompute.googleapis.com/instance/disk/throttled_write_ops_count 측정항목을 확인하여 Cloud Monitoring에서 I/O 제한을 확인합니다. 개별 인스턴스는 Google에서 관리하지만 노드 풀의 기본 인스턴스 그룹에 대해 이러한 측정항목을 필터링할 수 있습니다.
    • 네트워크 스토리지 (NFS) 문제: 스토리지 제공업체의 모니터링 도구를 사용하여 GKE 노드와 NFS 서버 간의 긴 지연 시간, 서버 측 오류 또는 네트워크 문제를 확인합니다. Cloud Logging에서 CSI 드라이버 포드의 로그를 확인합니다.

핵심 구성요소 오류 문제 해결

예상되는 원인과 리소스 부족을 제외하면 노드의 소프트웨어 또는 핵심 Kubernetes 메커니즘이 문제의 원인일 수 있습니다. 컨테이너 런타임과 같은 중요한 구성요소에 장애가 발생하면 NotReady 상태가 발생할 수 있습니다. 노드 임대 시스템과 같은 핵심 Kubernetes 상태 점검 메커니즘이 중단될 때도 발생할 수 있습니다.

컨테이너 런타임 문제 해결

containerd와 같은 컨테이너 런타임에 문제가 있으면 kubelet이 노드에서 포드를 실행하지 못할 수 있습니다.

증상:

kubelet 로그에 다음 메시지가 표시되면 컨테이너 런타임 문제가 노드의 NotReady 상태의 원인일 수 있습니다.

  • Container runtime not ready
  • Container runtime docker failed!
  • docker daemon exited
  • 런타임 소켓 (예: unix:///var/run/docker.sock 또는 unix:///run/containerd/containerd.sock)에 연결하는 중 오류가 발생합니다.

원인:

컨테이너 런타임이 올바르게 작동하지 않거나 잘못 구성되었거나 다시 시작 루프에 갇혀 있습니다.

해결 방법:

컨테이너 런타임 문제를 해결하려면 다음 단계를 따르세요.

  1. 컨테이너 런타임 로그 분석:

    1. Google Cloud 콘솔에서 로그 탐색기 페이지로 이동합니다.

      로그 탐색기로 이동

    2. 영향을 받는 노드에서 컨테이너 런타임의 모든 경고 및 오류 로그를 보려면 쿼리 창에 다음을 입력합니다.

      resource.type="k8s_node"
      resource.labels.node_name="NODE_NAME"
      resource.labels.cluster_name="CLUSTER_NAME"
      resource.labels.location="LOCATION"
      log_id("container-runtime")
      severity>=WARNING
      

      다음을 바꿉니다.

      • NODE_NAME: 조사 중인 노드의 이름
      • CLUSTER_NAME: 클러스터 이름입니다.
      • LOCATION: 클러스터의 Compute Engine 리전 또는 영역입니다 (예: us-central1 또는 us-central1-a).
    3. 쿼리 실행을 클릭하고 출력에서 런타임이 실패한 이유를 나타내는 특정 오류 메시지를 검토합니다. Cloud Logging의 containerd 로그에 failed to load TOML와 같은 메시지가 표시되는 경우 파일이 잘못된 형식임을 나타내는 경우가 많습니다.

    4. 런타임이 다시 시작 루프에 갇혀 있는지 확인하려면 시작 메시지를 검색하는 쿼리를 실행하세요. 이러한 메시지가 단기간에 많이 표시되면 자주 다시 시작되는 것입니다.

      resource.type="k8s_node"
      resource.labels.node_name="NODE_NAME"
      resource.labels.cluster_name="CLUSTER_NAME"
      resource.labels.location="LOCATION"
      log_id("container-runtime")
      ("starting containerd" OR "Containerd cri plugin version" OR "serving..."
      OR "loading plugin" OR "containerd successfully booted")
      

      잦은 재시작은 서비스가 반복적으로 비정상 종료되도록 하는 손상된 구성 파일이나 리소스 압력과 같은 기본 문제를 나타내는 경우가 많습니다.

  2. containerd 구성에서 수정사항 검토: 잘못된 설정으로 인해 컨테이너 런타임이 실패할 수 있습니다. 노드 시스템 구성 파일을 통해 또는 권한이 상승된 워크로드에서 직접 수정을 통해 구성을 변경할 수 있습니다.

    1. 노드 풀에서 노드 시스템 구성 파일을 사용하는지 확인합니다.

      gcloud container node-pools describe NODE_POOL_NAME \
          --cluster CLUSTER_NAME \
          --location LOCATION \
          --format="yaml(config.containerdConfig)"
      

      다음을 바꿉니다.

      • NODE_POOL_NAME: 노드 풀의 이름입니다.
      • CLUSTER_NAME: 클러스터 이름입니다.
      • LOCATION: 클러스터의 Compute Engine 리전 또는 영역입니다.

      출력에 containerdConfig 섹션이 표시되면 GKE가 이러한 맞춤 설정을 관리하는 것입니다. 설정을 수정하거나 되돌리려면 GKE 노드에서 containerd 구성 맞춤설정의 안내를 따르세요.

    2. GKE 관리 맞춤설정이 활성화되어 있지 않거나 다른 변경사항이 의심되는 경우 노드의 파일 시스템을 직접 수정할 수 있는 워크로드를 찾습니다. 권한이 상승된 (securityContext.privileged: true) DaemonSet 또는 /etc와 같은 민감한 디렉터리를 마운트하는 hostPath 볼륨을 찾습니다.

      구성을 검사하려면 YAML 형식으로 모든 DaemonSet을 나열합니다.

      kubectl get daemonsets --all-namespaces -o yaml
      

      출력을 검토하고 의심스러운 DaemonSet의 로그를 검사합니다.

    3. Standard 클러스터의 경우 구성 파일을 직접 검사합니다. Google에서 런타임 구성을 관리하므로 Autopilot 클러스터에서는 SSH 액세스 및 수동 파일 검사가 불가능합니다. 지속적인 런타임 문제를 Google Cloud Customer Care에 신고하세요.

      표준 클러스터를 사용하는 경우 파일을 검사합니다.

      1. SSH를 사용하여 노드에 연결합니다.

        gcloud compute ssh NODE_NAME \
            --zone ZONE \
            --project PROJECT_ID
        

        다음을 바꿉니다.

        • NODE_NAME: 연결할 노드의 이름
        • ZONE: 노드의 Compute Engine 영역입니다.
        • PROJECT_ID: 프로젝트 ID입니다.
      2. containerd 구성 파일의 콘텐츠를 표시합니다.

        sudo cat /etc/containerd/config.toml
        
      3. 최근 수정사항을 확인하려면 파일 세부정보를 나열합니다.

        ls -l /etc/containerd/config.toml
        
    4. 이 파일의 콘텐츠를 이전 단계에서 실행한 gcloud node-pools describe 명령어의 containerdConfig 출력과 비교합니다. gcloud 출력에 없는 /etc/containerd/config.toml의 설정은 관리되지 않는 변경사항입니다.

    5. 잘못된 구성을 수정하려면 노드 시스템 구성을 통해 적용되지 않은 변경사항을 삭제하세요.

  3. 일반적인 런타임 문제 해결: 자세한 문제 해결 단계는 컨테이너 런타임 문제 해결을 참고하세요.

kube-node-lease 네임스페이스 관련 문제 해결

kube-node-lease 네임스페이스의 리소스는 노드 상태를 유지합니다. 이 네임스페이스는 삭제하면 안 됩니다. 이 네임스페이스를 삭제하려고 하면 네임스페이스가 Terminating 상태로 멈춥니다. kube-node-lease 네임스페이스가 Terminating 상태로 멈추면 kubelet이 상태 점검 리스를 갱신할 수 없습니다. 이 문제로 인해 컨트롤 플레인에서 노드가 비정상으로 간주되어 노드가 ReadyNotReady 상태 간에 번갈아 표시되는 클러스터 전체 문제가 발생합니다.

증상:

다음 증상이 나타나면 kube-node-lease 네임스페이스의 문제가 클러스터 전체 불안정의 원인일 수 있습니다.

  • 모든 노드의 kubelet 로그에 다음과 유사한 지속적인 오류가 표시됩니다.

    leases.coordination.k8s.io NODE_NAME is forbidden: unable to create new content in namespace kube-node-lease because it is being terminated
    
  • 클러스터의 노드가 ReadyNotReady 상태 사이를 반복적으로 전환합니다.

원인:

노드 하트비트를 관리하는 kube-node-lease 네임스페이스가 Terminating 상태로 비정상적으로 멈춰 있습니다. 이 오류로 인해 Kubernetes API 서버가 네임스페이스 내에서 객체 생성 또는 수정을 허용하지 않습니다. 따라서 kubelet은 컨트롤 플레인에 활성 상태를 알리는 데 필수적인 Lease 객체를 갱신할 수 없습니다. 이러한 상태 업데이트가 없으면 컨트롤 플레인이 노드가 정상인지 확인할 수 없으므로 노드 상태가 ReadyNotReady 사이에서 번갈아 표시됩니다.

kube-node-lease 네임스페이스 자체가 Terminating 상태로 멈출 수 있는 근본적인 이유는 다음과 같습니다.

  • 최종화 프로그램이 있는 리소스: 시스템 kube-node-lease 네임스페이스 (주로 Lease 객체 포함)에서는 덜 일반적이지만, 이 네임스페이스 내의 리소스에 최종화 프로그램이 있을 수 있습니다. Kubernetes 파이널라이저는 리소스를 삭제하기 전에 컨트롤러가 정리 작업을 실행해야 함을 알리는 키입니다. 파이널라이저 삭제를 담당하는 컨트롤러가 올바르게 작동하지 않으면 리소스가 삭제되지 않고 네임스페이스 삭제 프로세스가 중지됩니다.
  • 비정상 또는 응답하지 않는 집계 API 서비스: 집계 API 서버를 등록하는 데 사용되는 APIService 객체가 네임스페이스에 연결되어 비정상 상태가 되면 네임스페이스 종료가 차단될 수 있습니다. 컨트롤 플레인은 집계된 API 서버가 제대로 종료되거나 정리될 때까지 기다릴 수 있지만 서비스가 응답하지 않으면 이 작업이 발생하지 않습니다.
  • 제어 영역 또는 컨트롤러 문제: 드물지만 Kubernetes 제어 영역, 특히 네임스페이스 컨트롤러 내의 버그나 문제로 인해 네임스페이스의 가비지 컬렉션 및 삭제가 성공적으로 이루어지지 않을 수 있습니다.

해결 방법:

종료 중 상태에서 멈춘 네임스페이스 문제 해결의 안내를 따르세요.

네트워크 연결 문제 해결

네트워크 문제로 인해 노드가 컨트롤 플레인과 통신하지 못하거나 CNI 플러그인과 같은 중요한 구성요소가 작동하지 않아 NotReady 상태가 될 수 있습니다.

증상:

다음 증상이 나타나면 네트워크 문제로 인해 노드 상태가 NotReady일 수 있습니다.

  • NetworkNotReady 조건은 True입니다.
  • 노드의 kubelet 로그에 다음과 유사한 오류가 표시됩니다.
    • connection timeout to the control plane IP address
    • network plugin not ready
    • CNI plugin not initialized
    • 컨트롤 플레인 IP 주소에 연결하려고 할 때 connection refused 또는 timeout 메시지
  • 특히 kube-system 네임스페이스의 포드가 NetworkPluginNotReady와 같은 이벤트와 함께 ContainerCreating에 멈춰 있습니다.

원인:

네트워크 관련 증상은 일반적으로 다음 영역 중 하나의 실패를 나타냅니다.

  • 연결 문제: 노드가 Kubernetes 컨트롤 플레인에 안정적인 네트워크 연결을 설정할 수 없습니다.
  • CNI 플러그인 실패: 포드 네트워킹 구성을 담당하는 CNI 플러그인이 올바르게 실행되지 않거나 초기화에 실패했습니다.
  • 웹훅 문제: 잘못 구성된 허용 웹훅이 CNI 플러그인 관련 리소스를 방해하여 네트워크가 올바르게 구성되지 않을 수 있습니다.

해결 방법:

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

  1. 일시적인 NetworkNotReady 상태 처리: 새로 생성된 노드에서는 짧은 NetworkNotReady 이벤트가 표시되는 것이 정상입니다. CNI 플러그인과 기타 구성요소가 초기화되는 동안 이 상태는 1~2분 내에 해결됩니다. 상태가 계속되면 다음 단계를 진행합니다.

  2. 노드-컨트롤 플레인 연결 및 방화벽 규칙 확인: 노드와 컨트롤 플레인 간의 네트워크 경로가 열려 있고 올바르게 작동하는지 확인합니다.

    1. 방화벽 규칙 확인: VPC 방화벽 규칙이 GKE 노드와 컨트롤 플레인 간에 필요한 트래픽을 허용하는지 확인합니다. 노드-제어 영역 통신에 GKE가 요구하는 규칙에 관한 자세한 내용은 자동으로 생성되는 방화벽 규칙을 참고하세요.
    2. 연결 테스트: Network Intelligence Center의 연결 테스트를 사용하여 노드의 내부 IP 주소와 포트 443의 제어 영역 엔드포인트 IP 주소 간 네트워크 경로를 확인합니다. Not Reachable 결과는 통신을 차단하는 방화벽 규칙이나 라우팅 문제를 식별하는 데 도움이 되는 경우가 많습니다.
  3. CNI 플러그인 상태 및 로그 조사: 노드의 네트워크가 준비되지 않은 경우 CNI 플러그인에 문제가 있을 수 있습니다.

    1. CNI 포드 상태 확인: 사용 중인 CNI 플러그인 (예: netd 또는 calico-node)을 식별하고 kube-system 네임스페이스에서 해당 포드의 상태를 확인합니다. 다음 명령어를 사용하여 특정 노드를 필터링할 수 있습니다.

      kubectl get pods \
          -n kube-system \
          -o wide \
          --field-selector spec.nodeName=NODE_NAME \
          | grep -E "netd|calico|anetd"
      
    2. CNI 포드 로그 검사: 포드가 올바르게 작동하지 않으면 Cloud Logging에서 로그를 검사하여 자세한 오류 메시지를 확인합니다. 특정 노드의 netd 포드에 대해 다음과 유사한 쿼리를 사용합니다.

      resource.type="k8s_container"
      resource.labels.cluster_name="CLUSTER_NAME"
      resource.labels.location="LOCATION"
      resource.labels.namespace_name="kube-system"
      labels."k8s-pod/app"="netd"
      resource.labels.node_name="NODE_NAME"
      severity>=WARNING
      
    3. 특정 CNI 오류 해결:

      • 로그에 Failed to allocate IP address가 표시되면 포드 IP 주소 범위가 소진되었을 수 있습니다. 포드 IP 주소 사용률을 확인하고 클러스터의 CIDR 범위를 검토합니다.
      • 로그에 NetworkPluginNotReady 또는 cni plugin not initialized이 표시되면 노드에 CPU 및 메모리 리소스가 충분한지 확인합니다. CNI 포드를 삭제하여 다시 시작할 수도 있습니다. 이렇게 하면 DaemonSet이 포드를 다시 만듭니다.
      • GKE Dataplane V2를 사용하고 로그에 Cilium API client timeout exceeded가 표시되면 노드에서 anetd 포드를 다시 시작합니다.
    4. 허용 웹훅 간섭 확인: 오작동하는 웹훅으로 인해 CNI 포드가 시작되지 않아 노드가 NetworkNotReady 상태로 남을 수 있습니다.

    5. API 서버 로그 확인: Cloud Logging에서 웹훅 호출과 관련된 오류가 있는지 API 서버 로그를 검토합니다. 웹훅이 CNI 리소스 생성을 차단하는지 확인하려면 failed calling webhook와 같은 메시지를 검색하세요.

      웹훅으로 인해 문제가 발생하는 경우 문제가 있는 ValidatingWebhookConfiguration 또는 MutatingWebhookConfiguration를 식별하고 노드가 준비될 수 있도록 일시적으로 사용 중지해야 할 수 있습니다. 자세한 내용은 승인 웹훅으로 인한 문제 해결을 참고하세요.

클러스터 잘못된 구성 문제 해결

다음 섹션에서는 정상적인 노드 작업을 방해할 수 있는 일부 클러스터 전체 구성을 감사하는 방법을 설명합니다.

허용 웹훅으로 인한 문제 해결

잘못 구성되었거나, 사용할 수 없거나, 너무 느린 허용 웹훅은 중요한 API 요청을 차단하여 필수 구성요소가 시작되지 않거나 노드가 클러스터에 참여하지 못하게 할 수 있습니다.

증상:

다음 증상이 나타나면 잘못 구성되었거나 사용할 수 없는 허용 웹훅이 필수 클러스터 작업을 차단하고 있을 수 있습니다.

  • 특히 kube-system 네임스페이스 (예: CNI 또는 스토리지 포드)의 포드가 Pending 또는 Terminating 상태로 멈춰 있습니다.
  • 새 노드가 클러스터에 가입하지 못하고 NotReady 상태로 시간이 초과되는 경우가 많습니다.

원인:

잘못 구성되었거나 응답하지 않는 허용 웹훅이 필수 클러스터 작업을 차단할 수 있습니다.

해결 방법:

웹훅 구성이 복원력이 있고 범위가 적절한지 검토하세요. 서비스 중단을 방지하려면 중요하지 않은 웹훅의 failurePolicy 필드를 Ignore로 설정하세요. 중요한 웹훅의 경우 지원 서비스의 가용성이 높아야 하며 namespaceSelector를 사용하여 제어 영역 교착 상태를 방지함으로써 웹훅 감독에서 kube-system 네임스페이스를 제외해야 합니다. 자세한 내용은 웹훅을 사용할 때 컨트롤 플레인 안정성 보장을 참고하세요.

리소스 할당량으로 인한 문제 해결

kube-system 네임스페이스의 리소스 할당량이 잘못 계산되면 GKE에서 중요한 시스템 포드를 만들지 못할 수 있습니다. 네트워킹 (CNI) 및 DNS와 같은 구성요소가 차단되므로 이 문제로 인해 새 노드가 클러스터에 성공적으로 참여하지 못할 수 있습니다.

증상:

  • kube-system 네임스페이스의 중요 포드 (예: netd, konnectivity-agent, kube-dns)가 Pending 상태로 멈춰 있습니다.
  • 클러스터 로그 또는 kubectl describe pod 출력의 오류 메시지에 exceeded quota: gcp-critical-pods과 같은 실패가 표시됩니다.

원인:

이 문제는 Kubernetes 리소스 할당량 컨트롤러가 ResourceQuota 객체에서 사용된 수를 정확하게 업데이트하지 않을 때 발생합니다. 일반적인 원인은 컨트롤러의 업데이트를 차단하는 오작동하는 서드 파티 승인 웹훅으로, 할당량 사용량이 실제보다 훨씬 높게 표시됩니다.

해결 방법:

  1. 문제가 있는 웹훅이 근본 원인일 가능성이 가장 높으므로 승인 웹훅으로 인한 문제 해결 섹션의 안내에 따라 시스템 구성요소를 차단할 수 있는 웹훅을 식별하고 수정하세요. 웹훅을 수정하면 할당량 문제가 자동으로 해결되는 경우가 많습니다.
  2. 기록된 할당량 사용량이 실행 중인 실제 Pod 수와 동기화되지 않는지 확인합니다. 이 단계에서는 ResourceQuota 객체의 개수가 잘못되었는지 확인합니다.

    1. 할당량의 보고된 사용량을 확인합니다.

      kubectl get resourcequota gcp-critical-pods -n kube-system -o yaml
      
    2. 실제 포드 수를 확인합니다.

      kubectl get pods -n kube-system --no-headers | wc -l
      
  3. ResourceQuota의 사용된 개수가 잘못된 것 같으면 (예: 실제 포드 수보다 훨씬 높음) gcp-critical-pods 객체를 삭제합니다. GKE 컨트롤 플레인은 올바르고 조정된 사용량으로 이 객체를 자동으로 다시 생성하도록 설계되었습니다.

    kubectl delete resourcequota gcp-critical-pods -n kube-system
    
  4. 몇 분 동안 kube-system 네임스페이스를 모니터링하여 객체가 다시 생성되고 대기 중인 포드가 예약되기 시작하는지 확인합니다.

서드 파티 DaemonSet으로 인한 문제 해결

보안, 모니터링 또는 로깅에 자주 사용되는 새로 배포되거나 업데이트된 서드 파티 DaemonSet이 노드 불안정을 유발할 수 있습니다. 이 문제는 DaemonSet가 노드의 컨테이너 런타임이나 네트워킹을 방해하거나, 과도한 시스템 리소스를 소비하거나, 예상치 못한 시스템 수정을 하는 경우 발생할 수 있습니다.

증상:

다음과 같은 증상이 나타나면 최근에 배포되거나 수정된 서드 파티 DaemonSet이 노드 장애의 원인일 수 있습니다.

  • DaemonSet가 배포되거나 업데이트된 직후 클러스터 전체에 걸쳐 여러 노드가 NotReady 상태가 됩니다.
  • 영향을 받는 노드의 kubelet 로그에는 다음과 같은 오류가 보고됩니다.
    • container runtime is down
    • Failed to create pod sandbox
    • 컨테이너 런타임 소켓 (예: /run/containerd/containerd.sock)에 연결하는 중 오류가 발생합니다.
  • 시스템 포드 또는 DaemonSet 자체 포드를 포함한 포드가 PodInitializing 또는 ContainerCreating 상태로 멈춰 있습니다.
  • 애플리케이션의 컨테이너 로그에 exec format error와 같은 비정상적인 오류가 표시됩니다.
  • 노드 문제 감지기는 런타임 상태 또는 리소스 압력과 관련된 조건을 보고할 수 있습니다.

원인:

다음과 같은 이유로 서드 파티 DaemonSet가 노드 안정성에 영향을 미칠 수 있습니다.

  • CPU, 메모리 또는 디스크 I/O를 과도하게 사용하여 중요한 노드 구성요소의 성능에 영향을 미칩니다.
  • 컨테이너 런타임의 작동을 방해합니다.
  • 노드의 네트워크 구성 또는 컨테이너 네트워크 인터페이스 (CNI) 플러그인과 충돌합니다.
  • 의도하지 않은 방식으로 시스템 구성 또는 보안 정책을 변경합니다.

해결 방법:

DaemonSet가 원인인지 확인하려면 DaemonSet를 격리하고 테스트하세요.

  1. DaemonSet 식별: 클러스터에서 실행 중인 모든 DaemonSet을 나열합니다.

    kubectl get daemonsets --all-namespaces
    

    기본 GKE 설치에 포함되지 않은 DaemonSet에 특히 주의하세요.

    다음 사항을 검토하면 이러한 DaemonSet을 식별할 수 있는 경우가 많습니다.

    • 네임스페이스: 기본 GKE 구성요소는 일반적으로 kube-system 네임스페이스에서 실행됩니다. 다른 네임스페이스의 DaemonSet은 서드 파티 또는 맞춤일 가능성이 높습니다.
    • 이름 지정: 기본 DaemonSet의 이름은 gke-metrics-agent, netd, calico-node와 같은 경우가 많습니다. 서드 파티 에이전트의 이름은 제품을 반영하는 경우가 많습니다.
  2. 배포 시간 상관관계: NotReady 노드의 출현이 특정 서드 파티 DaemonSet의 배포 또는 업데이트와 일치하는지 확인합니다.

  3. 단일 노드에서 테스트:

    1. 영향을 받는 노드 하나를 선택합니다.
    2. 노드를 차단하고 드레이닝합니다.
    3. 이 노드에서 DaemonSet가 예약되지 않도록 일시적으로 방지합니다.
      • 임시 노드 라벨을 적용하고 DaemonSet의 매니페스트에서 노드 어피니티 또는 안티 어피니티를 구성합니다.
      • 해당 특정 노드에서 DaemonSet의 포드를 삭제합니다.
    4. 노드의 가상 머신 인스턴스를 재부팅합니다.
    5. DaemonSet이 노드에서 실행되지 않는 동안 노드가 Ready이 되고 안정적으로 유지되는지 확인합니다. DaemonSet을 다시 도입한 후 문제가 다시 나타나면 DaemonSet이 문제의 원인일 수 있습니다.
  4. 공급업체에 문의: 서드 파티 에이전트가 원인이라고 생각되면 공급업체의 문서에서 알려진 호환성 문제나 GKE에서 에이전트를 실행하기 위한 권장사항을 검토하세요. 추가 지원이 필요한 경우 소프트웨어 공급업체에 문의하세요.

노드가 복구되었는지 확인

가능한 해결 방법을 적용한 후 다음 단계에 따라 노드가 성공적으로 복구되고 안정적인지 확인합니다.

  1. 노드의 상태를 확인합니다.

    kubectl get nodes -o wide
    

    출력에서 영향을 받는 노드를 찾습니다. 이제 Status 열에 Ready 값이 표시됩니다. 수정사항이 적용된 후 상태가 업데이트되는 데 몇 분 정도 걸릴 수 있습니다. 상태가 여전히 NotReady로 표시되거나 상태가 계속 전환되면 문제가 완전히 해결되지 않은 것입니다.

  2. 노드의 Conditions 섹션을 검사합니다.

    kubectl describe node NODE_NAME
    

    Conditions 섹션에서 다음 값을 확인합니다.

    • Ready 조건의 상태는 True입니다.
    • 이전에는 True 상태였던 부정 조건 (예: MemoryPressure 또는 NetworkUnavailable)이 이제 False 상태가 됩니다. 이러한 조건의 ReasonMessage 필드는 문제가 해결되었음을 나타내야 합니다.
  3. 포드 예약 테스트 이전에 노드에서 워크로드를 실행할 수 없었던 경우 새 포드가 노드에 예약되고 기존 포드가 문제없이 실행되는지 확인합니다.

    kubectl get pods --all-namespaces -o wide --field-selector spec.nodeName=NODE_NAME
    

    노드의 포드는 Running 또는 Completed 상태여야 합니다. 포드가 Pending 또는 기타 오류 상태로 멈춰서는 안 됩니다.

다음 단계

  • 문서에서 문제 해결 방법을 찾을 수 없으면 지원 받기를 참조하여 다음 주제에 대한 조언을 포함한 추가 도움을 요청하세요.