Esta página mostra-lhe como resolver problemas com os conjuntos de nós do modo padrão do GKE.
Problemas de criação do node pool
Esta secção apresenta uma lista de problemas que podem ocorrer ao criar novos node pools em clusters padrão e fornece sugestões sobre como os pode corrigir.
Problema: a criação do node pool falha devido a recursos insuficientes
O seguinte problema ocorre quando cria um node pool com hardware específico numa zona que não tem hardware suficiente disponível para satisfazer os seus requisitos. Google Cloud
Para validar se a criação do conjunto de nós falhou porque uma zona não tinha recursos suficientes, verifique os registos para ver se existem mensagens de erro relevantes.
Aceda ao Explorador de registos na Google Cloud consola:
No campo Consulta, especifique 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.
Pode 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'
Para resolver este problema, experimente as seguintes sugestões:
- Certifique-se de que a Google Cloud região ou a zona selecionada tem o hardware específico de que precisa. Use a tabela de disponibilidade do Compute Engine para verificar se zonas específicas suportam hardware específico. Escolha uma Google Cloud região ou uma zona diferente para os seus nós que possa ter uma melhor disponibilidade do hardware de que precisa.
- Crie o node pool com tipos de máquinas mais pequenos. Aumentar o número de nós no conjunto de nós para que a capacidade de computação total permaneça igual.
- Use a reserva de capacidade do Compute Engine para reservar os recursos antecipadamente.
- Use o aprovisionamento de melhor esforço, descrito na secção seguinte, para criar com êxito o conjunto de nós se puder aprovisionar, pelo menos, um número mínimo especificado de nós a partir do número pedido.
Aprovisionamento com o melhor esforço
Para determinado hardware, pode usar o aprovisionamento de melhor esforço, que indica ao GKE para criar com êxito o conjunto de nós se conseguir aprovisionar pelo menos um número mínimo especificado de nós. O GKE continua a tentar aprovisionar os nós restantes para satisfazer o pedido original ao longo do tempo. Para indicar ao GKE que use o aprovisionamento de melhor esforço, use o seguinte comando:
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
Substitua o seguinte:
NODE_POOL_NAME
: o nome do novo node pool.CONTROL_PLANE_LOCATION
: a localização do Compute Engine do plano de controlo do seu cluster. Indique uma região para clusters regionais ou uma zona para clusters zonais.ZONE1,ZONE2,...
: as zonas do Compute Engine para os nós. Estas zonas têm de suportar 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 aprovisionar e criar com êxito o conjunto de nós. Se for omitido, o valor predefinido é1
.
Por exemplo, considere um cenário em que precisa de 10 nós com GPUs NVIDIA A100 de 40 GB anexadas em us-central1-c
. De acordo com a tabela de disponibilidade de regiões e zonas de GPUs, esta zona suporta GPUs A100. Para evitar a falha na criação do conjunto de nós se não estiverem disponíveis 10 máquinas com GPU, use o aprovisionamento de melhor esforço.
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
O GKE cria o node pool, mesmo que apenas cinco GPUs estejam disponíveis em us-central1-c
. Ao longo do tempo, o GKE tenta aprovisionar mais nós até existirem 10 nós no conjunto de nós.
Erro: a instância não contém metadados "instance-template"
Pode ver o seguinte erro como estado de um conjunto de nós que não consegue atualizar, dimensionar nem realizar a reparação automática de nós:
Instance INSTANCE_NAME does not contain 'instance-template' metadata
Este erro indica que os metadados das instâncias de VM, atribuídos pelo GKE, foram danificados. Normalmente, isto acontece quando a automatização ou os scripts criados pelo utilizador tentam adicionar novos metadados de instâncias (como block-project-ssh-keys
) e, em vez de apenas adicionar ou atualizar valores, também eliminam os metadados existentes.
Pode ler acerca dos metadados da instância de VM em
Definir metadados personalizados.
Caso algum dos valores de metadados críticos (entre outros: instance-template
,
kube-labels
, kubelet-config
, kubeconfig
, cluster-name
, configure-sh
,
cluster-uid
) tenha sido eliminado, o nó ou todo o conjunto de nós pode ficar
num estado instável, uma vez que estes valores são cruciais para as operações do GKE.
Se os metadados da instância estiverem danificados, recomendamos que recupere os metadados recriando o conjunto de nós que contém as instâncias de VMs danificadas. Tem de adicionar um conjunto de nós ao cluster e aumentar o número de nós no novo conjunto de nós, ao mesmo tempo que isola e remove nós noutro. Consulte as instruções para migrar cargas de trabalho entre pools de nós.
Para saber quem e quando os metadados da instância foram editados, pode rever as informações de registo de auditoria do Compute Engine ou encontrar registos através do Explorador de registos com uma consulta de pesquisa semelhante à seguinte:
resource.type="gce_instance_group_manager"
protoPayload.methodName="v1.compute.instanceGroupManagers.setInstanceTemplate"
Nos registos, pode encontrar o endereço IP e o agente do utilizador do originador do pedido. Por exemplo:
requestMetadata: {
callerIp: "REDACTED"
callerSuppliedUserAgent: "google-api-go-client/0.5 GoogleContainerEngine/v1"
}
Migre cargas de trabalho entre node pools
Siga as instruções abaixo para migrar cargas de trabalho de um node pool para outro. Se quiser alterar os atributos da máquina dos nós no seu conjunto de nós, consulte o artigo Escale verticalmente alterando os atributos da máquina dos nós.
Compreenda como migrar agrupamentos para um novo conjunto de nós
Para migrar pods para um novo conjunto de nós, tem de fazer o seguinte:
Isolar os nós no conjunto de nós existente: esta operação marca os nós no conjunto de nós existente como não agendáveis. O Kubernetes deixa de agendar novos pods para estes nós assim que os marcar como não agendáveis.
Esvazie os nós no node pool existente: esta operação desalojar os volumes de trabalho em execução nos nós do node pool existente de forma graciosa.
Estes passos, realizados individualmente para cada nó, fazem com que os pods em execução no seu conjunto de nós existente terminem normalmente. O Kubernetes reagenda-os para outros nós disponíveis.
Para garantir que o Kubernetes termina as suas aplicações corretamente, os contentores devem processar o sinal SIGTERM. Use esta abordagem para fechar as ligações ativas aos clientes e confirmar ou reverter as transações da base de dados de forma limpa. No manifesto do Pod, pode usar o campo spec.terminationGracePeriodSeconds
para especificar quanto tempo o Kubernetes tem de esperar antes de parar os contentores no Pod. A predefinição é 30 segundos.
Pode ler mais acerca da terminação de pods na documentação do Kubernetes.
Pode isolar e esvaziar nós com os comandos kubectl cordon
e kubectl drain
.
Crie um node pool e migre cargas de trabalho
Para migrar as suas cargas de trabalho para um novo node pool, crie o novo node pool e, de seguida, isole e esvazie os nós no node pool existente:
Adicione um grupo de nós ao seu cluster.
Execute o seguinte comando para verificar se o novo conjunto de nós foi criado:
gcloud container node-pools list --cluster CLUSTER_NAME
Para desativar o redimensionamento automático no conjunto de nós existente, se estiver ativado, execute o seguinte comando:
gcloud container clusters update CLUSTER_NAME --location=CONTROL_PLANE_LOCATION \ --no-enable-autoscaling \ --node-pool=EXISTING_NODE_POOL_NAME
Substitua
CONTROL_PLANE_LOCATION
pela localização do Compute Engine do plano de controlo do seu cluster. Indique uma região para clusters regionais ou uma zona para clusters zonais.Execute o seguinte comando para ver em que nó os pods estão a ser executados (consulte a coluna
NODE
):kubectl get pods -o=wide
Obtenha uma lista de nós no conjunto de nós existente, 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 seguinte comando de shell itera cada nó no conjunto de nós existente e marca-os como não agendáveis:for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=EXISTING_NODE_POOL_NAME -o=name); do kubectl cordon "$node"; done
Opcionalmente, atualize as cargas de trabalho em execução no node pool existente para adicionar um nodeSelector para a etiqueta
cloud.google.com/gke-nodepool:NEW_NODE_POOL_NAME
, ondeNEW_NODE_POOL_NAME
é o nome do novo node pool. Isto garante que o GKE coloca essas cargas de trabalho em nós no novo conjunto de nós.Esvazie cada nó removendo todos os pods com um período de encerramento gracioso atribuído 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
pela quantidade de tempo necessária para o encerramento normal.Confirme se os nós no conjunto de nós existente têm o estado
SchedulingDisabled
na lista de nós executando o seguinte comando:kubectl get nodes
Além disso, deve ver que os pods são agora executados nos nós no novo conjunto de nós:
kubectl get pods -o=wide
Elimine o node pool existente se não precisar dele:
gcloud container node-pools delete default-pool --cluster CLUSTER_NAME
O que se segue?
Se não conseguir encontrar uma solução para o seu problema na documentação, consulte a secção Obtenha apoio técnico para receber mais ajuda, incluindo aconselhamento sobre os seguintes tópicos:
- Abrindo um registo de apoio ao cliente através do contacto com o Cloud Customer Care.
- Receber apoio técnico da comunidade fazendo perguntas no StackOverflow e usando a etiqueta
google-kubernetes-engine
para pesquisar problemas semelhantes. Também pode juntar-se ao#kubernetes-engine
canal do Slack para receber mais apoio técnico da comunidade. - Abrir erros ou pedidos de funcionalidades através do rastreador de problemas público.