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 se inicie el nodo antes de colocar Pods pendientes en el nodo nuevo. Luego, 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 tus Pods se inicien más rápido durante los eventos de escalamiento. 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 baja prioridad que tienen diferentes niveles de prioridad, GKE expulsa primero los Pods de menor prioridad.

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 implementación se asegura de que GKE aprovisione más capacidad para volver a crear los Pods de baja prioridad expulsados. 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 pase 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 para un período determinado.

Precios

En GKE Autopilot, se te cobra por las solicitudes de recursos de tus 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 Google Kubernetes Engine.
  • Habilitar la API de Google Kubernetes Engine
  • 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 para asegurarte de elegir los 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: Es 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 Pods que usen una PriorityClass más baja.
  • PriorityClass baja: Es una PriorityClass no predeterminada establecida en la prioridad más baja posible en GKE. Los Pods con esta PriorityClass se pueden expulsar para ejecutar pods con PriorityClasses más altas.
  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 de los Pods que usan PriorityClass. La PriorityClass default usa 0. La PriorityClass low-priority usa -10. En Autopilot, puedes establecer este valor en cualquier valor inferior a la prioridad de 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 necesitas ayuda para decidir los valores adecuados para la prioridad, consulta Elige una prioridad.

    • globalDefault: Especifica si GKE asigna o no la PriorityClass a los Pods que no establecen una PriorityClass de forma explícita 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 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 capacidad.
    • spec.backoffLimit: 0: Evita que el controlador de trabajos vuelva a crear trabajos expulsados.
    • template.spec.resources.requests: Cambia las solicitudes de CPU y memoria para cumplir con tus requisitos. Usa la orientación que se proporciona en Consideraciones para ayudarte a 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 según lo esperado, haz lo siguiente:

  1. En la 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 terminal original, ten en cuenta que GKE finaliza algunas de las cargas de trabajo de aprovisionamiento de capacidad para programar tus réplicas nuevas, 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 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, de modo que esas cargas de trabajo puedan adaptarse a 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 un solo uso

  • 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 que la necesitas.
  • Establece un período de mantenimiento para el mismo período durante el que reservas la capacidad. Esto evita que se desalojen tus trabajos de prioridad baja durante una actualización de nodo. Establecer un período de mantenimiento también es una práctica recomendada cuando anticipas 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 la escala verticalmente, esa capacidad ya no estará disponible para otro evento de aumento de escala. 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 requisitos diferentes. 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 primero las cargas de trabajo de prioridad más baja.

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?