Nesta página, mostramos como resolver problemas com pools de nós do modo padrão do GKE.
Se precisar de mais ajuda, entre em contato com o Cloud Customer Care.Problemas de criação de pool de nós
Nesta seção, listamos problemas que podem ocorrer ao criar novos pools de nós em clusters padrão e fornecemos sugestões de como corrigi-los.
Falha na criação do pool de nós devido à disponibilidade de recursos
O problema a seguir ocorre quando você cria um pool de nós com hardware específico em uma zona do Google Cloud que não tem hardware suficiente disponível para atender aos requisitos.
Para validar se a criação do pool de nós falhou porque uma zona não tinha recursos suficientes, verifique se há mensagens de erro relevantes nos registros.
Acesse a Análise de registros no console do Google Cloud.
No campo Consulta, insira a seguinte consulta:
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")
Substitua
CLUSTER_NAME
pelo nome do cluster do GKE.Clique em Executar consulta.
Talvez você verá uma das seguintes mensagens de erro:
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'
Resolver
Para resolver esse problema, tente o seguinte:
- Verifique se a região ou zona selecionada do Google Cloud tem o hardware específico de que você precisa. Use a tabela de disponibilidade do Compute Engine para verificar se determinadas zonas aceitam hardware específico. Escolha uma região ou zona do Google Cloud diferente para os nós que possam ter melhor disponibilidade do hardware necessário.
- Crie o pool de nós com tipos de máquina menores. Aumente o número de nós no pool para que a capacidade de computação total permaneça a mesma.
- Use a reserva de capacidade do Compute Engine para reservar os recursos com antecedência.
- Use o provisionamento de melhor esforço, descrito na seção a seguir, para criar o pool de nós se ele puder provisionar pelo menos um número mínimo especificado de nós do número solicitado.
Provisionamento de melhor esforço
Para determinados hardwares, é possível usar o provisionamento de melhor esforço, que diz ao GKE para criar o pool de nós se ele puder provisionar pelo menos um número mínimo de nós. O GKE continua tentando provisionar os nós restantes para atender à solicitação original ao longo do tempo. Para instruir o GKE a usar o provisionamento de melhor esforço, use o seguinte comando:
gcloud container node-pools create NODE_POOL_NAME \
--cluster=CLUSTER_NAME \
--node-locations=ZONE1,ZONE2,... \
--machine-type=MACHINE_TYPE
--best-effort-provision \
--min-provision-nodes=MINIMUM_NODES
Substitua:
NODE_POOL_NAME
: o nome do novo pool de nós.ZONE1,ZONE2,...
: as zonas do Compute Engine para os nós. Essas zonas precisam ser compatíveis com o hardware selecionado.MACHINE_TYPE
: o tipo de máquina do Compute Engine para os nós. Por exemplo,a2-highgpu-1g
.MINIMUM_NODES
: o número mínimo de nós para o GKE provisionar e criar o pool de nós. Se omitido, o padrão é1
.
Por exemplo, considere um cenário em que você precisa de 10 nós com GPUs NVIDIA® A100 de 40 GB anexadas a us-central1-c
. De acordo com a
tabela de disponibilidade de regiões e zonas de GPU,
essa zona é compatível com GPUs A100. Para evitar a falha na criação do pool de nós se 10 máquinas de GPU não estiverem disponíveis, use o provisionamento de melhor esforço.
gcloud container node-pools create a100-nodes \
--cluster=ml-cluster \
--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
O GKE cria o pool de nós mesmo que apenas cinco GPUs estejam disponíveis em us-central1-c
. Com o tempo, o GKE tenta provisionar mais nós até que haja 10 nós no pool.
Migrar cargas de trabalho entre pools de nós
Use as instruções a seguir para migrar cargas de trabalho de um pool de nós para outro. Se você quiser alterar os atributos de máquina dos nós no pool de nós, consulte Escalonar verticalmente alterando os atributos da máquina de nós.
Como migrar pods para um novo pool de nós
Para migrar pods para um novo pool de nós, faça o seguinte:
Demarque o pool de nós existente: esta operação marca os nós no pool de nós existente como não programáveis. O Kubernetes para de programar novos pods para esses nós quando você os sinaliza como não programáveis.
Drene o pool de nós existente: esta operação remove as cargas de trabalho em execução nos nós do pool de nós existente normalmente.
Essas etapas fazem com que os pods em execução no pool de nós atual sejam encerrados de maneira prática. O Kubernetes faz a reprogramação delas em outros nós disponíveis.
Para garantir que o Kubernetes encerre seus aplicativos normalmente, seus contêineres devem manipular o sinal SIGTERM. Use essa abordagem para fechar conexões ativas com clientes e confirmar ou reverter transações de banco de dados de maneira limpa. No manifesto do pod, use o campo spec.terminationGracePeriodSeconds
para especificar quanto tempo o Kubernetes precisa aguardar antes de interromper os contêineres no pod. O padrão é 30 segundos.
Leia mais sobre o encerramento de pods na documentação do Kubernetes.
Você pode restringir e drenar nós usando os comandos kubectl cordon
e kubectl drain
.
Criar pool de nós e migrar cargas de trabalho
Para migrar as cargas de trabalho para um novo pool de nós, crie o novo pool de nós e, em seguida, restrinja e esvazie os nós no pool atual:
Adicione um pool de nós ao cluster.
Para verificar se o novo pool de nós foi criado, execute o seguinte comando:
gcloud container node-pools list --cluster CLUSTER_NAME
Execute o seguinte comando para ver em qual nó os pods são executados. Consulte a coluna
NODE
:kubectl get pods -o=wide
Receba uma lista de nós no pool de nós atual, substituindo
EXISTING_NODE_POOL_NAME
pelo nome:kubectl get nodes -l cloud.google.com/gke-nodepool=EXISTING_NODE_POOL_NAME
Execute o comando
kubectl cordon NODE
. SubstituaNODE
pelos nomes do comando anterior. O comando do shell a seguir itera cada nó no pool de nós atual e os marca como não programáveis:for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=EXISTING_NODE_POOL_NAME -o=name); do kubectl cordon "$node"; done
Se quiser, atualize as cargas de trabalho em execução no pool de nós atual para adicionar um nodeSelector para o rótulo
cloud.google.com/gke-nodepool:NEW_NODE_POOL_NAME
, em queNEW_NODE_POOL_NAME
é o nome do novo pool de nós. Isso garante que o GKE coloque essas cargas de trabalho em nós no novo pool de nós.Drene cada nó removendo pods com um período de encerramento normal de 10 segundos:
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
Substitua
GRACEFUL_TERMINATION_PERIOD_SECONDS
pelo tempo necessário para o encerramento normal.Execute o comando a seguir para ver se os nós no pool atual têm o status
SchedulingDisabled
na lista de nós:kubectl get nodes
Além disso, você vai notar que os pods agora estão em execução nos nós no novo pool de nós:
kubectl get pods -o=wide
Exclua o pool de nós atual se não precisar mais dele:
gcloud container node-pools delete default-pool --cluster CLUSTER_NAME