Aprovisione capacidade de computação adicional para o escalonamento rápido de pods

Esta página mostra-lhe como reservar capacidade de computação adicional nos seus clusters do Google Kubernetes Engine (GKE) para que as suas cargas de trabalho possam ser rapidamente dimensionadas durante eventos de tráfego elevado sem esperar que novos nós sejam iniciados. Pode usar estas instruções para reservar a sobrecarga de computação de forma consistente ou antes de eventos específicos.

Por que motivo o aprovisionamento de capacidade adicional é útil

Os clusters do GKE Autopilot e os clusters padrão com aprovisionamento automático de nós criam novos nós quando não existem nós com capacidade para executar novos pods. Cada novo nó demora aproximadamente 80 a 120 segundos a arrancar. O GKE aguarda até que o nó seja iniciado antes de colocar os pods pendentes no novo nó. Depois disso, os pods podem ser iniciados. Nos clusters padrão, em alternativa, pode criar manualmente um novo node pool com a capacidade adicional de que precisa para executar novos pods. Esta página aplica-se a clusters que usam um mecanismo de escalabilidade automática de nós, como o Autopilot ou o aprovisionamento automático de nós.

Em alguns casos, pode querer que os seus pods sejam iniciados mais rapidamente durante eventos de expansão. Por exemplo, se estiver a lançar uma nova expansão para o seu popular jogo multijogador de serviço em direto, os tempos de arranque mais rápidos dos pods do servidor de jogos podem reduzir os tempos de espera para os jogadores que iniciam sessão no dia do lançamento. Como outro exemplo, se tiver uma plataforma de comércio eletrónico e estiver a planear uma venda flash por um período limitado, espera picos de tráfego durante a venda.

O aprovisionamento de capacidade adicional é compatível com o Pod bursting, que permite que os pods usem temporariamente recursos pedidos por outros pods no nó, se essa capacidade estiver disponível e não for usada por outros pods. Para usar o aumento temporário, defina os limites de recursos como superiores aos pedidos de recursos ou não defina limites de recursos. Para ver detalhes, consulte o artigo Configure o aumento rápido de pods no GKE.

Como funciona o aprovisionamento de capacidade adicional no GKE

Para aprovisionar capacidade adicional, pode usar PriorityClassesPriorityClasses e pods de marcadores de posição. Uma PriorityClass permite-lhe indicar ao GKE que algumas cargas de trabalho têm uma prioridade inferior à de outras cargas de trabalho. Pode implementar pods de marcadores de posição que usam uma PriorityClass de baixa prioridade e pedir a capacidade de computação que precisa de reservar. O GKE adiciona capacidade ao cluster criando novos nós para acomodar os pods de marcadores de posição.

Quando as cargas de trabalho de produção são dimensionadas, o GKE despeja os pods de marcadores de posição de prioridade inferior e agenda as novas réplicas dos pods de produção (que usam uma PriorityClass de prioridade superior) no respetivo lugar. Se tiver vários pods de baixa prioridade com diferentes níveis de prioridade, o GKE remove primeiro os pods de prioridade mais baixa.

Métodos de aprovisionamento de capacidade

Consoante o seu exemplo de utilização, pode aprovisionar capacidade adicional nos seus clusters do GKE de uma das seguintes formas:

  • Aprovisionamento de capacidade consistente: use uma implementação para criar um número específico de pods de marcadores de posição de baixa prioridade que são executados constantemente no cluster. Quando o GKE despeja estes pods para executar as suas cargas de trabalho de produção, o controlador de implementação garante que o GKE aprovisiona mais capacidade para recriar os pods de baixa prioridade despejados. Este método oferece custos gerais de capacidade consistentes em vários eventos de aumento e diminuição da escala, até eliminar a implementação.
  • Aprovisionamento de capacidade de utilização única: use uma tarefa para executar um número específico de pods de marcadores de posição paralelos de baixa prioridade durante um período específico. Quando esse tempo tiver passado ou quando o GKE desalojar todas as réplicas do trabalho, a capacidade reservada deixa de estar disponível. Este método oferece uma quantidade específica de capacidade disponível durante um período específico.

Preços

No GKE Autopilot, é-lhe cobrado o valor dos pedidos de recursos dos seus pods em execução, incluindo as cargas de trabalho de baixa prioridade que implementa. Para ver detalhes, consulte os preços do Autopilot.

No GKE Standard, é-lhe cobrado o valor das VMs do Compute Engine subjacentes que o GKE aprovisiona, independentemente de os pods usarem essa capacidade. Para ver os detalhes, consulte a secção Preços padrão

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 gcloud components update para obter a versão mais recente.
  • Certifique-se de que tem um cluster do GKE Autopilot ou um cluster do GKE Standard com o aprovisionamento automático de nós ativado.
  • Leia as Considerações para o aprovisionamento de capacidade de modo a garantir que escolhe valores adequados nos seus pedidos de capacidade.

Crie uma PriorityClass

Para usar qualquer um dos métodos descritos em Métodos de aprovisionamento de capacidade, primeiro, tem de criar as seguintes PriorityClasses:

  • PriorityClass predefinida: uma PriorityClass predefinida global que é atribuída a qualquer Pod que não defina explicitamente uma PriorityClass diferente na especificação do Pod. Os pods com esta PriorityClass predefinida podem despejar pods que usam uma PriorityClass inferior.
  • Low PriorityClass: uma PriorityClass não predefinida definida para a prioridade mais baixa possível no GKE. Os pods com esta PriorityClass podem ser despejados para executar pods com PriorityClasses mais elevadas.
  1. Guarde o seguinte manifesto como priorityclasses.yaml:

    apiVersion: scheduling.k8s.io/v1
    kind: PriorityClass
    metadata:
      name: low-priority
    value: -10
    preemptionPolicy: Never
    globalDefault: false
    description: "Low priority workloads"
    ---
    apiVersion: scheduling.k8s.io/v1
    kind: PriorityClass
    metadata:
      name: default-priority
    value: 0
    preemptionPolicy: PreemptLowerPriority
    globalDefault: true
    description: "The global default priority."
    

    Este manifesto inclui os seguintes campos:

    • preemptionPolicy: especifica se os pods que usam uma PriorityClass podem ou não expulsar pods de prioridade inferior. A low-priority PriorityClass usa Never, e a default PriorityClass usa PreemptLowerPriority.
    • value: a prioridade dos pods que usam a PriorityClass. A default PriorityClass usa 0. A low-priority PriorityClass usa -10. No Autopilot, pode definir este parâmetro para qualquer valor inferior à prioridade da default PriorityClass.

      No modo padrão, se definir este valor para menos de -10, os pods que usam essa PriorityClass não acionam a criação de novos nós e permanecem pendentes.

      Para obter ajuda na decisão sobre os valores adequados para a prioridade, consulte o artigo Escolha uma prioridade.

    • globalDefault: especifica se o GKE atribui ou não a PriorityClass a pods que não definem explicitamente uma PriorityClass na especificação do pod. A low-priority PriorityClass usa false e a default PriorityClass usa true.

  2. Aplique o manifesto:

    kubectl apply -f priorityclasses.yaml
    

Aprovisione capacidade de computação adicional

As secções seguintes mostram um exemplo em que aprovisiona capacidade para um único evento ou de forma consistente ao longo do tempo.

Use uma implementação para o aprovisionamento de capacidade consistente

  1. Guarde o seguinte manifesto como capacity-res-deployment.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: capacity-res-deploy
    spec:
      replicas: 10
      selector:
        matchLabels:
          app: reservation
      template:
        metadata:
          labels:
            app: reservation
        spec:
          priorityClassName: low-priority
          terminationGracePeriodSeconds: 0
          containers:
          - name: ubuntu
            image: ubuntu
            command: ["sleep"]
            args: ["infinity"]
            resources:
              requests:
                cpu: 500m
                memory: 500Mi
    

    Este manifesto inclui os seguintes campos:

    • spec.replicas: altere este valor para cumprir os seus requisitos.
    • spec.resources.requests: altere os pedidos de CPU e memória para satisfazer os seus requisitos. Use as orientações em Escolha o dimensionamento da capacidade para ajudar a decidir sobre os valores de pedidos adequados.
    • spec.containers.command e spec.containers.args: indicam aos pods que devem permanecer ativos até serem removidos pelo GKE.
  2. Aplique o manifesto:

    kubectl apply -f capacity-res-deployment.yaml
    
  3. Veja o estado do agrupamento:

    kubectl get pods -l app=reservation
    

    Aguarde até que todas as réplicas tenham o estado Running.

Use uma tarefa para o aprovisionamento de capacidade de evento único

  1. Guarde o seguinte manifesto como capacity-res-job.yaml:

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: capacity-res-job
    spec:
      parallelism: 4
      backoffLimit: 0
      template:
        spec:
          priorityClassName: low-priority
          terminationGracePeriodSeconds: 0
          containers:
          - name: ubuntu-container
            image: ubuntu
            command: ["sleep"]
            args: ["36000"]
            resources:
              requests:
                cpu: "16"
          restartPolicy: Never
    

    Este manifesto inclui os seguintes campos:

    • spec.parallelism: altere o número de tarefas que quer executar em paralelo para reservar capacidade.
    • spec.backoffLimit: 0: impede que o controlador de tarefas recrie tarefas removidas.
    • template.spec.resources.requests: altere os pedidos de CPU e memória para satisfazer os seus requisitos. Use as orientações em Considerações para ajudar a decidir sobre os valores adequados.
    • template.spec.containers.command e template.spec.containers.args: Indique aos trabalhos que devem permanecer ativos durante o período, em segundos, em que precisa da capacidade adicional.
  2. Aplique o manifesto:

    kubectl apply -f capacity-res-job.yaml
    
  3. Obtenha o estado da tarefa:

    kubectl get jobs
    

    Aguarde até que todas as tarefas tenham o estado Running.

Teste o aprovisionamento e a remoção de capacidade

Para verificar se o aprovisionamento de capacidade funciona como esperado, faça o seguinte:

  1. No terminal, monitorize o estado das cargas de trabalho de aprovisionamento de capacidade:

    1. Para implementações, execute o seguinte comando:

      kubectl get pods --label=app=reservation -w
      
    2. Para tarefas, execute o seguinte comando:

      kubectl get Jobs -w
      
  2. Abra uma nova janela de terminal e faça o seguinte:

    1. Guarde o seguinte manifesto como test-deployment.yaml:

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: helloweb
        labels:
          app: hello
      spec:
        replicas: 5
        selector:
          matchLabels:
            app: hello
            tier: web
        template:
          metadata:
            labels:
              app: hello
              tier: web
          spec:
            containers:
            - name: hello-app
              image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0
              ports:
              - containerPort: 8080
              resources:
                requests:
                  cpu: 400m
                  memory: 400Mi
      
    2. Aplique o manifesto:

      kubectl apply -f test-deployment.yaml
      
  3. Na janela do terminal original, repare que o GKE termina alguns dos trabalhos de aprovisionamento de capacidade para agendar as novas réplicas, de forma semelhante ao seguinte exemplo:

    NAME                                         READY   STATUS    RESTARTS   AGE
    capacity-res-deploy-6bd9b54ffc-5p6wc         1/1     Running   0          7m25s
    capacity-res-deploy-6bd9b54ffc-9tjbt         1/1     Running   0          7m26s
    capacity-res-deploy-6bd9b54ffc-kvqr8         1/1     Running   0          2m32s
    capacity-res-deploy-6bd9b54ffc-n7zn4         1/1     Running   0          2m33s
    capacity-res-deploy-6bd9b54ffc-pgw2n         1/1     Running   0          2m32s
    capacity-res-deploy-6bd9b54ffc-t5t57         1/1     Running   0          2m32s
    capacity-res-deploy-6bd9b54ffc-v4f5f         1/1     Running   0          7m24s
    helloweb-85df88c986-zmk4f                    0/1     Pending   0          0s
    helloweb-85df88c986-lllbd                    0/1     Pending   0          0s
    helloweb-85df88c986-bw7x4                    0/1     Pending   0          0s
    helloweb-85df88c986-gh8q8                    0/1     Pending   0          0s
    helloweb-85df88c986-74jrl                    0/1     Pending   0          0s
    capacity-res-deploy-6bd9b54ffc-v6dtk   1/1     Terminating   0          2m47s
    capacity-res-deploy-6bd9b54ffc-kvqr8   1/1     Terminating   0          2m47s
    capacity-res-deploy-6bd9b54ffc-pgw2n   1/1     Terminating   0          2m47s
    capacity-res-deploy-6bd9b54ffc-n7zn4   1/1     Terminating   0          2m48s
    capacity-res-deploy-6bd9b54ffc-2f8kx   1/1     Terminating   0          2m48s
    ...
    helloweb-85df88c986-lllbd              0/1     Pending       0          1s
    helloweb-85df88c986-gh8q8              0/1     Pending       0          1s
    helloweb-85df88c986-74jrl              0/1     Pending       0          1s
    helloweb-85df88c986-zmk4f              0/1     Pending       0          1s
    helloweb-85df88c986-bw7x4              0/1     Pending       0          1s
    helloweb-85df88c986-gh8q8              0/1     ContainerCreating   0          1s
    helloweb-85df88c986-zmk4f              0/1     ContainerCreating   0          1s
    helloweb-85df88c986-bw7x4              0/1     ContainerCreating   0          1s
    helloweb-85df88c986-lllbd              0/1     ContainerCreating   0          1s
    helloweb-85df88c986-74jrl              0/1     ContainerCreating   0          1s
    helloweb-85df88c986-zmk4f              1/1     Running             0          4s
    helloweb-85df88c986-lllbd              1/1     Running             0          4s
    helloweb-85df88c986-74jrl              1/1     Running             0          5s
    helloweb-85df88c986-gh8q8              1/1     Running             0          5s
    helloweb-85df88c986-bw7x4              1/1     Running             0          5s
    

    Este resultado mostra que a nova implementação demorou 5 segundos a mudar de Pendente para Em execução.

Considerações para o aprovisionamento de capacidade

As secções seguintes fornecem recomendações que podem ajudar a melhorar a fiabilidade da capacidade que aprovisiona.

Aprovisionamento de capacidade consistente

  • Avalie quantas réplicas de agrupamentos de marcadores de posição precisa e o tamanho dos pedidos em cada réplica. As réplicas de baixa prioridade devem pedir pelo menos a mesma capacidade que a sua maior carga de trabalho de produção, para que essas cargas de trabalho possam caber na capacidade reservada pela sua carga de trabalho de baixa prioridade.
  • Se operar um grande número de cargas de trabalho de produção em grande escala, pondere definir os pedidos de recursos dos seus pods de marcadores de posição para valores que aprovisionem capacidade suficiente para executar várias cargas de trabalho de produção em vez de apenas uma.

Aprovisionamento de capacidade de utilização única

  • Defina o período durante o qual as tarefas fictícias devem persistir, de acordo com o período durante o qual precisa de capacidade adicional. Por exemplo, se quiser a capacidade adicional para um dia de lançamento de um jogo de 24 horas, defina o período como 86 400 segundos. Isto garante que a capacidade aprovisionada não dura mais tempo do que o necessário.
  • Defina um período de manutenção para o mesmo período de tempo que está a reservar a capacidade. Isto impede que as tarefas de baixa prioridade sejam removidas durante uma atualização do nó. Definir um período de manutenção também é uma boa prática quando prevê uma elevada procura da sua carga de trabalho.
  • Se operar um grande número de cargas de trabalho de produção em grande escala, pondere definir os pedidos de recursos dos seus trabalhos de marcadores de posição para valores que aprovisionem capacidade suficiente para executar várias cargas de trabalho de produção em vez de apenas uma.

A capacidade só é aprovisionada para um único evento de escalabilidade. Se aumentar a escala e usar a capacidade, e, em seguida, diminuir a escala, essa capacidade deixa de estar disponível para outro evento de aumento da escala. Se prevê vários eventos de aumento e diminuição da escala, use o método de reserva de capacidade consistente e ajuste o tamanho da reserva conforme necessário. Por exemplo, aumentar os pedidos de agrupamentos antes de um evento e diminuí-los ou anulá-los depois.

Escolha uma prioridade

Pode definir várias PriorityClasses no cluster para usar com cargas de trabalho que tenham requisitos diferentes. Por exemplo, pode criar uma PriorityClass com uma prioridade de -10 para o aprovisionamento de capacidade de utilização única e uma PriorityClass com uma prioridade de -9 para o aprovisionamento de capacidade consistente. Em seguida, pode aprovisionar capacidade consistente usando a PriorityClass com uma prioridade de -9 e, quando quiser mais capacidade para um evento especial, pode implementar novos trabalhos que usem a PriorityClass com uma prioridade de -10. O GKE despeja primeiro as cargas de trabalho de prioridade mais baixa.

Também pode usar outras PriorityClasses para executar cargas de trabalho de não produção de baixa prioridade que realizam tarefas reais, como cargas de trabalho em lote com tolerância a falhas, a uma prioridade inferior à das cargas de trabalho de produção, mas superior à dos pods de marcadores de posição. Por exemplo, -5.

Escolha o dimensionamento da capacidade

Defina as contagens de réplicas e os pedidos de recursos da sua carga de trabalho de marcador de posição como superiores ou iguais à capacidade de que as cargas de trabalho de produção podem precisar ao aumentar a escala.

A capacidade total aprovisionada baseia-se no número de agrupamentos de marcadores de posição que implementa e nos pedidos de recursos de cada réplica. Se o aumento da escala exigir mais capacidade do que o GKE aprovisionou para os seus pods de marcadores de posição, algumas das suas cargas de trabalho de produção permanecem em Pending até que o GKE possa aprovisionar mais capacidade.

O que se segue?