Esta página mostra como usar VMs preemptíveis no Google Kubernetes Engine (GKE).
Vista geral
As VMs preemptivas são instâncias de VM do Compute Engine com um preço inferior ao das VMs padrão e não oferecem garantia de disponibilidade. As VMs preemptivas oferecem uma funcionalidade semelhante às VMs de instância temporária, mas duram apenas até 24 horas após a criação.
Em alguns casos, uma VM preemptível pode durar mais de 24 horas. Isto pode ocorrer quando a nova instância do Compute Engine é iniciada demasiado rapidamente e o Kubernetes não reconhece que foi criada uma VM do Compute Engine diferente. A instância do Compute Engine subjacente tem uma duração máxima de 24 horas e segue o comportamento esperado da VM preemptível.
Comparação com VMs do Spot
As VMs preemptivas partilham muitas semelhanças com as VMs do Spot, incluindo o seguinte:
- Terminada quando o Compute Engine requer os recursos para executar VMs padrão.
- Útil para executar cargas de trabalho sem estado, em lote ou com tolerância a falhas.
- Preços mais baixos do que os das VMs padrão.
- Nos clusters que executam a versão 1.20 e posteriores do GKE, o encerramento elegante de nós está ativado por predefinição.
- Funciona com o redimensionador automático de clusters e o aprovisionamento automático de nós.
Ao contrário das VMs de spot, que não têm um tempo de expiração máximo, as VMs preemptíveis duram apenas até 24 horas após a criação.
Pode ativar as VMs preemptivas em novos clusters e node pools, usar a afinidade de nós ou de nós para controlar o agendamento e usar restrições e tolerâncias para evitar problemas com cargas de trabalho do sistema quando os nós são preemptivos.nodeSelector
Encerramento e encerramento controlado de VMs preemptivas
Quando o Compute Engine precisa de reaver os recursos usados pelas VMs preemptíveis, é enviado um aviso de preemptibilidade para o GKE. As VMs preemptíveis terminam 30 segundos após receberem um aviso de encerramento.
Por predefinição, os clusters usam o graceful node shutdown. O kubelet repara no aviso de rescisão e rescinde graciosamente os pods que estão a ser executados no nó. Se os pods fizerem parte de uma carga de trabalho gerida, como uma implementação, o controlador cria e agenda novos pods para substituir os pods terminados.
Com base no melhor esforço, o kubelet concede um período de encerramento elegante de 15 segundos para os pods não pertencentes ao sistema, após o qual os pods do sistema (com as priorityClasses system-cluster-critical
ou system-node-critical
) têm 15 segundos para terminar elegantemente. Durante o encerramento elegante de nós, o kubelet atualiza o estado dos pods e atribui uma fase Failed
e um motivo Terminated
aos pods encerrados.
A VM é encerrada 30 segundos após o envio do aviso de rescisão, mesmo que especifique um valor superior a 15 segundos no campo terminationGracePeriodSeconds
do manifesto do agrupamento.
Quando o número de pods terminados atinge um limite de 1000 para clusters com menos de 100 nós ou 5000 para clusters com 100 nós ou mais, a recolha de lixo limpa os pods.
Também pode eliminar manualmente os pods terminados através dos seguintes comandos:
kubectl get pods --all-namespaces | grep -i NodeShutdown | awk '{print $1, $2}' | xargs -n2 kubectl delete pod -n
kubectl get pods --all-namespaces | grep -i Terminated | awk '{print $1, $2}' | xargs -n2 kubectl delete pod -n
Modificações ao comportamento do Kubernetes
A utilização de VMs preemptivas no GKE modifica as garantias fornecidas pelo Kubernetes PodDisruptionBudgets
. A recuperação de VMs preemptíveis é involuntária e não está coberta pelas garantias de PodDisruptionBudgets
.
Pode ocorrer uma indisponibilidade superior à PodDisruptionBudget
configurada.
Limitações
- A funcionalidade de encerramento elegante do nó do kubelet só está ativada em clusters com a versão 1.20 e posteriores do GKE. Para versões do GKE anteriores à 1.20, pode usar o controlador de eventos de terminação de nós do Kubernetes no GCP para terminar graciosamente os seus pods quando as VMs preemptíveis são terminadas.
- As VMs preemptíveis não suportam pools de nós do Windows Server.
- No GKE, não pode alterar a duração do período de tolerância para o encerramento do nó. Os campos de configuração do kubelet
shutdownGracePeriod
eshutdownGracePeriodCriticalPods
são imutáveis.
Crie um cluster ou um node pool com VMs preemptíveis
Pode usar a CLI Google Cloud para criar um cluster ou um conjunto de nós com VMs preemptivas.
Para criar um cluster com VMs preemptivas, execute o seguinte comando:
gcloud container clusters create CLUSTER_NAME \
--preemptible
Substitua CLUSTER_NAME
pelo nome do novo cluster.
Para criar um node pool com VMs preemptivas, execute o seguinte comando:
gcloud container node-pools create POOL_NAME \
--cluster=CLUSTER_NAME \
--preemptible
Substitua POOL_NAME
pelo nome do novo conjunto de nós.
Use nodeSelector para agendar pods em VMs preemptivas
O GKE adiciona as etiquetas cloud.google.com/gke-preemptible=true
e cloud.google.com/gke-provisioning=preemptible
(para nós que executam a versão 1.25.5-gke.2500 ou posterior do GKE) aos nós que usam VMs preemptivas. Pode usar um nodeSelector
nas suas implementações para indicar ao GKE que agende pods em VMs preemptivas.
Por exemplo, os seguintes filtros de implementação para VMs preemptíveis que usam a etiqueta cloud.google.com/gke-preemptible
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-app
spec:
replicas: 3
selector:
matchLabels:
app: hello-app
template:
metadata:
labels:
app: hello-app
spec:
containers:
- name: hello-app
image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0
resources:
requests:
cpu: 200m
nodeSelector:
cloud.google.com/gke-preemptible: "true"
Use taints de nós para VMs preemptivas
Pode contaminar nós que usam VMs preemptivas para que o GKE só possa colocar pods com a tolerância correspondente nesses nós.
Para adicionar uma restrição de nó a um node pool que usa VMs preemptivas, use a flag --node-taints
quando criar o node pool, semelhante ao seguinte comando:
gcloud container node-pools create POOL2_NAME \
--cluster=CLUSTER_NAME \
--node-taints=cloud.google.com/gke-preemptible="true":NoSchedule
Agora, apenas os pods que toleram a rejeição do nó são agendados para o nó.
Para adicionar a tolerância relevante aos seus pods, modifique as implementações e adicione o seguinte à especificação do pod:
tolerations:
- key: cloud.google.com/gke-preemptible
operator: Equal
value: "true"
effect: NoSchedule
Taints de nós para VMs preemptivas de GPU
As VMs preemptíveis suportam a utilização de GPUs. Deve criar, pelo menos, outro conjunto de nós no cluster que não use VMs preemptivas antes de adicionar um conjunto de nós de GPU que use VMs preemptivas. Ter um conjunto de nós padrão garante que o GKE pode colocar em segurança componentes do sistema, como o DNS.
Se criar um novo cluster com pools de nós de GPU que usam VMs preemptivas ou se adicionar um novo pool de nós de GPU que usa VMs preemptivas a um cluster que ainda não tem um pool de nós padrão, o GKE não adiciona automaticamente a restrição nvidia.com/gpu=present:NoSchedule
aos nós. O GKE pode agendar pods do sistema nas VMs preemptíveis, o que pode levar a interrupções. Este comportamento também aumenta o consumo de recursos, porque os nós de GPU são mais caros do que os nós sem GPU.
O que se segue?
- Saiba como executar uma aplicação GKE em VMs Spot com nós a pedido como alternativa.
- Saiba mais sobre as VMs Spot no GKE.
- Saiba mais sobre as restrições e as tolerâncias.