Google Kubernetes Engine (GKE) Standard 클러스터를 관리할 때 노드 풀에 문제가 있으면 중요한 작업이 중단될 수 있습니다. 이러한 문제로 인해 수요를 충족하기 위해 워크로드를 확장하거나 필수 인프라 업그레이드를 실행할 수 없게 되어 애플리케이션의 안정성에 영향을 미칠 수 있습니다.
이 페이지를 사용하여 일반적인 노드 풀 문제를 해결하세요. 리소스가 부족한지 확인하고, 최선을 다하는 프로비저닝과 같은 기능을 사용하여 노드를 만들고, 중단 없이 워크로드를 안전하게 이전하는 방법을 알아보세요.
이 정보는 클러스터 인프라 관리를 담당하는 플랫폼 관리자 및 운영자에게 중요합니다. 노드 풀 제한이 애플리케이션 배포에 어떤 영향을 미칠 수 있는지 이해해야 하는 애플리케이션 개발자에게도 유용합니다. Google Cloud 콘텐츠에서 참조하는 일반적인 역할과 예시 태스크에 대한 자세한 내용은 일반 GKE 사용자 역할 및 태스크를 참고하세요.
노드 풀 만들기 문제
이 섹션에서는 Standard 클러스터에서 새 노드 풀을 만들 때 발생할 수 있는 문제를 나열하고 문제를 해결하는 방법에 대한 제안을 제공합니다.
문제: 리소스 부족으로 인해 노드 풀 만들기 실패
요구 사항을 충족하는 데 사용할 수 있는 하드웨어가 충분하지 않은 Google Cloud 영역에서 특정 하드웨어로 노드 풀을 만들 때 다음 문제가 발생합니다.
영역에 리소스가 충분하지 않아 노드 풀 생성이 실패했는지 확인하려면 로그에서 관련 오류 메시지를 확인하세요.
Google Cloud 콘솔에서 로그 탐색기로 이동합니다.
쿼리 필드에 다음 쿼리를 지정합니다.
log_id(cloudaudit.googleapis.com/activity) resource.labels.cluster_name="CLUSTER_NAME" protoPayload.status.message:("ZONE_RESOURCE_POOL_EXHAUSTED" OR "does not have enough resources available to fulfill the request" OR "resource pool exhausted" OR "does not exist in zone")
CLUSTER_NAME
을 GKE 클러스터 이름으로 바꿉니다.쿼리 실행을 클릭합니다.
다음 오류 메시지 중 하나가 표시될 수 있습니다.
resource pool exhausted
The zone does not have enough resources available to fulfill the request. Try a different zone, or try again later.
ZONE_RESOURCE_POOL_EXHAUSTED
ZONE_RESOURCE_POOL_EXHAUSTED_WITH_DETAILS
Machine type with name 'MACHINE_NAME' does not exist in zone 'ZONE_NAME'
이 문제를 해결하려면 다음을 제안을 시도해 보세요.
- 선택한 Google Cloud 리전 또는 영역에 필요한 특정 하드웨어가 있는지 확인합니다. Compute Engine 가용성 표를 사용하여 특정 영역이 특정 하드웨어를 지원하는지 확인합니다. 필요한 하드웨어 가용성을 높일 수 있는 노드에 대한 다른Google Cloud 리전 또는 영역을 선택합니다.
- 더 작은 머신 유형으로 노드 풀을 만듭니다. 총 컴퓨팅 용량이 동일하게 유지되도록 노드 풀의 노드 수를 늘립니다.
- Compute Engine 용량 예약을 사용하여 리소스를 미리 예약합니다.
- 다음 섹션에 설명된 대로 최선의 프로비저닝을 사용하여 노드 풀이 요청된 수 중에서 지정된 최소 노드 수를 프로비저닝할 수 있는 경우 해당 노드 풀이 성공적으로 생성됩니다.
최선의 프로비저닝
특정 하드웨어의 경우 최선의 프로비저닝을 사용하여 GKE가 지정된 최소 노드 수를 프로비저닝할 수 있는 경우 노드 풀을 성공적으로 만들도록 지정할 수 있습니다. GKE는 시간이 지남에 따라 원래 요청을 충족하도록 나머지 노드를 프로비저닝하려고 계속 시도합니다. GKE에 최선의 프로비저닝을 사용하도록 지시하려면 다음 명령어를 사용합니다.
gcloud container node-pools create NODE_POOL_NAME \
--cluster=CLUSTER_NAME \
--location=CONTROL_PLANE_LOCATION \
--node-locations=ZONE1,ZONE2,... \
--machine-type=MACHINE_TYPE
--best-effort-provision \
--min-provision-nodes=MINIMUM_NODES
다음을 바꿉니다.
NODE_POOL_NAME
: 새 노드 풀의 이름CONTROL_PLANE_LOCATION
: 클러스터의 컨트롤 플레인에 대한 Compute Engine 위치입니다. 리전 클러스터의 경우 리전 또는 영역 클러스터의 경우 영역을 제공합니다.ZONE1,ZONE2,...
: 노드의 Compute Engine 영역입니다. 이러한 영역은 선택한 하드웨어를 지원해야 합니다.MACHINE_TYPE
: 노드의 Compute Engine 머신 유형입니다. 예를 들면a2-highgpu-1g
입니다.MINIMUM_NODES
: GKE가 노드 풀을 프로비저닝하고 성공적으로 만들기 위한 최소 노드 수입니다. 생략할 경우 기본값은1
입니다.
예를 들어 us-central1-c
에 연결된 NVIDIA A100 40GB GPU가 있는 10개의 노드가 필요한 시나리오를 생각해 보십시오. GPU 리전 및 영역 가용성 표에 따라 이 영역은 A100 GPU를 지원합니다. GPU 머신 10대를 사용할 수 없는 경우 노드 풀 생성 실패를 방지하려면 최선의 프로비저닝을 사용합니다.
gcloud container node-pools create a100-nodes \
--cluster=ml-cluster \
--location=us-central1 \
--node-locations=us-central1-c \
--num-nodes=10 \
--machine-type=a2-highgpu-1g \
--accelerator=type=nvidia-tesla-a100,count=1 \
--best-effort-provision \
--min-provision-nodes=5
GKE는 us-central1-c
에서 5개의 GPU만 사용할 수 있는 경우에도 노드 풀을 만듭니다. 시간 경과에 따라 GKE는 노드 풀에 노드가 10개가 될 때까지 더 많은 노드를 프로비저닝하려고 시도합니다.
오류: 인스턴스에 'instance-template' 메타데이터가 포함되지 않음
업그레이드, 확장, 자동 노드 복구 수행에 실패한 노드 풀의 상태로 다음 오류가 표시될 수 있습니다.
Instance INSTANCE_NAME does not contain 'instance-template' metadata
이 오류는 GKE에서 할당된 VM 인스턴스의 메타데이터가 손상되었음을 나타냅니다. 이는 일반적으로 커스텀 방식으로 작성된 자동화 또는 스크립트가 새 인스턴스 메타데이터를 추가하려고 시도할 때(예: block-project-ssh-keys
) 그리고 값을 추가하거나 업데이트하는 대신 기존 메타데이터를 삭제할 때 발생합니다.
커스텀 메타데이터 설정에서 VM 인스턴스 메타데이터에 대해 알아볼 수 있습니다.
중요한 메타데이터 값(특히 instance-template
, kube-labels
, kubelet-config
, kubeconfig
, cluster-name
, configure-sh
, cluster-uid
)이 삭제된 경우 이러한 값이 GKE 운영에 중요하기 때문에 노드 또는 전체 노드 풀이 불안정한 상태로 전환될 수 있습니다.
인스턴스 메타데이터가 손상된 경우 손상된 VM 인스턴스가 포함된 노드 풀을 다시 만들어 메타데이터를 복구하는 것이 좋습니다. 클러스터에 노드 풀을 추가하고 새 노드 풀에서 노드 수를 늘려야 하며, 다른 노드 풀에서는 노드를 차단하고 삭제해야 합니다. 노드 풀 간의 워크로드 마이그레이션 안내를 참조하세요.
인스턴스 메타데이터를 수정한 사람과 시간을 찾으려면 Compute Engine 감사 로깅 정보를 검토하거나 다음과 비슷한 검색어로 로그 탐색기를 사용해서 로그를 찾을 수 있습니다.
resource.type="gce_instance_group_manager"
protoPayload.methodName="v1.compute.instanceGroupManagers.setInstanceTemplate"
로그에서 요청 시작자 IP 주소 및 사용자 에이전트를 찾을 수 있습니다. 예를 들면 다음과 같습니다.
requestMetadata: {
callerIp: "REDACTED"
callerSuppliedUserAgent: "google-api-go-client/0.5 GoogleContainerEngine/v1"
}
노드 풀 간 워크로드 마이그레이션
다음 안내에 따라 한 노드 풀에서 다른 노드 풀로 워크로드를 마이그레이션합니다. 노드 풀에 있는 노드의 머신 속성을 변경하려면 노드 머신 속성을 변경하여 수직 확장을 참조하세요.
포드를 새 노드 풀로 마이그레이션하는 방법 이해
포드를 새 노드 풀로 마이그레이션하려면 다음을 수행해야 합니다.
기존 노드 풀의 노드 차단: 이 작업은 기존 노드 풀의 노드를 예약 불가능으로 표시합니다. 이를 예약 불가능으로 표시한 다음에는 Kubernetes가 이러한 노드에 대한 새 포드 예약을 중지합니다.
기존 노드 풀의 노드 드레이닝: 이 작업은 기존 노드 풀의 노드에서 실행 중인 워크로드를 정상적으로 제거합니다.
이러한 단계는 각 노드에서 개별적으로 실행되어 기존 노드 풀에서 실행 중인 포드를 정상적으로 종료합니다. Kubernetes는 이 포드를 다른 사용 가능한 노드에 다시 예약합니다.
Kubernetes가 애플리케이션을 정상적으로 종료하도록 하려면, 컨테이너가 SIGTERM 신호를 처리해야 합니다. 이 방법을 사용하면 클라이언트에 대한 활성 연결을 닫고 데이터베이스 트랜잭션을 깔끔한 방식으로 커밋하거나 롤백할 수 있습니다. 포드 매니페스트에서 spec.terminationGracePeriodSeconds
필드를 사용하여 Kubernetes가 포드의 컨테이너를 중지하기 전에 대기해야 하는 시간을 지정할 수 있습니다. 기본값은 30초입니다.
포드 종료에 대한 상세 설명은 Kubernetes 문서를 참조하세요.
kubectl cordon
및 kubectl drain
명령어를 사용하여 노드를 차단 및 드레이닝할 수 있습니다.
노드 풀 만들기 및 워크로드 마이그레이션
워크로드를 새 노드 풀로 마이그레이션하려면 새 노드 풀을 만든 다음 기존 노드 풀에서 노드를 차단 및 드레이닝합니다.
클러스터에 노드 풀을 추가합니다.
다음 명령어를 실행하여 새 노드 풀이 생성되었는지 확인합니다.
gcloud container node-pools list --cluster CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION
다음을 바꿉니다.
CLUSTER_NAME
: 클러스터의 이름입니다.CONTROL_PLANE_LOCATION
: 클러스터의 컨트롤 플레인에 대한 Compute Engine 위치. 리전 클러스터의 경우 리전 또는 영역 클러스터의 경우 영역을 제공합니다.
기존 노드 풀에서 자동 확장을 사용 중지하려면(사용 설정된 경우) 다음 명령어를 실행합니다.
gcloud container clusters update CLUSTER_NAME --location=CONTROL_PLANE_LOCATION \ --no-enable-autoscaling \ --node-pool=EXISTING_NODE_POOL_NAME
다음 명령어를 실행하여 포드가 실행 중인 노드를 확인합니다 (
NODE
열 참조).kubectl get pods -o=wide
기존 노드 풀의 노드 목록을 가져오고
EXISTING_NODE_POOL_NAME
을 이름으로 바꿉니다.kubectl get nodes -l cloud.google.com/gke-nodepool=EXISTING_NODE_POOL_NAME
kubectl cordon NODE
명령어를 실행합니다(NODE
를 이전 명령어 이름으로 대체). 다음 셸 명령어는 기존 노드 풀에서 각 노드를 반복하고 예약 불가능으로 표시합니다.for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=EXISTING_NODE_POOL_NAME -o=name); do kubectl cordon "$node"; done
선택적으로 기존 노드 풀에서 실행되는 워크로드를 업데이트하여
cloud.google.com/gke-nodepool:NEW_NODE_POOL_NAME
라벨의 nodeSelector를 추가합니다. 여기서NEW_NODE_POOL_NAME
은 새 노드 풀의 이름입니다. 이렇게 하면 GKE가 새 노드 풀의 노드에 이러한 워크로드를 배치합니다.10초의 할당된 단계적 종료 시간에 따라 포드를 제거하여 각 노드를 드레이닝합니다.
for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=EXISTING_NODE_POOL_NAME -o=name); do kubectl drain --force --ignore-daemonsets --delete-emptydir-data --grace-period=GRACEFUL_TERMINATION_SECONDS "$node"; done
GRACEFUL_TERMINATION_PERIOD_SECONDS
를 단계적 종료에 필요한 시간으로 바꿉니다.다음 명령어를 실행하여 기존 노드 풀의 노드가 노드 목록에서
SchedulingDisabled
상태인지 확인합니다.kubectl get nodes
또한 이제 새 노드 풀의 노드에서 포드가 실행 중임을 확인할 수 있습니다.
kubectl get pods -o=wide
필요하지 않은 경우 기존 노드 풀을 삭제합니다.
gcloud container node-pools delete default-pool --cluster CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION
다음 단계
문서에서 문제 해결 방법을 찾을 수 없으면 지원 받기를 참조하여 다음 주제에 대한 조언을 포함한 추가 도움을 요청하세요.
- Cloud Customer Care에 문의하여 지원 케이스를 엽니다.
- StackOverflow에서 질문하고
google-kubernetes-engine
태그를 사용하여 유사한 문제를 검색해 커뮤니티의 지원을 받습니다.#kubernetes-engine
Slack 채널에 가입하여 더 많은 커뮤니티 지원을 받을 수도 있습니다. - 공개 Issue Tracker를 사용하여 버그나 기능 요청을 엽니다.