Proporcionar capacidad de computación adicional para escalar rápidamente los pods

En esta página se explica cómo reservar capacidad de computación adicional en tus clústeres de Google Kubernetes Engine (GKE) para que tus cargas de trabajo puedan aumentar rápidamente durante eventos de tráfico elevado sin tener que esperar a que se inicien nuevos nodos. Puedes seguir estas instrucciones para reservar la sobrecarga de computación de forma constante o antes de eventos específicos.

Por qué es útil el aprovisionamiento de capacidad de reserva

Los clústeres Autopilot y Estándar de GKE con aprovisionamiento automático de nodos crean nodos nuevos cuando no hay nodos con capacidad para ejecutar nuevos pods. Cada nodo nuevo tarda entre 80 y 120 segundos en iniciarse. GKE espera a que el nodo se haya iniciado antes de colocar los pods pendientes en el nuevo nodo, tras lo cual los pods pueden iniciarse. En los clústeres estándar, también puedes crear manualmente un grupo de nodos que tenga la capacidad adicional que necesitas para ejecutar nuevos pods. Esta página se aplica a los clústeres que usan un mecanismo de autoescalado de nodos, como Autopilot o el aprovisionamiento automático de nodos.

En algunos casos, puede que quieras que tus pods se inicien más rápido durante los eventos de escalado vertical. Por ejemplo, si vas a lanzar una nueva expansión para tu popular juego multijugador como servicio, los tiempos de arranque más rápidos de los pods de tu servidor de juego podrían reducir los tiempos de espera de los jugadores que inicien sesión el día del lanzamiento. Por ejemplo, si gestionas una plataforma de comercio electrónico y tienes previsto hacer una oferta flash durante un tiempo limitado, es de esperar que haya picos de tráfico mientras dure la oferta.

El aprovisionamiento de capacidad de reserva es compatible con el bursting de pods, que permite que los pods usen temporalmente los recursos que hayan solicitado otros pods en el nodo, si esa capacidad está disponible y otros pods no la utilizan. Para usar el bursting, define límites de recursos superiores a tus solicitudes de recursos o no definas límites de recursos. Para obtener más información, consulta Configurar el aumento de pods en GKE.

Cómo funciona el aprovisionamiento de capacidad de reserva en GKE

Para aprovisionar capacidad de reserva, puedes usar PriorityClasses de Kubernetes y pods de marcador de posición. PriorityClass te permite indicar a GKE que algunas cargas de trabajo tienen una prioridad inferior a otras. Puedes desplegar pods de marcador de posición que usen una clase PriorityClass de baja prioridad y solicitar la capacidad de computación que necesites reservar. GKE añade capacidad al clúster creando nuevos nodos para dar cabida a los pods de marcador de posición.

Cuando las cargas de trabajo de producción se escalan verticalmente, GKE expulsa los pods de marcador de posición de menor prioridad y programa las nuevas réplicas de los pods de producción (que usan una PriorityClass de mayor prioridad) en su lugar. Si tienes varios pods de baja prioridad con diferentes niveles de prioridad, GKE desalojará primero los pods de menor prioridad.

Métodos de aprovisionamiento de capacidad

En función de tu caso práctico, puedes aprovisionar capacidad adicional en tus clústeres de GKE de una de las siguientes formas:

  • Provisionamiento de capacidad constante: usa un Deployment para crear un número específico de pods de marcador de posición de baja prioridad que se ejecuten constantemente en el clúster. Cuando GKE expulsa estos pods para ejecutar tus cargas de trabajo de producción, el controlador de Deployment se asegura de que GKE proporcione más capacidad para recrear los pods de baja prioridad expulsados. Este método proporciona una sobrecarga de capacidad coherente en varios eventos de escalado vertical y horizontal hasta que elimines la implementación.
  • Provisionamiento de capacidad de un solo uso: usa un trabajo para ejecutar un número específico de pods de marcador de posición paralelos de baja prioridad durante un periodo concreto. Cuando haya transcurrido ese tiempo o cuando GKE expulse todas las réplicas de Job, la capacidad reservada dejará de estar disponible. Este método proporciona una cantidad específica de capacidad disponible durante un periodo concreto.

Precios

En Autopilot de GKE, se te cobra por las solicitudes de recursos de tus pods en ejecución, incluidas las cargas de trabajo de baja prioridad que implementes. Para obtener más información, consulta los precios de Autopilot.

En GKE Standard, se te cobra por las VMs de Compute Engine subyacentes que aprovisiona GKE, independientemente de si los pods usan esa capacidad. Para obtener más información, consulta los precios estándar.

Antes de empezar

Antes de empezar, asegúrate de que has realizado las siguientes tareas:

  • Habilita la API de Google Kubernetes Engine.
  • Habilitar la API de Google Kubernetes Engine
  • Si quieres usar Google Cloud CLI para esta tarea, instálala y, a continuación, inicialízala. Si ya has instalado la gcloud CLI, obtén la versión más reciente ejecutando gcloud components update.
  • Asegúrate de tener un clúster de Autopilot de GKE o un clúster estándar de GKE con el aprovisionamiento automático de nodos habilitado.
  • Consulta las consideraciones sobre el aprovisionamiento de capacidad para asegurarte de que eliges los valores adecuados en tus solicitudes de capacidad.

Crear un PriorityClass

Para usar cualquiera de los métodos descritos en Métodos de aprovisionamiento de capacidad, primero debes crear las siguientes PriorityClasses:

  • PriorityClass predeterminada: es una PriorityClass predeterminada global que se asigna a cualquier pod que no defina explícitamente otra PriorityClass en la especificación del pod. Los pods con este PriorityClass predeterminado pueden desalojar pods que usen un PriorityClass inferior.
  • PriorityClass de baja prioridad: PriorityClass no predeterminado definido con la prioridad más baja posible en GKE. Los pods con este PriorityClass se pueden desalojar para ejecutar pods con PriorityClass más altos.
  1. Guarda el siguiente archivo de manifiesto 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 manifiesto incluye los siguientes campos:

    • preemptionPolicy: especifica si los pods que usan una PriorityClass pueden expulsar pods de menor prioridad. low-priority PriorityClass usa Never, y default PriorityClass usa PreemptLowerPriority.
    • value: la prioridad de los pods que usan PriorityClass. default PriorityClass usa 0. low-priority PriorityClass usa -10. En Autopilot, puedes asignar a este campo cualquier valor inferior a la prioridad de default PriorityClass.

      En Standard, si asignas a este valor un número inferior a -10, los pods que usen esa PriorityClass no activarán la creación de nodos nuevos y permanecerán en estado Pending.

      Para obtener ayuda a la hora de decidir los valores de prioridad adecuados, consulta Elegir una prioridad.

    • globalDefault: especifica si GKE asigna o no la PriorityClass a los pods que no definen explícitamente una PriorityClass en la especificación del pod. low-priority PriorityClass usa false y default PriorityClass usa true.

  2. Aplica el archivo de manifiesto:

    kubectl apply -f priorityclasses.yaml
    

Aprovisionar capacidad de computación adicional

En las siguientes secciones se muestra un ejemplo en el que se aprovisiona capacidad para un solo evento o de forma constante a lo largo del tiempo.

Usar un Deployment para aprovisionar capacidad de forma coherente

  1. Guarda el siguiente archivo de manifiesto 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 manifiesto incluye los siguientes campos:

    • spec.replicas: cambia este valor para que se ajuste a tus necesidades.
    • spec.resources.requests: cambia las solicitudes de CPU y memoria para que se ajusten a tus requisitos. Consulta las directrices de la sección Elegir el tamaño de la capacidad para decidir los valores de solicitud adecuados.
    • spec.containers.command y spec.containers.args: indica a los pods que permanezcan activos hasta que GKE los expulse.
  2. Aplica el archivo de manifiesto:

    kubectl apply -f capacity-res-deployment.yaml
    
  3. Obtén el estado del pod:

    kubectl get pods -l app=reservation
    

    Espera hasta que todas las réplicas tengan el estado Running.

Usar un trabajo para aprovisionar la capacidad de un solo evento

  1. Guarda el siguiente archivo de manifiesto 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 manifiesto incluye los siguientes campos:

    • spec.parallelism: cambia el número de trabajos que quieres ejecutar en paralelo para reservar capacidad.
    • spec.backoffLimit: 0: impide que el controlador de trabajos vuelva a crear los trabajos desalojados.
    • template.spec.resources.requests: cambia las solicitudes de CPU y memoria para que se ajusten a tus requisitos. Consulta las consideraciones para decidir qué valores son los más adecuados.
    • template.spec.containers.command y template.spec.containers.args: Indica a los trabajos que permanezcan activos durante el periodo de tiempo, en segundos, en el que necesites la capacidad adicional.
  2. Aplica el archivo de manifiesto:

    kubectl apply -f capacity-res-job.yaml
    
  3. Obtener el estado de la tarea:

    kubectl get jobs
    

    Espera hasta que todas las tareas tengan el estado Running.

Probar el aprovisionamiento y la expulsión de capacidad

Para verificar que el aprovisionamiento de capacidad funciona correctamente, haga lo siguiente:

  1. En tu terminal, consulta el estado de las cargas de trabajo de aprovisionamiento de capacidad:

    1. Para los despliegues, ejecuta el siguiente comando:

      kubectl get pods --label=app=reservation -w
      
    2. En el caso de los trabajos, ejecuta el siguiente comando:

      kubectl get Jobs -w
      
  2. Abre una nueva ventana de terminal y haz lo siguiente:

    1. Guarda el siguiente archivo de manifiesto 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. Aplica el archivo de manifiesto:

      kubectl apply -f test-deployment.yaml
      
  3. En la ventana de terminal original, observa que GKE finaliza algunas de las cargas de trabajo de aprovisionamiento de capacidad para programar tus nuevas réplicas, como en el siguiente ejemplo:

    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
    

    En este resultado se muestra que tu nueva implementación ha tardado cinco segundos en cambiar de Pendiente a En ejecución.

Consideraciones sobre el aprovisionamiento de capacidad

En las siguientes secciones se ofrecen recomendaciones que pueden ayudarle a mejorar la fiabilidad de la capacidad que aprovisiona.

Aprovisionamiento de capacidad coherente

  • Evalúa cuántas réplicas de Pod de marcador de posición necesitas y el tamaño de las solicitudes de cada réplica. Las réplicas de baja prioridad deben solicitar al menos la misma capacidad que tu carga de trabajo de producción más grande para que esas cargas de trabajo puedan ajustarse a la capacidad reservada por tu carga de trabajo de baja prioridad.
  • Si gestionas un gran número de cargas de trabajo de producción a gran escala, te recomendamos que definas las solicitudes de recursos de tus pods de marcador de posición con valores que proporcionen capacidad suficiente para ejecutar varias cargas de trabajo de producción en lugar de solo una.

Aprovisionamiento de capacidad de un solo uso

  • Define el periodo durante el que quieres que se conserven los trabajos de marcador de posición, que debe ser el tiempo durante el que necesites capacidad adicional. Por ejemplo, si quieres tener capacidad adicional durante el día del lanzamiento de un juego (24 horas), define la duración en 86.400 segundos. De esta forma, la capacidad aprovisionada no durará más de lo necesario.
  • Define una ventana de mantenimiento para el mismo periodo que la reserva de capacidad. De esta forma, se evita que se expulsen tus trabajos de baja prioridad durante una actualización de nodos. También es recomendable definir una ventana de mantenimiento cuando preveas que tu carga de trabajo tendrá una demanda alta.
  • Si gestionas un gran número de cargas de trabajo de producción a gran escala, te recomendamos que definas las solicitudes de recursos de tus trabajos de marcador de posición con valores que proporcionen capacidad suficiente para ejecutar varias cargas de trabajo de producción en lugar de solo una.

La capacidad solo se aprovisiona para un único evento de escalado. Si aumentas la capacidad y la usas, y luego la reduces, esa capacidad ya no estará disponible para otro evento de aumento. Si prevés que se produzcan varios eventos de escalado vertical y horizontal, utiliza el método de reserva de capacidad coherente y ajusta el tamaño de la reserva según sea necesario. Por ejemplo, aumentar las solicitudes de Pod antes de un evento y reducirlas o eliminarlas después.

Elige una prioridad

Puedes definir varias PriorityClasses en tu clúster para usarlas con cargas de trabajo que tengan diferentes requisitos. Por ejemplo, puedes crear un PriorityClass con una prioridad de -10 para el aprovisionamiento de capacidad de un solo uso y un PriorityClass con una prioridad de -9 para el aprovisionamiento de capacidad constante. De esta forma, podrías aprovisionar una capacidad constante con PriorityClass con prioridad -9 y, cuando quieras más capacidad para un evento especial, podrías desplegar nuevos trabajos que usen PriorityClass con prioridad -10. GKE expulsa primero las cargas de trabajo de menor prioridad.

También puedes usar otras PriorityClasses para ejecutar cargas de trabajo de no producción de baja prioridad que realicen tareas reales, como cargas de trabajo por lotes tolerantes a fallos, con una prioridad inferior a la de tus cargas de trabajo de producción, pero superior a la de tus pods de marcador de posición. Por ejemplo, -5.

Elegir el tamaño de la capacidad

Define el número de réplicas y las solicitudes de recursos de tu carga de trabajo de marcador de posición para que sean mayores o iguales que la capacidad que puedan necesitar tus cargas de trabajo de producción al aumentar la escala.

La capacidad total aprovisionada se basa en el número de pods de marcador de posición que implementes y en las solicitudes de recursos de cada réplica. Si el escalado vertical requiere más capacidad de la que GKE ha aprovisionado para tus pods de marcador de posición, algunas de tus cargas de trabajo de producción permanecerán en Pending hasta que GKE pueda aprovisionar más capacidad.

Siguientes pasos