Nesta página, mostramos como usar VMs preemptivas no Google Kubernetes Engine (GKE).
Visão geral
As VMs preemptivas são instâncias de VM do Compute Engine com um preço menor que o das VMs padrão e que não oferecem garantia de disponibilidade. As VMs preemptivas oferecem funcionalidade semelhante à do Spot, mas duram apenas 24 horas após a criação.
Em alguns casos, uma VM preemptiva pode durar mais de 24 horas. Isso ocorre quando a nova instância do Compute Engine chega muito rápido e o Kubernetes não reconhece que uma VM do Compute Engine diferente foi criada. A instância subjacente do Compute Engine terá uma duração máxima de 24 horas e seguir o comportamento esperado de VM preemptiva.
Comparação com VMs do Spot
As VMs preemptivas compartilham muitas semelhanças com as VMs do Spot, incluindo:
- Terminado quando o Compute Engine exige que os recursos executem VMs padrão.
- Útil para executar cargas de trabalho sem estado, em lote ou tolerantes a falhas.
- Preço menor que o das VMs padrão.
- Nos clusters que executam o GKE versão 1.20 e mais recente, a opção Encerramento de nó otimizado está ativada por padrão.
- Funcionam com o escalonador automático de cluster e o provisionamento automático de nós.
Ao contrário das VMs do Spot, que não têm prazo de validade máximo, as VMs preemptivas duram somente por 24 horas após a criação.
É possível ativar VMs preemptivas em novos clusters e pools de nós, usar nodeSelector
ou afinidade do nó para controlar a programação e usar taints e tolerâncias para evitar problemas com
as cargas de trabalho do sistema quando os nós são interrompidos.
Encerramento e encerramento otimizado das VMs preemptivas
Quando o Compute Engine precisa recuperar os recursos usados pelas VMs preemptivas, um aviso de preempção é enviado para o GKE. As VMs preemptivas são encerradas 30 segundos após o recebimento de um aviso de encerramento.
Por padrão, os clusters usam a desativação otimizada de nós. O kubelet detecta o aviso de encerramento e encerra corretamente os pods em execução no nó. Se os pods fizerem parte de uma implantação, o controlador vai criar e programar novos pods para substituir os pods encerrados.
Na melhor das hipóteses, o kubelet concede um período de encerramento sem complicações de 15
segundos para pods que não são do sistema. Depois disso, os pods do sistema, com as
classes de prioridade system-cluster-critical
ou system-node-critical
, têm 15
segundos para serem encerrados corretamente.
Durante o encerramento normal dos nós, o kubelet atualiza o status deles,
atribuindo uma fase Failed
e um motivo Terminated
.
Quando o número de pods encerrados atinge um limite de 1.000 para clusters com menos de 100 nós ou 5.000 para clusters com 100 nós ou mais, a coleta de lixo limpa os pods.
Também é possível excluir pods encerrados manualmente usando os 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
Alterações no comportamento do Kubernetes
O uso de VMs preemptivas no GKE altera algumas garantias e restrições que o Kubernetes fornece, como:
O GKE encerra as VMs preemptivas sem um período de encerramento para os pods, 30 segundos após receber um aviso de preempção do Compute Engine.
A recuperação de VMs preemptivas é involuntária e não está coberta pelas garantias de
PodDisruptionBudgets
. Pode haver indisponibilidade maior do que oPodDisruptionBudget
configurado.
Limitações
- O recurso de encerramento otimizado de nós do kubelet só é ativado nos clusters que executam o GKE versão 1.20 e posterior. Para versões do GKE anteriores à 1.20, use o gerenciador de eventos de encerramento de nós do Kubernetes no GCP para encerrar corretamente seus pods quando as VMs preemptivas são encerradas.
- As VMs preemptivas não são compatíveis com os pools de nós do Windows Server.
Criar um cluster ou pool de nós com VMs preemptivas
É possível usar a CLI do Google Cloud para criar um cluster ou pool de nós com VMs preemptivas.
Para criar um cluster com VMs preemptivas, execute o comando a seguir:
gcloud container clusters create CLUSTER_NAME \
--preemptible
Substitua CLUSTER_NAME
pelo nome do novo bucket.
Para criar um pool de nós 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 pool de nós.
Usar o nodeSelector para programar pods em VMs preemptivas
O GKE adiciona os identificadores 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. Use um nodeSelector
nas
implantações para instruir o GKE a programar pods em VMs preemptivas.
Por exemplo, os seguintes filtros de implantação para VMs preemptivas usando o
identificador 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"
Usar taints de nó para VMs preemptivas
É possível usar taint de nós que usam VMs preemptivas para que o GKE coloque apenas pods com tolerância correspondente nesses nós.
Para adicionar um taint a um pool de nós que usa VMs preemptivas, use a
sinalização --node-taints
ao criar o pool de nós, 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 o taint serão programados no nó.
Para adicionar a tolerância relevante aos pods, modifique as implantaçõ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ó para VMs preemptivas de GPU
As VMs preemptivas são compatíveis com GPUs. Crie pelo menos um outro pool de nós no cluster que não use VMs preemptivas antes de adicionar um pool de nós de GPU que use VMs preemptivas. Ter um pool de nós padrão garante que o GKE possa colocar componentes do sistema com segurança, como DNS.
Se você 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 use VMs preemptivas a um cluster que ainda não
tem um pool de nós sob demanda, o GKE não adiciona
automaticamente o taint nvidia.com/gpu=present:NoSchedule
aos nós. O GKE
pode programar pods do sistema nas VMs preemptivas, o que pode gerar
interrupções. Esse comportamento também aumenta o consumo de recursos, porque os nós do
GPU são mais caros do que os nós não-GPU.
A seguir
- Saiba como executar um aplicativo do GKE em VMs do Spot com nós sob demanda como substituto.
- Saiba mais sobre Spot VMs no GKE.
- Saiba mais sobre taints e tolerâncias.