En este tutorial se usa Kueue para mostrarte cómo implementar un sistema de colas de trabajos, configurar el uso compartido de recursos y cuotas de cargas de trabajo entre diferentes espacios de nombres en Google Kubernetes Engine (GKE) y maximizar la utilización de tu clúster.
Fondo
Como ingeniero de infraestructura o administrador de clústeres, es muy importante maximizar la utilización entre espacios de nombres. Es posible que un lote de trabajos de un espacio de nombres no utilice por completo la cuota asignada al espacio de nombres, mientras que otro espacio de nombres puede tener varios trabajos pendientes. Para usar de forma eficiente los recursos del clúster entre los trabajos de diferentes espacios de nombres y aumentar la flexibilidad de la gestión de cuotas, puedes configurar cohortes en Kueue. Una cohorte es un grupo de ClusterQueues que pueden tomar prestada cuota no utilizada entre sí. Un ClusterQueue gestiona un conjunto de recursos, como CPU, memoria y aceleradores de hardware.
Puedes consultar una definición más detallada de todos estos conceptos en la documentación de Kueue.
Crear los ResourceFlavors
ResourceFlavor representa las variaciones de recursos en los nodos de tu clúster, como diferentes máquinas virtuales (por ejemplo, máquinas virtuales esporádicas frente a máquinas virtuales bajo demanda), arquitecturas (por ejemplo, CPUs x86 frente a CPUs ARM), marcas y modelos (por ejemplo, GPUs Nvidia A100 frente a GPUs T4).
ResourceFlavors usa etiquetas de nodo y taints para coincidir con un conjunto de nodos del clúster.
En este manifiesto:
- El ResourceFlavor
on-demand
tiene la etiquetacloud.google.com/gke-provisioning: standard
. - El ResourceFlavor
spot
tiene la etiquetacloud.google.com/gke-provisioning: spot
.
Cuando se asigna un ResourceFlavor a una carga de trabajo, Kueue asigna los pods de la carga de trabajo a los nodos que coinciden con las etiquetas de nodo definidas para el ResourceFlavor.
Despliega el ResourceFlavor:
kubectl apply -f flavors.yaml
Crear ClusterQueue y LocalQueue
Crea dos ClusterQueues, cq-team-a
y cq-team-b
, y sus LocalQueues correspondientes, lq-team-a
y lq-team-b
, respectivamente, en los espacios de nombres team-a
y team-b
.
ClusterQueues son objetos centrados en clústeres que rigen un conjunto de recursos, como CPU, memoria y aceleradores de hardware. Los administradores de lotes pueden restringir la visibilidad de estos objetos a los usuarios de lotes.
LocalQueues son objetos con espacio de nombres que los usuarios por lotes pueden enumerar. Apuntan a ClusterQueues, desde donde se asignan recursos para ejecutar las cargas de trabajo de LocalQueue.
ClusterQueues permite que los recursos tengan varios tipos. En este caso, ambos
ClusterQueues tienen dos variantes, on-demand
y spot
, y cada una proporciona cpu
recursos.
La cuota de ResourceFlavor spot
se ha definido como 0
y no se usará por el momento.
Ambas ClusterQueues comparten la misma cohorte, llamada all-teams
, definida en .spec.cohort
.
Cuando dos o más ClusterQueues comparten la misma cohorte, pueden tomar prestada la cuota no utilizada de los demás.
Puedes consultar más información sobre cómo funcionan las cohortes y la semántica de préstamo en la documentación de Kueue.
Despliega ClusterQueues y LocalQueues:
kubectl apply -f cq-team-a.yaml
kubectl apply -f cq-team-b.yaml
(Opcional) Monitorizar cargas de trabajo con kube-prometheus
Puedes usar Prometheus para monitorizar tus cargas de trabajo de Kueue activas y pendientes.
Para monitorizar las cargas de trabajo que se están poniendo en marcha y observar la carga de cada ClusterQueue, implementa kube-prometheus en el clúster del espacio de nombres monitoring
:
Descarga el código fuente del operador de Prometheus:
cd git clone https://github.com/prometheus-operator/kube-prometheus.git
Crea los CustomResourceDefinitions(CRDs):
kubectl create -f kube-prometheus/manifests/setup
Crea los componentes de monitorización:
kubectl create -f kube-prometheus/manifests
Permite que
prometheus-operator
extraiga métricas de los componentes de Kueue:kubectl apply -f https://github.com/kubernetes-sigs/kueue/releases/download/$VERSION/prometheus.yaml
Cambia al directorio de trabajo:
cd kubernetes-engine-samples/batch/kueue-cohort
Configura el reenvío de puertos al servicio de Prometheus que se ejecuta en tu clúster de GKE:
kubectl --namespace monitoring port-forward svc/prometheus-k8s 9090
Abre la interfaz web de Prometheus en localhost:9090 en el navegador.
En Cloud Shell:
Haz clic en Vista previa web.
Haz clic en Cambiar puerto y define el número de puerto como
9090
.Haz clic en Cambiar y obtener vista previa.
Aparecerá la siguiente interfaz web de Prometheus.
En el cuadro de consulta Expression (Expresión), introduce la siguiente consulta para crear el primer panel que monitoriza las cargas de trabajo activas de
cq-team-a
ClusterQueue:kueue_pending_workloads{cluster_queue="cq-team-a", status="active"} or kueue_admitted_active_workloads{cluster_queue="cq-team-a"}
Haz clic en Añadir panel.
En el cuadro de consulta Expresión, introduce la siguiente consulta para crear otro panel que monitorice las cargas de trabajo activas de
cq-team-b
ClusterQueue:kueue_pending_workloads{cluster_queue="cq-team-b", status="active"} or kueue_admitted_active_workloads{cluster_queue="cq-team-b"}
Haz clic en Añadir panel.
En el cuadro de consulta Expression (Expresión), introduce la siguiente consulta para crear un panel que monitorice el número de nodos del clúster:
count(kube_node_info)
Opcional: Monitorizar cargas de trabajo con Google Cloud Managed Service para Prometheus
Puedes usar Google Cloud Managed Service para Prometheus para monitorizar tus cargas de trabajo de Kueue activas y pendientes. Puedes consultar la lista completa de métricas en la documentación de Kueue.
Configura la identidad y el control de acceso basado en roles para acceder a las métricas:
La siguiente configuración crea 4 recursos de Kubernetes que proporcionan acceso a las métricas de los recopiladores de Google Cloud Managed Service para Prometheus.
Se usará una cuenta de servicio llamada
kueue-metrics-reader
en el espacio de nombreskueue-system
para autenticar el acceso a las métricas de Kueue.Un secreto asociado a la cuenta de servicio
kueue-metrics-reader
almacena un token de autenticación que usa el recopilador para autenticarse en el endpoint de métricas expuesto por la implementación de Kueue.Un rol llamado
kueue-secret-reader
en el espacio de nombreskueue-system
, que permite leer el secreto que contiene el token de la cuenta de servicio.Un ClusterRoleBinding que otorgue a la
kueue-metrics-reader
cuenta de servicio elkueue-metrics-reader
ClusterRole.
apiVersion: v1 kind: ServiceAccount metadata: name: kueue-metrics-reader namespace: kueue-system --- apiVersion: v1 kind: Secret metadata: name: kueue-metrics-reader-token namespace: kueue-system annotations: kubernetes.io/service-account.name: kueue-metrics-reader type: kubernetes.io/service-account-token --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: kueue-secret-reader namespace: kueue-system rules: - resources: - secrets apiGroups: [""] verbs: ["get", "list", "watch"] resourceNames: ["kueue-metrics-reader-token"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: kueue-metrics-reader subjects: - kind: ServiceAccount name: kueue-metrics-reader namespace: kueue-system roleRef: kind: ClusterRole name: kueue-metrics-reader apiGroup: rbac.authorization.k8s.io
Configura RoleBinding para Google Cloud Managed Service para Prometheus:
En función de si usas un clúster de Autopilot o Standard, tendrás que crear el RoleBinding en el espacio de nombres
gke-gmp-system
ogmp-system
. Este recurso permite que la cuenta de servicio del recopilador acceda alkueue-metrics-reader-token
secreto para autenticar y obtener las métricas de Kueue.Autopilot
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: gmp-system:collector:kueue-secret-reader namespace: kueue-system roleRef: name: kueue-secret-reader kind: Role apiGroup: rbac.authorization.k8s.io subjects: - name: collector namespace: gke-gmp-system kind: ServiceAccount
Estándar
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: gmp-system:collector:kueue-secret-reader namespace: kueue-system roleRef: name: kueue-secret-reader kind: Role apiGroup: rbac.authorization.k8s.io subjects: - name: collector namespace: gmp-system kind: ServiceAccount
Configura el recurso de PodMonitoring:
El siguiente recurso configura la monitorización de la implementación de Kueue y especifica que las métricas se exponen en la ruta /metrics a través de HTTPS. Usa el secreto
kueue-metrics-reader-token
para la autenticación al raspar las métricas.apiVersion: monitoring.googleapis.com/v1 kind: PodMonitoring metadata: name: kueue namespace: kueue-system spec: selector: matchLabels: control-plane: controller-manager endpoints: - port: 8443 interval: 30s path: /metrics scheme: https tls: insecureSkipVerify: true authorization: type: Bearer credentials: secret: name: kueue-metrics-reader-token key: token
Consultar métricas exportadas
Consultas de PromQL de ejemplo para monitorizar sistemas basados en Kueue
Estas consultas de PromQL te permiten monitorizar métricas clave de Kueue, como el rendimiento de los trabajos, la utilización de recursos por cola y los tiempos de espera de las cargas de trabajo, para comprender el rendimiento del sistema e identificar posibles cuellos de botella.
Rendimiento de las tareas
Calcula la tasa por segundo de las cargas de trabajo admitidas durante 5 minutos para cada cluster_queue. Esta métrica puede ayudar a desglosarlo por colas para identificar los cuellos de botella y, al sumarlo, se obtiene el rendimiento general del sistema.
Consulta:
sum(rate(kueue_admitted_workloads_total[5m])) by (cluster_queue)
Uso de recursos
Se presupone que metrics.enableClusterQueueResources
está habilitada. Calcula la relación entre el uso actual de la CPU y la cuota nominal de CPU de cada cola. Un valor cercano a 1 indica una utilización alta. Puedes adaptar este ejemplo a la memoria u otros recursos cambiando la etiqueta del recurso.
Para instalar una versión lanzada de Kueue con una configuración personalizada en tu clúster, sigue la documentación de Kueue.
Consulta:
sum(kueue_cluster_queue_resource_usage{resource="cpu"}) by (cluster_queue) / sum(kueue_cluster_queue_nominal_quota{resource="cpu"}) by (cluster_queue)
Tiempo de espera en la cola
Proporciona el tiempo de espera del percentil 90 de las cargas de trabajo de una cola específica. Puedes modificar el valor del cuantil (por ejemplo, 0,5 para la mediana o 0,99 para el percentil 99) para conocer la distribución del tiempo de espera.
Consulta:
histogram_quantile(0.9, kueue_admission_wait_time_seconds_bucket{cluster_queue="QUEUE_NAME"})
Crea trabajos y observa las cargas de trabajo admitidas
En esta sección, creará trabajos de Kubernetes en los espacios de nombres team-a
y team-b
. Un controlador de trabajo de Kubernetes crea uno o varios pods y se asegura de que ejecuten correctamente una tarea específica.
Genera tareas para ambas ClusterQueues que se suspenderán durante 10 segundos, con tres tareas paralelas, y se completarán con tres finalizaciones. Después de 60 segundos, se eliminará.
job-team-a.yaml
crea tareas en el espacio de nombres team-a
y apunta a LocalQueue lq-team-a
y ClusterQueue cq-team-a
.
Del mismo modo, job-team-b.yaml
crea tareas en el espacio de nombres team-b
y apunta a LocalQueue lq-team-b
y ClusterQueue cq-team-b
.
Inicia un nuevo terminal y ejecuta esta secuencia de comandos para generar un trabajo cada segundo:
./create_jobs.sh job-team-a.yaml 1
Abre otra terminal y crea trabajos para el espacio de nombres
team-b
:./create_jobs.sh job-team-b.yaml 1
Observa los trabajos que se ponen en cola en Prometheus. O con este comando:
watch -n 2 kubectl get clusterqueues -o wide
La salida debería ser similar a la siguiente:
NAME COHORT STRATEGY PENDING WORKLOADS ADMITTED WORKLOADS
cq-team-a all-teams BestEffortFIFO 0 5
cq-team-b all-teams BestEffortFIFO 0 4
Pedir prestada cuota no utilizada con cohortes
Es posible que ClusterQueues no tenga la capacidad máxima en todo momento. El uso de las cuotas no se maximiza cuando las cargas de trabajo no se distribuyen de forma uniforme entre las ClusterQueues. Si los ClusterQueues comparten la misma cohorte entre sí, pueden tomar prestadas cuotas de otros ClusterQueues para maximizar el uso de las cuotas.
Cuando haya tareas en cola para las ClusterQueues
cq-team-a
ycq-team-b
, detén la secuencia de comandos del espacio de nombresteam-b
pulsandoCTRL+c
en la terminal correspondiente.Una vez que se hayan procesado todos los trabajos pendientes del espacio de nombres
team-b
, los trabajos del espacio de nombresteam-a
podrán usar los recursos disponibles decq-team-b
:kubectl describe clusterqueue cq-team-a
Como
cq-team-a
ycq-team-b
comparten la misma cohorte llamadaall-teams
, estas ClusterQueues pueden compartir recursos que no se utilizan.Flavors Usage: Name: on-demand Resources: Borrowed: 5 Name: cpu Total: 15 Borrowed: 5Gi Name: memory Total: 15Gi
Reanuda la secuencia de comandos del espacio de nombres
team-b
../create_jobs.sh job-team-b.yaml 3
Observa cómo los recursos prestados de
cq-team-a
vuelven a0
, mientras que los recursos decq-team-b
se usan para sus propias cargas de trabajo:kubectl describe clusterqueue cq-team-a
Flavors Usage: Name: on-demand Resources: Borrowed: 0 Name: cpu Total: 9 Borrowed: 0 Name: memory Total: 9Gi
Aumentar la cuota con máquinas virtuales de acceso puntual
Cuando sea necesario aumentar la cuota temporalmente, por ejemplo, para satisfacer la alta demanda de cargas de trabajo pendientes, puede configurar Kueue para que se adapte a la demanda añadiendo más ClusterQueues al cohorte. Los ClusterQueues con recursos sin usar pueden compartir esos recursos con otros ClusterQueues que pertenezcan a la misma cohorte.
Al principio del tutorial, creaste un grupo de nodos llamado spot
con máquinas virtuales Spot y un ResourceFlavor llamado spot
con la etiqueta cloud.google.com/gke-provisioning: spot
. Crea un ClusterQueue para usar este grupo de nodos y el ResourceFlavor que lo representa:
Crea un ClusterQueue llamado
cq-spot
con el valorall-teams
en el campo Cohort:Como este ClusterQueue comparte la misma cohorte que
cq-team-a
ycq-team-b
, tanto ClusterQueuecq-team-a
comocq-team-b
pueden tomar prestados recursos de hasta 15 solicitudes de CPU y 15 Gi de memoria.kubectl apply -f cq-spot.yaml
En Prometheus, observa cómo se dispara el número de cargas de trabajo admitidas tanto para
cq-team-a
como paracq-team-b
gracias a la cuota añadida porcq-spot
, que comparte la misma cohorte. O con este comando:watch -n 2 kubectl get clusterqueues -o wide
En Prometheus, observa el número de nodos del clúster. O con este comando:
watch -n 2 kubectl get nodes -o wide
Detén ambas secuencias de comandos pulsando
CTRL+c
para el espacio de nombresteam-a
yteam-b
.