Los búferes de capacidad mejoran la capacidad de respuesta y la confiabilidad de las cargas de trabajo críticas mediante la administración proactiva de la capacidad de clúster de repuesto y los estados suspendidos de la capacidad aprovisionada previamente y configurada previamente con una CustomResourceDefinition (CRD) de CapacityBuffer de Kubernetes. El uso de búferes de capacidad te permite definir de forma explícita una cantidad específica de capacidad de nodo sin usar dentro de tu clúster. Esta capacidad reservada ayuda a reducir el tiempo de programación de Pods.
Cuando una carga de trabajo de alta prioridad necesita escalar verticalmente con rapidez, la nueva carga de trabajo puede usar la capacidad vacía de inmediato sin esperar el aprovisionamiento de nodos. Este enfoque minimiza la latencia y evita la contención de recursos durante los aumentos repentinos de demanda.
En esta página, se proporcionan métodos para configurar búferes de capacidad: un búfer de réplicas fijas, un búfer de límites de recursos y un búfer basado en porcentajes.
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 el comando
gcloud components updatepara obtener la versión más reciente. Es posible que las versiones anteriores de gcloud CLI no admitan la ejecución de los comandos de este documento.
- Crea un clúster de GKE en la versión 1.35.2-gke.1842000 para búferes activos y la versión 1.36.0-gke.2253000 o posterior para búferes en espera, o bien ten acceso a uno.
- Habilita el aprovisionamiento automático de nodos en tus clústeres estándar. En los clústeres de Autopilot, el aprovisionamiento automático de nodos ya está habilitado. El aprovisionamiento automático de nodos es opcional, pero se recomienda para los búferes activos y es obligatorio para los búferes en espera.
Crea objetos de Kubernetes de requisitos previos
Para configurar un CapacityBuffer, necesitas un espacio de nombres que contenga todos los objetos requeridos (el CapacityBuffer en sí y recursos adicionales, como un PodTemplate o una carga de trabajo). El PodTemplate y el CapacityBuffer deben estar en el mismo espacio de nombres. Puedes crear un espacio de nombres o usar uno existente, incluido el espacio de nombres default.
Según el tipo de CapacityBuffer que configures, también necesitas uno de los siguientes elementos:
- PodTemplate: Define los requisitos de recursos para una sola unidad de capacidad de búfer. La configuración especificada en el objeto CapacityBuffer hace referencia a la plantilla de Pod.
Carga de trabajo: Una carga de trabajo existente a la que haces referencia en el objeto CapacityBuffer. En esta guía, se usa un objeto Deployment como ejemplo de carga de trabajo, pero los búferes de capacidad admiten cualquiera de los siguientes tipos de recursos:
- Deployment
- ReplicaSet
- StatefulSet
- ReplicationController
- Trabajo
CustomResourceDefinitions (CRD) que implementan el subrecurso
scale
En esta sección, se proporcionan ejemplos de estos objetos. Si ya tienes una carga de trabajo que deseas configurar con un búfer de capacidad, continúa con Aplica un búfer de capacidad.
Para crear una carga de trabajo de Kubernetes de ejemplo, completa los siguientes pasos:
Guarda el siguiente manifiesto como
namespace.yaml:apiVersion: v1 kind: Namespace metadata: name: capacity-buffer-example labels: name: capacity-buffer-exampleEste manifiesto crea un espacio de nombres llamado
capacity-buffer-example.Opcional: Para usar búferes de capacidad con una ComputeClass personalizada, guarda el siguiente manifiesto como
custom-compute-class.yaml:apiVersion: cloud.google.com/v1 kind: ComputeClass metadata: name: ccc-example namespace: capacity-buffer-example spec: # Buffers are also created according to these priorities priorities: - machineFamily: n4 - machineFamily: n4d - machineFamily: c4 - machineFamily: c4d nodePoolAutoCreation: enabled: trueEste manifiesto crea una
ComputeClasspersonalizada que define y controla las prioridades de procesamiento para los nodos que aprovisiona GKE. Para obtener más información, consulta ComputeClasses personalizadas.Guarda el siguiente manifiesto como
buffer-pod-template.yaml:apiVersion: v1 kind: PodTemplate metadata: name: buffer-unit-template namespace: capacity-buffer-example # the namespace must be the same namespace as the CapacityBuffer template: spec: terminationGracePeriodSeconds: 0 containers: - name: buffer-container image: registry.k8s.io/pause:3.9 resources: requests: cpu: "1" memory: "1Gi" limits: cpu: "1" memory: "1Gi" # Optional: Using buffers with a custom ComputeClass / # controls the properties of the provisioned nodes. nodeSelector: cloud.google.com/compute-class: ccc-exampleEste manifiesto crea un
PodTemplateque define los requisitos de recursos para una sola unidad de capacidad de búfer (1CPU y1Gide memoria). Esta configuración especifica el tamaño de las unidades de capacidad que GKE aprovisiona para el búfer. Por ejemplo, con este PodTemplate, GKE no considerará los nodos con menos de 1 CPU y 1Gi de recursos disponibles como parte del búfer, si el clúster escala verticalmente.Guarda el siguiente manifiesto como
sample-workload-deployment.yaml:apiVersion: apps/v1 kind: Deployment metadata: name: critical-workload-ref namespace: capacity-buffer-example # the namespace must be the same namespace as the CapacityBuffer spec: replicas: 10 selector: matchLabels: app: critical-workload template: metadata: labels: app: critical-workload spec: containers: - name: busybox image: busybox command: ["sleep", "3600"] resources: requests: cpu: 100m # Optional: Using buffers with a custom ComputeClass / # controls the properties of the provisioned nodes. nodeSelector: cloud.google.com/compute-class: ccc-exampleEste manifiesto crea una Deployment de muestra con 10 réplicas, que es el objeto de referencia para el ejemplo de búfer basado en porcentajes de la siguiente sección.
Aplica los manifiestos a tu clúster.
kubectl apply -f namespace.yaml -f custom-compute-class.yaml -f buffer-pod-template.yaml -f sample-workload-deployment.yamlVerifica que GKE haya creado los objetos:
kubectl get podtemplate -n capacity-buffer-example kubectl get deployment critical-workload-ref -n capacity-buffer-exampleEl resultado es similar a este:
NAME AGE buffer-unit-template 1m NAME READY UP-TO-DATE AVAILABLE AGE critical-workload-ref 10/10 10 10 1m
Aplica un búfer de capacidad
En esta sección, se proporcionan ejemplos de los diferentes tipos de búferes de capacidad que puedes aplicar a tus cargas de trabajo.
Configura un búfer de réplicas fijas
La configuración de un CapacityBuffer con réplicas fijas especifica la cantidad exacta de unidades de búfer que deseas según un PodTemplate.
Para crear un búfer con réplicas fijas, completa los siguientes pasos:
Guarda el siguiente manifiesto como
cb-fixed-replicas.yaml:apiVersion: autoscaling.x-k8s.io/v1beta1 kind: CapacityBuffer metadata: name: fixed-replica-buffer namespace: NAMESPACE spec: podTemplateRef: name: POD_TEMPLATE replicas: 3 provisioningStrategy: "STRATEGY"Reemplaza lo siguiente:
NAMESPACE: Es el nombre de tu espacio de nombres, por ejemplo,capacity-buffer-example.POD_TEMPLATE: Es el PodTemplate que define tus requisitos de recursos, por ejemplo,buffer-unit-template.STRATEGY: Es la estrategia de aprovisionamiento, ya sea"buffer.x-k8s.io/active-capacity"(predeterminada) o"buffer.gke.io/standby-capacity".
Este manifiesto crea un recurso CapacityBuffer que hace referencia a un PodTemplate para solicitar una cantidad específica de unidades de búfer.
Aplica el manifiesto
kubectl apply -f cb-fixed-replicas.yamlConfirma que GKE aplicó el búfer de capacidad:
kubectl get capacitybuffer fixed-replica-buffer -n NAMESPACEEl campo
replicasen el estado debe mostrar3, lo que refleja la cantidad de réplicas que definiste en el manifiesto. El campoSTATUSdebe mostrarReadyForProvisioning.
Configura un búfer de límites de recursos
Puedes usar el campo limits para definir una cantidad máxima de recursos que debe consumir el búfer, calculada en función del tamaño de tu PodTemplate.
Para crear un búfer de límites de recursos, completa los siguientes pasos:
Guarda el siguiente manifiesto como
cb-resource-limits.yaml:apiVersion: autoscaling.x-k8s.io/v1beta1 kind: CapacityBuffer metadata: name: resource-limit-buffer namespace: NAMESPACE spec: podTemplateRef: name: POD_TEMPLATE limits: cpu: "5" memory: "5Gi" provisioningStrategy: "STRATEGY"Reemplaza lo siguiente:
NAMESPACE: Es el nombre de tu espacio de nombres, por ejemplo,capacity-buffer-example.POD_TEMPLATE: Es el PodTemplate que define tus requisitos de recursos, por ejemplo,buffer-unit-template.STRATEGY: Es la estrategia de aprovisionamiento, ya sea"buffer.x-k8s.io/active-capacity"(predeterminada) o"buffer.gke.io/standby-capacity".
Este manifiesto crea un recurso CapacityBuffer con un límite total de 5 CPU y 5 GiB de memoria. Si usas el ejemplo de PodTemplate del paso anterior, defines cada unidad como
1CPU y1Gide memoria, lo que debería generar 5 unidades de búfer.Aplica el manifiesto
kubectl apply -f cb-resource-limits.yamlConfirma que GKE aplicó el búfer de capacidad:
kubectl get capacitybuffer resource-limit-buffer -n NAMESPACEVerifica el estado de CapacityBuffer. El campo
replicasdebe mostrar un valor derivado de los límites que definiste. Si usas el ejemplo de PodTemplate de la sección anterior, deberías ver5unidades de búfer, ya que esta es la cantidad máxima de unidades que caben dentro de los límites definidos.
Configura un búfer basado en porcentajes
La configuración de un búfer basado en porcentajes cambia el tamaño del búfer de forma dinámica según un porcentaje de una carga de trabajo escalable existente. Los búferes de capacidad basados en porcentajes
solo se admiten para objetos escalables de Kubernetes que implementan el
subrecurso de escala, como implementaciones, StatefulSets, ReplicaSets o trabajos. No puedes definir un búfer basado en porcentajes para las plantillas de Pod porque no tienen un campo replicas.
Por lo general, recomendamos comenzar con réplicas fijas o estrategias de límite de recursos, en lugar de búferes basados en porcentajes. Los búferes basados en porcentajes son menos sensibles a los aumentos repentinos si la carga de trabajo se ajusta a números bajos o cero, ya que el margen de seguridad se ajusta en proporción a los Pods activos. Son útiles principalmente para implementaciones grandes que nunca se ajustan a cantidades de réplicas muy bajas.
Para crear un búfer basado en porcentajes, completa los siguientes pasos:
Guarda el siguiente manifiesto como
cb-percentage-based.yaml:apiVersion: autoscaling.x-k8s.io/v1beta1 kind: CapacityBuffer metadata: name: percentage-buffer namespace: NAMESPACE spec: scalableRef: apiGroup: apps kind: Deployment name: SCALABLE_RESOURCE_NAME percentage: 20 provisioningStrategy: "STRATEGY"Reemplaza lo siguiente:
NAMESPACE: Es el nombre de tu espacio de nombres.SCALABLE_RESOURCE_NAME: Es el nombre de tu recurso escalable, por ejemplo,critical-workload-ref.STRATEGY: Es la estrategia de aprovisionamiento, ya sea"buffer.x-k8s.io/active-capacity"(predeterminada) o"buffer.gke.io/standby-capacity".
Este manifiesto crea un recurso CapacityBuffer que solicita un tamaño de búfer equivalente al 20% de las réplicas del recurso al que se hace referencia. Si usas el ejemplo de Deployment de la sección anterior, el valor de la réplica se establece en
10.Aplica el manifiesto
kubectl apply -f cb-percentage-based.yamlConfirma que GKE aplicó el búfer de capacidad:
kubectl get capacitybuffer percentage-buffer -n NAMESPACEVerifica el estado de CapacityBuffer. El campo
replicasdebe mostrar un valor del cálculo del porcentaje. Si usas el ejemplo de Deployment de la sección anterior, deberías ver2unidades de búfer, que es el 20% de las 10 réplicas definidas en la Deployment.Para probar el ajuste de escala dinámico, escala manualmente la Deployment a 20 réplicas:
kubectl scale deployment critical-workload-ref -n NAMESPACE --replicas=20El controlador CapacityBuffer reacciona y ajusta automáticamente el búfer a 4 réplicas.
Personaliza el comportamiento del búfer en espera
Puedes usar anotaciones para personalizar cómo se inician y actualizan los búferes en espera.
Agrega estas anotaciones al campo metadata.annotations de tu recurso CapacityBuffer:
buffer.gke.io/standby-capacity-init-time: Es la cantidad de tiempo que un nodo permanece activo después de la creación antes de que se suspenda. El formato es una cadena de duración (por ejemplo,5mo1h). El valor predeterminado es5m.buffer.gke.io/standby-capacity-refresh-frequency: Es la frecuencia con la que se actualizan los nodos suspendidos. El valor predeterminado es1d.
En el siguiente ejemplo, se muestra un manifiesto con estos campos opcionales para personalizar el comportamiento de los búferes en espera:
apiVersion: autoscaling.x-k8s.io/v1beta1
kind: CapacityBuffer
metadata:
name: customized-standby-buffer
namespace: my-namespace
annotations:
buffer.gke.io/standby-capacity-init-time: "15m"
buffer.gke.io/standby-capacity-refresh-frequency: "12h"
spec:
podTemplateRef:
name: buffer-unit-template
replicas: 3
provisioningStrategy: "buffer.gke.io/standby-capacity"
Precarga imágenes en búferes en espera
Para acelerar los tiempos de inicio de la carga de trabajo cuando se reanuda un nodo en espera, puedes precargar imágenes de contenedor con un DaemonSet. El DaemonSet se ejecuta durante el período de inicio antes de que se suspenda el nodo.
Para precargar imágenes con el DaemonSet, completa los siguientes pasos:
Guarda el siguiente manifiesto como
image-puller-daemonset.yaml:apiVersion: apps/v1 kind: DaemonSet metadata: name: image-prefetch-daemonset namespace: NAMESPACE spec: selector: matchLabels: name: image-prefetch template: metadata: labels: name: image-prefetch spec: tolerations: - key: "buffer.gke.io/standby-node-suspended" operator: "Exists" initContainers: - name: image-puller image: IMAGE_NAME command: ["sh", "-c", "true"] containers: - name: pause image: registry.k8s.io/pause:3.9Reemplaza lo siguiente:
NAMESPACE: Es el espacio de nombres del DaemonSet, por ejemplo,capacity-buffer-example.IMAGE_NAME: Es el nombre de la imagen que se precargará, por ejemplo,your-app-image:latest.
Aplica el manifiesto de DaemonSet a tu clúster:
kubectl apply -f image-puller-daemonset.yamlVerifica que se haya creado el DaemonSet:
kubectl get daemonset image-prefetch-daemonset -n NAMESPACEVerifica que se haya creado tu búfer de capacidad y que esté listo para el aprovisionamiento:
kubectl get capacitybuffer CAPACITY_BUFFER_NAME -n NAMESPACEVerifica el estado. El campo
STATUSdebe mostrarReadyForProvisioning.
Supervisa el estado y el rendimiento del búfer de capacidad
Puedes supervisar el estado y el estado de tus búferes de capacidad con los comandos kubectl y las métricas de Cloud Monitoring.
Verifica el estado del recurso CapacityBuffer
Para verificar el estado de tus búferes de capacidad y verificar que estén listos para recibir cargas de trabajo, completa los siguientes pasos:
Obtén el estado de todos los búferes de capacidad en el clúster:
kubectl get capacitybuffer -AInspecciona el estado detallado, las condiciones y los registros de eventos de un búfer específico:
kubectl describe capacitybuffer CAPACITY_BUFFER_NAME -n NAMESPACE
Identifica los nodos de búfer en espera suspendidos
Las VMs de búfer en espera se aprovisionan previamente, pero se mantienen en un estado suspendido para ayudar a reducir los costos. Puedes reconocer estos nodos suspendidos porque tienen una condición personalizada. Para auditar las instancias de nodos suspendidos, ejecuta el siguiente comando:
kubectl get nodes -o custom-columns='NAME:.metadata.name,SUSPENDED:.status.conditions[?(@.type=="Suspended")].status'
Un estado de True indica que una VM en espera está suspendida. Un estado de False o
<none> indica un nodo activo en ejecución.
Supervisa el rendimiento con Cloud Monitoring
Para ayudar a supervisar el rendimiento de los búferes de capacidad, supervisa los siguientes recursos en Cloud Monitoring:
- Latencia de reacción (
cluster_autoscaler/reaction_time_milliseconds): Realiza un seguimiento de la duración del escalador automático de clústeres para tomar una decisión de ajuste de escala en función de la demanda pendiente de tu CapacityBuffer. - Registros del escalador automático de clústeres: Busca entradas de registro como
"Capacity pod processor injecting ..."para observar los eventos de reemplazo de Pods de búfer activos.
Quita los búferes de capacidad
Si ya no necesitas un búfer de capacidad para tus cargas de trabajo, borra el objeto CapacityBuffer. Esto quita los Pods de marcador de posición y permite que el escalador automático de clústeres reduzca la escala verticalmente de los nodos.
kubectl delete capacitybuffer CAPACITY_BUFFER_NAME -n NAMESPACE
Reemplaza CAPACITY_BUFFER_NAME por el nombre del CapacityBuffer que deseas borrar.
Soluciona problemas
En la siguiente sección, se proporciona información para resolver problemas comunes con los búferes de capacidad.
El búfer de capacidad no está listo debido al modelo de facturación
Si creas un CapacityBuffer para una carga de trabajo que usa el modelo de facturación basado en Pods (pago por Pod), el búfer de capacidad no estará listo para el aprovisionamiento.
Para identificar este problema, verifica el estado de CapacityBuffer:
kubectl describe capacitybuffer BUFFER_NAME -n NAMESPACE
Busca una condición del tipo ReadyForProvisioning con un estado de False.
Para resolver este problema, asegúrate de que tu CapacityBuffer haga referencia a una carga de trabajo o PodTemplate que sea compatible con la facturación basada en nodos.
Errores de permisos para recursos escalables personalizados
Si configuras un CapacityBuffer para que funcione con objetos escalables personalizados (con el campo scalableRef), es posible que el escalador automático de clústeres no pueda escalar el búfer si no tiene los permisos necesarios.
Para resolver este problema, otorga de forma manual los permisos necesarios mediante la
creación de un ClusterRole y un ClusterRoleBinding, como en el siguiente
ejemplo:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: custom-scale-getter
rules:
- apiGroups: ["api.example.com"]
resources: ["customreplicatedresources/scale"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: ca-custom-scale-getter
subjects:
- kind: User
name: "system:cluster-autoscaler"
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: custom-scale-getter
Para obtener más información sobre la configuración de RBAC, consulta la documentación de RBAC de Kubernetes.
¿Qué sigue?
- Obtén más información sobre los búferes de capacidad.
- Consulta la documentación de la CRD de CapacityBuffer.