Esta página mostra como executar cargas de trabalho tolerantes a falhas a custos mais baixos através de pods de instância instantânea nos clusters do Autopilot do Google Kubernetes Engine (GKE).
Vista geral
Nos clusters do GKE Autopilot, os pods de capacidade instantânea são pods que são executados em nós suportados por VMs de capacidade instantânea do Compute Engine. Os Spot Pods têm um preço inferior ao dos Autopilot Pods padrão, mas podem ser desalojados pelo GKE sempre que forem necessários recursos de computação para executar Pods padrão.
Os Spot Pods são ideais para executar cargas de trabalho sem estado, em lote ou com tolerância a falhas a custos mais baixos em comparação com a execução dessas cargas de trabalho como Pods padrão. Para usar Spot Pods em clusters do Autopilot, modifique o manifesto com a especificação do pod para pedir Spot Pods.
Pode executar Spot Pods na classe de computação Autopilot de uso geral predefinida, bem como em classes de computação especializadas que cumprem requisitos de hardware específicos. Para ver informações sobre estas classes de computação, consulte o artigo Classes de computação no Autopilot.
Para saber mais sobre os preços dos Spot Pods em clusters do Autopilot, consulte os preços do Google Kubernetes Engine.
Os Spot Pods estão excluídos do contrato de nível de serviço do Autopilot.
Vantagens
A utilização de Spot Pods nos seus clusters do Autopilot oferece-lhe as seguintes vantagens:
- Preços mais baixos do que a execução das mesmas cargas de trabalho em Autopilot Pods padrão.
- O GKE gere automaticamente a escala automática e o agendamento.
- O GKE contamina automaticamente os nós que executam pods de spot para garantir que os pods padrão, como as suas cargas de trabalho críticas, não são agendados nesses nós. As suas implementações que usam Spot Pods são atualizadas automaticamente com uma tolerância correspondente.
Antes de começar
Antes de começar, certifique-se de que realizou as seguintes tarefas:
- Ative a API Google Kubernetes Engine. Ative a API Google Kubernetes Engine
- Se quiser usar a CLI gcloud para esta tarefa,
instale-a e, em seguida,
inicialize-a. Se instalou anteriormente a CLI gcloud, execute o comando
gcloud components update
para obter a versão mais recente. As versões anteriores da CLI gcloud podem não suportar a execução dos comandos neste documento.
Peça Spot Pods nas suas cargas de trabalho do Autopilot
Para pedir que os seus Pods sejam executados como Spot Pods, use a etiqueta cloud.google.com/gke-spot=true
num nodeSelector ou numa nodeAffinity na especificação do seu Pod. O GKE aprovisiona automaticamente nós
que podem executar pods spot.
Os Spot Pods podem ser desalojados e terminados em qualquer altura, por exemplo, se os recursos de computação forem necessários noutro local em Google Cloud. Quando ocorre uma rescisão, os Spot Pods no nó de rescisão podem pedir um período de tolerância de até 15 segundos antes da rescisão, que é concedido com base no melhor esforço, especificando o campo terminationGracePeriodSeconds
.
O período de tolerância máximo concedido aos Spot Pods durante a preempção é de 15 segundos. Pedir mais de 15 segundos em terminationGracePeriodSeconds
não concede mais de 15 segundos durante a preempção. Na expulsão, o seu pod recebe o sinal SIGTERM e deve tomar medidas para encerrar durante o período de tolerância.
Para o Autopilot, o GKE também marca automaticamente os nós criados para executar pods Spot e modifica essas cargas de trabalho com a tolerância correspondente. A restrição impede que os pods padrão sejam agendados em nós que executam pods de instância de custo reduzido.
Use um nodeSelector para exigir pods spot
Pode usar um nodeSelector para exigir Spot Pods numa implementação. Adicione a etiqueta cloud.google.com/gke-spot=true
à sua implementação, como no seguinte exemplo:
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
metadata:
labels:
app: pi
spec:
nodeSelector:
cloud.google.com/gke-spot: "true"
terminationGracePeriodSeconds: 15
containers:
- name: pi
image: perl:5.34.0
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
Use a afinidade de nós para pedir pods spot
Em alternativa, pode usar a afinidade de nós para pedir Spot Pods. A afinidade de nós oferece uma forma mais extensível de selecionar nós para executar as suas cargas de trabalho. Por exemplo, pode combinar vários critérios de seleção para ter um controlo mais preciso sobre onde os seus pods são executados. Quando usa a afinidade de nós para pedir Spot Pods, pode especificar o tipo de afinidade de nós a usar, da seguinte forma:
requiredDuringSchedulingIgnoredDuringExecution
: tem de usar Spot Pods.preferredDuringSchedulingIgnoredDuringExecution
: use Spot Pods com base no melhor esforço.
Para usar a afinidade de nós para exigir Spot Pods numa implementação, adicione a seguinte regra nodeAffinity
ao manifesto de implementação:
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
metadata:
labels:
app: pi
spec:
terminationGracePeriodSeconds: 15
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: cloud.google.com/gke-spot
operator: In
values:
- "true"
containers:
- name: pi
image: perl:5.34.0
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
Pedir Spot Pods com base no melhor esforço
Para usar a afinidade de nós para pedir Spot Pods com base no melhor esforço, use
preferredDuringSchedulingIgnoredDuringExecution
.
Quando pede Spot Pods numa base preferencial, o GKE agenda os seus pods com base na seguinte ordem:
- Nós existentes que podem executar Spot Pods com capacidade atribuível disponível.
- Nós padrão existentes com capacidade atribuível disponível.
- Novos nós que podem executar pods de spot, se os recursos de computação estiverem disponíveis.
- Novos nós padrão.
Uma vez que o GKE prefere nós padrão existentes com capacidade atribuível à criação de novos nós para pods de spot, pode reparar que mais pods são executados como pods padrão do que como pods de spot, o que impede que tire total partido dos preços mais baixos dos pods de spot.
Pedidos de agrupamentos preemptivos
Os clusters do Autopilot suportam pedidos de pods preemptíveis através do seletor cloud.google.com/gke-preemptible
. Os pods que usam este seletor são migrados automaticamente para pods de spot, e o seletor é alterado para cloud.google.com/gke-spot
.
Encontre e elimine pods terminados
Durante o encerramento gracioso do pod, o kubelet atribui um estado Failed
e um motivo Shutdown
aos pods encerrados. Quando o número de pods terminados atinge um limite de 1000, a recolha de lixo limpa os pods. Também pode eliminar manualmente os pods encerrados através do seguinte comando:
kubectl get pods --all-namespaces | grep -i shutdown | awk '{print $1, $2}' | xargs -n2 kubectl delete pod -n
Impeça que as cargas de trabalho usem pods do Spot
Se tiver Spot Pods existentes que quer atualizar para serem executados como Pods padrão, pode usar um dos seguintes métodos:
- Recrie a carga de trabalho: elimine a implementação, remova as linhas no manifesto que selecionam pods Spot e, em seguida, aplique o manifesto de implementação atualizado ao cluster.
- Edite a carga de trabalho: edite a especificação de implementação enquanto os pods estão a ser executados no cluster.
Com ambos os métodos, pode sentir pequenas interrupções na carga de trabalho.
Recrie a carga de trabalho
Os passos seguintes mostram como eliminar a implementação existente e aplicar um manifesto atualizado ao cluster. Também pode usar estes passos para outros tipos de cargas de trabalho do Kubernetes, como Jobs.
Para garantir que o GKE coloca os pods atualizados no tipo correto de nó, tem de exportar o estado existente da carga de trabalho do servidor da API Kubernetes para um ficheiro e editar esse ficheiro.
Escreva a especificação da carga de trabalho num ficheiro YAML:
kubectl get deployment DEPLOYMENT_NAME -o yaml > DEPLOYMENT_NAME-on-demand.yaml
Substitua
DEPLOYMENT_NAME
pelo nome da sua implementação. Para outros tipos de cargas de trabalho, como Jobs ou Pods, use o nome do recurso correspondente no comandokubectl get
, comokubectl get pod
.Abra o ficheiro YAML num editor de texto:
vi DEPLOYMENT_NAME-on-demand.yaml
Remova o nodeSelector para Spot Pods e a tolerância que o GKE adicionou para Spot Pods do ficheiro:
apiVersion: apps/v1 kind: Deployment metadata: annotations: # lines omitted for clarity spec: progressDeadlineSeconds: 600 replicas: 6 revisionHistoryLimit: 10 selector: matchLabels: pod: nginx-pod strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate template: metadata: # lines omitted for clarity spec: containers: - image: nginx imagePullPolicy: Always name: web-server resources: limits: ephemeral-storage: 1Gi requests: cpu: 500m ephemeral-storage: 1Gi memory: 2Gi securityContext: capabilities: drop: - NET_RAW terminationMessagePath: /dev/termination-log terminationMessagePolicy: File dnsPolicy: ClusterFirst nodeSelector: cloud.google.com/gke-spot: "true" restartPolicy: Always schedulerName: default-scheduler securityContext: seccompProfile: type: RuntimeDefault terminationGracePeriodSeconds: 15 tolerations: - effect: NoSchedule key: kubernetes.io/arch operator: Equal value: amd64 - effect: NoSchedule key: cloud.google.com/gke-spot operator: Equal value: "true" status: #lines omitted for clarity
Tem de remover a tolerância e o nodeSelector para indicar ao GKE que os pods têm de ser executados em nós a pedido em vez de em nós Spot.
Guarde o manifesto atualizado.
Elimine e volte a aplicar o manifesto de implementação ao cluster:
kubectl replace -f DEPLOYMENT_NAME-on-demand.yaml
A duração desta operação depende do número de pods que o GKE tem de terminar e limpar.
Edite a carga de trabalho no local
Os passos seguintes mostram como editar uma implementação em execução no local para indicar ao GKE que os pods têm de ser executados em nós a pedido. Também pode usar estes passos para outros tipos de cargas de trabalho do Kubernetes, como Jobs.
Tem de editar o objeto de carga de trabalho na API Kubernetes porque o GKE adiciona automaticamente uma tolerância para pods de spot à especificação da carga de trabalho durante a admissão da carga de trabalho.
Abra o manifesto da carga de trabalho para edição num editor de texto:
kubectl edit deployment/DEPLOYMENT_NAME
Substitua
DEPLOYMENT_NAME
pelo nome da implementação. Para outros tipos de cargas de trabalho, como Jobs ou Pods, use o nome do recurso correspondente no comandokubectl edit
, comokubectl edit pod/POD_NAME
.No editor de texto, elimine o seletor de nós ou a regra de afinidade de nós para os Spot Pods e a tolerância que o GKE adicionou ao manifesto, como no exemplo seguinte:
apiVersion: apps/v1 kind: Deployment metadata: name: example-deployment namespace: default spec: replicas: 1 selector: matchLabels: type: dev template: metadata: labels: type: dev spec: nodeSelector: cloud.google.com/gke-spot: "true" tolerations: - effect: NoSchedule key: cloud.google.com/gke-spot operator: Equal value: "true" containers: - name: nginx image: nginx ports: - containerPort: 80
Guarde o manifesto atualizado e feche o editor de texto. A configuração do objeto atualizada indica ao GKE que os pods têm de ser executados em nós a pedido. O GKE recria os pods para os colocar em novos nós a pedido.
Verifique se as cargas de trabalho são executadas em nós a pedido
Para verificar se as cargas de trabalho atualizadas já não são executadas em Spot Pods, inspecione a carga de trabalho e procure a tolerância para Spot Pods:
Inspecione a carga de trabalho:
kubectl describe deployment DEPLOYMENT_NAME
O resultado não apresenta uma entrada para cloud.google.com/gke-spot
no campo spec.tolerations
.
O que se segue?
- Saiba mais sobre a arquitetura de clusters do Autopilot.
- Saiba mais sobre o ciclo de vida dos agrupamentos.
- Leia acerca das VMs Spot em clusters padrão do GKE.