Aprovisiona capacidad de procesamiento adicional para un escalamiento rápido de Pod


En esta página, se muestra cómo reservar capacidad de procesamiento adicional en tus clústeres de Google Kubernetes Engine (GKE) para que tus cargas de trabajo puedan escalar verticalmente con rapidez durante eventos de tráfico alto sin esperar a que se inicien los nodos nuevos. Puedes usar estas instrucciones para reservar la sobrecarga de procesamiento de manera constante o con anticipación de los eventos específicos.

Por qué es útil el aprovisionamiento de capacidad libre

Los clústeres de GKE Autopilot y los clústeres de GKE Standard con aprovisionamiento automático de nodos crean nodos nuevos cuando no hay nodos existentes con la capacidad de ejecutar pods nuevos. Cada nodo nuevo tarda entre 80 y 120 segundos en iniciarse. GKE espera hasta que el nodo se inicie antes de colocar los Pods pendientes en el nodo nuevo, después de lo cual los Pods pueden iniciarse. En los clústeres Standard, también puedes crear un grupo de nodos nuevo de forma manual que tenga la capacidad adicional que necesitas para ejecutar Pods nuevos. Esta página se aplica a los clústeres que usan un mecanismo de ajuste de escala automático de nodos, como Autopilot o el aprovisionamiento automático de nodos.

En algunos casos, es posible que desees que los Pods se inicien más rápido durante los eventos de escalamiento vertical. Por ejemplo, si lanzas una expansión nueva de tu popular juego multijugador de servicios en vivo, los tiempos de inicio más rápidos para los Pods del servidor de juegos pueden reducir los tiempos de espera para los jugadores que acceden el día del lanzamiento. Otro ejemplo es que, si ejecutas una plataforma de comercio electrónico y planeas realizar una oferta relámpago por un tiempo limitado, esperas aumentos repentinos de tráfico durante el período de la oferta.

El aprovisionamiento de capacidad libre es compatible con los aumentos de actividad de Pods, que permiten que los Pods usen de forma temporal los recursos que solicitaron otros Pods en el nodo, si esa capacidad está disponible y no la usan otros Pods. Para usar aumentos de actividad, establece límites de recursos más altos que las solicitudes de recursos o no establezcas límites de recursos. Para obtener más información, consulta Configura el aumento de actividad de Pods en GKE.

Cómo funciona el aprovisionamiento de capacidad libre en GKE

Para aprovisionar capacidad libre, puedes usar PriorityClasses de Kubernetes y Pods de marcadores de posición. Una PriorityClass te permite indicarle a GKE que algunas cargas de trabajo tienen una prioridad más baja que otras. Puedes implementar Pods de marcadores de posición que usan una PriorityClass de baja prioridad y solicitar la capacidad de procesamiento que necesitas reservar. GKE agrega capacidad al clúster mediante la creación de nodos nuevos para alojar los Pods de marcadores de posición.

Cuando las cargas de trabajo de producción escalan verticalmente, GKE expulsa los Pods de marcadores de posición de menor prioridad y programa las réplicas nuevas de los Pods de producción (que usan una PriorityClass de mayor prioridad). Si tienes varios Pods de prioridad baja con diferentes niveles de prioridad, GKE expulsa los Pods de menor prioridad primero.

Métodos de aprovisionamiento de capacidad

Según tu caso de uso, puedes aprovisionar capacidad adicional en tus clústeres de GKE de una de las siguientes maneras:

  • Aprovisionamiento de capacidad constante: Usa un Deployment para crear una cantidad específica de Pods de marcadores de posición de baja prioridad que se ejecuten de forma constante en el clúster. Cuando GKE expulsa estos Pods para ejecutar tus cargas de trabajo de producción, el controlador de Deployment garantiza que GKE aprovisione más capacidad para volver a crear los Pods expulsados de baja prioridad. Este método proporciona una sobrecarga de capacidad constante en varios eventos de escalamiento vertical y horizontal hasta que borres el Deployment.
  • Aprovisionamiento de capacidad de uso único: usa un trabajo para ejecutar una cantidad específica de Pods de marcadores de posición paralelos de prioridad baja durante un período específico. Cuando ese tiempo haya pasado o cuando GKE expulsa todas las réplicas de trabajo, la capacidad reservada deja de estar disponible. Este método proporciona una cantidad específica de capacidad disponible durante un período específico.

Precios

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

En GKE Standard, se te cobra por las VM de Compute Engine subyacentes que aprovisiona GKE, sin importar si los Pods usan esa capacidad. Para obtener más información, consulta Precios de Standard.

Antes de comenzar

Antes de comenzar, asegúrate de haber realizado las siguientes tareas:

  • Habilita la API de Kubernetes Engine de Google.
  • Habilitar la API de Kubernetes Engine de Google
  • Si deseas usar Google Cloud CLI para esta tarea, instala y, luego, inicializa gcloud CLI. Si ya instalaste gcloud CLI, ejecuta gcloud components update para obtener la versión más reciente.
  • Asegúrate de tener un clúster de GKE Autopilot o un clúster de GKE Standard con aprovisionamiento automático de nodos habilitado.
  • Lee las Consideraciones para el aprovisionamiento de capacidad a fin de asegurarte de elegir valores adecuados en tus solicitudes de capacidad.

Crea una PriorityClass

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

  • PriorityClass predeterminada: Una PriorityClass predeterminada global que se asigna a cualquier Pod que no establezca de forma explícita una PriorityClass diferente en la especificación del Pod. Los Pods con esta PriorityClass predeterminada pueden expulsar los Pods que usan una PriorityClass más baja.
  • PriorityClass baja: una PriorityClass no predeterminada configurada con la prioridad más baja posible en GKE. Los Pods con esta PriorityClass se pueden expulsar para ejecutar Pods con mayores PriorityClasses.
  1. Guarda el siguiente 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 los Pods de menor prioridad. La PriorityClass low-priority usa Never y la PriorityClass default usa PreemptLowerPriority.
    • value: Es la prioridad para los Pods que usan PriorityClass. La PriorityClass default usa 0. La PriorityClass low-priority usa -1. En Autopilot, puedes establecer esto en cualquier valor que sea menor que la prioridad PriorityClass default.

      En Standard, si estableces este valor en menos de -10, los Pods que usan esa PriorityClass no activarán la creación de nodos nuevos y permanecerán en Pendiente.

      Si deseas obtener ayuda para decidir los valores de prioridad adecuados, consulta Elige una prioridad.

    • globalDefault: Especifica si GKE asigna la PriorityClass a los pods que no establecen de forma explícita una PriorityClass en la especificación del pod. La PriorityClass low-priority usa false, y la PriorityClass default usa true.

  2. Aplica el manifiesto

    kubectl apply -f priorityclasses.yaml
    

Aprovisiona capacidad de procesamiento adicional

En las siguientes secciones, se muestra un ejemplo en el que aprovisionas capacidad para un solo evento o de manera constante en el tiempo.

Usa un Deployment para un aprovisionamiento de capacidad constante

  1. Guarda el siguiente 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 cumplir con tus requisitos.
    • spec.resources.requests: Cambia las solicitudes de CPU y memoria para cumplir con tus requisitos. Usa la guía en Elige el tamaño de la capacidad para ayudarte a decidir los valores de solicitud adecuados.
    • spec.containers.command y spec.containers.args: Indican a los Pods que permanezcan activos hasta que GKE los expulse.
  2. Aplica el 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.

Usa un trabajo para el aprovisionamiento de la capacidad de un solo evento

  1. Guarda el siguiente 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 a la cantidad de trabajos que deseas ejecutar en paralelo para reservar la capacidad.
    • spec.backoffLimit: 0: Evita que el controlador de trabajo vuelva a crear trabajos expulsados.
    • template.spec.resources.requests: Cambia las solicitudes de CPU y memoria para cumplir con tus requisitos. Usa la guía de Consideraciones para decidir los valores adecuados.
    • template.spec.containers.command y template.spec.containers.args: Indican a los trabajos que permanezcan activos durante el período, en segundos, durante el cual necesitas la capacidad adicional.
  2. Aplica el manifiesto

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

    kubectl get jobs
    

    Espera hasta que todos los trabajos tengan el estado Running.

Prueba la expulsión y el aprovisionamiento de la capacidad

Para verificar que el aprovisionamiento de capacidad funcione como se espera, haz lo siguiente:

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

    1. Para los Deployments, ejecuta el siguiente comando:

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

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

    1. Guarda el siguiente 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 manifiesto

      kubectl apply -f test-deployment.yaml
      
  3. En la ventana de la terminal original, ten en cuenta que GKE finaliza algunas de las cargas de trabajo de aprovisionamiento de capacidad para programar las réplicas nuevas, de manera similar al 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
    

    Este resultado muestra que tu nuevo Deployment tardó cinco segundos en cambiar de Pendiente a En ejecución.

Consideraciones para el aprovisionamiento de la capacidad

Aprovisionamiento de capacidad constante

  • Evalúa cuántas réplicas de Pod de marcadores de posición necesitas y el tamaño de las solicitudes en cada réplica. Las réplicas de prioridad baja 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 caber en la capacidad reservada por tu carga de trabajo de prioridad baja.
  • Si operas una gran cantidad de cargas de trabajo de producción a gran escala, considera configurar las solicitudes de recursos de tus Pods de marcadores de posición en valores que aprovisionen suficiente capacidad para ejecutar varias cargas de trabajo de producción en lugar de solo una.

Aprovisionamiento de capacidad de uso único

  • Configura la cantidad de tiempo para que los trabajos de marcadores de posición se conserven en el tiempo durante el cual necesitas capacidad adicional. Por ejemplo, si deseas la capacidad adicional para un día de lanzamiento de juegos de 24 horas, establece el tiempo en 86,400 segundos. Esto garantiza que la capacidad aprovisionada no dure más de lo necesario.
  • Configura un período de mantenimiento durante el mismo período que reservas la capacidad. Esto evita que los trabajos de baja prioridad se expulsen durante una actualización de nodo. Configurar un período de mantenimiento también es una buena práctica cuando prevés una alta demanda para tu carga de trabajo.
  • Si operas una gran cantidad de cargas de trabajo de producción a gran escala, considera configurar las solicitudes de recursos de tus trabajos de marcadores de posición en valores que aprovisionen suficiente capacidad para ejecutar varias cargas de trabajo de producción en lugar de solo una.

La capacidad se aprovisiona solo para un único evento de escalamiento. Si escalas verticalmente y usas la capacidad y, luego, reduces el escalamiento, esa capacidad ya no estará disponible para otro evento de escalamiento vertical. Si prevés varios eventos de escalamiento vertical y horizontal, usa el método de reserva de capacidad constante y ajusta el tamaño de la reserva según sea necesario. Por ejemplo, si haces que las solicitudes de pods sean mayores antes de un evento y menores o nulas después.

Elige una prioridad

Establece la prioridad en tus PriorityClasses en menos de 0.

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

También puedes usar otras PriorityClasses para ejecutar cargas de trabajo de baja prioridad que no sean de producción y que realicen tareas reales, como cargas de trabajo por lotes tolerantes a errores, con una prioridad menor que tus cargas de trabajo de producción, pero mayor que tus Pods de marcadores de posición. Por ejemplo, -5.

Elige el tamaño de la capacidad

Establece recuentos de réplicas y solicitudes de recursos de la carga de trabajo de marcadores de posición para que sea superior o igual a la capacidad que podrían necesitar tus cargas de trabajo de producción cuando escalen verticalmente.

La capacidad total aprovisionada se basa en la cantidad de Pods de marcadores de posición que implementas y las solicitudes de recursos de cada réplica. Si el escalamiento vertical requiere más capacidad que GKE aprovisionado para los Pods de marcadores de posición, algunas de las cargas de trabajo de producción permanecerán en Pending hasta que GKE pueda aprovisionar más capacidad.

¿Qué sigue?