En este instructivo, se usa Kueue para mostrarte cómo implementar un sistema de colas de trabajos, configurar el recurso de carga de trabajo y el uso compartido de cuotas entre diferentes espacios de nombres en Google Kubernetes Engine (GKE), y maximizar el uso de tu clúster.
Fondo
Como ingeniero de infraestructura o administrador de clústeres, es muy importante maximizar el uso entre espacios de nombres. Es posible que un lote de trabajos en un espacio de nombres no use por completo la cuota completa asignada al espacio de nombres, mientras que otro espacio de nombres puede tener varios trabajos pendientes. Para utilizar de manera eficiente los recursos del clúster entre trabajos en diferentes espacios de nombres y aumentar la flexibilidad de la administración de cuotas, puedes configurar cohortes en Kueue. Una cohorte es un grupo de ClusterQueues que pueden tomar prestadas la cuota sin usar entre sí. Una ClusterQueue rige un grupo de recursos como CPU, memoria y aceleradores de hardware.
Puedes encontrar una definición más detallada de todos estos conceptos en la documentación de Kueue.
Crea los ResourceFlavors
Un ResourceFlavor representa las variaciones de recursos en los nodos de tu clúster, como diferentes VMs (por ejemplo, Spot frente a bajo demanda), arquitecturas (por ejemplo, CPU x86 frente a CPU de ARM), marcas y modelos (por ejemplo, Nvidia A100) en comparación con las GPU T4).
ResourceFlavors usa etiquetas de nodo y taints para hacer coincidir un conjunto de nodos en el clúster.
En el manifiesto se muestra lo siguiente:
- El ResourceFlavor
on-demand
tiene la etiqueta configurada encloud.google.com/gke-provisioning: standard
. - El ResourceFlavor
spot
tiene la etiqueta configurada encloud.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 coincidan con las etiquetas de nodo definidas para el ResourceFlavor.
Implementa ResourceFlavor:
kubectl apply -f flavors.yaml
Crea la ClusterQueue y la LocalQueue
Crea dos ClusterQueues cq-team-a
y cq-team-b
, y sus LocalQueues correspondientes lq-team-a
y lq-team-b
, respectivamente, con espacios de nombres en team-a
y team-b
.
Las ClusterQueues son objetos con permisos de clúster que rigen un grupo de recursos como los aceleradores de CPU, memoria y hardware. Los administradores de lotes pueden restringir la visibilidad de estos objetos a los usuarios por lotes.
LocalQueues son objetos con espacio de nombres que los usuarios pueden agrupar. Apuntan a CluterQueues, desde las cuales se asignan los recursos para ejecutar las cargas de trabajo de LocalQueue.
ClusterQueues permite que los recursos tengan múltiples variantes. En este caso, ambas ClusterQueues tienen dos variantes, on-demand
y spot
, cada una de las cuales proporciona recursos cpu
.
La cuota de spot
de ResourceFlavor está configurada como 0
y no se usará por ahora.
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 sin usar entre sí.
Puedes obtener más información sobre el funcionamiento de las cohortes y la semántica del préstamo en la doumentación de la UE.
Implementa las ClusterQueues y las LocalQueues:
kubectl apply -f cq-team-a.yaml
kubectl apply -f cq-team-b.yaml
Supervisa cargas de trabajo con kube-prometheus (opcional)
Puedes usar Prometheus para supervisar tus cargas de trabajo activas y pendientes de Kueue.
Para supervisar las cargas de trabajo que se activan y observar la carga en cada ClusterQueue, implementa kube-prometheus en el clúster bajo el 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 las CustomResourceDefinitions(CRD):
kubectl create -f kube-prometheus/manifests/setup
Crea los componentes de supervisión:
kubectl create -f kube-prometheus/manifests
Permite que
prometheus-operator
recopile 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 la redirección 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 IU web de Prometheus en localhost:9090 en el navegador.
En Cloud Shell, haz lo siguiente:
Haz clic en Vista previa en la Web.
Haz clic en Cambiar puerto y establece el número de puerto en
9090
.Haz clic en Cambiar y obtener vista previa (Change and Preview).
Aparecerá la siguiente IU web de Prometheus.
En el cuadro de consulta Expression, ingresa la siguiente consulta para crear el primer panel que supervisa las cargas de trabajo activas para la ClusterQueue
cq-team-a
:kueue_pending_workloads{cluster_queue="cq-team-a", status="active"} or kueue_admitted_active_workloads{cluster_queue="cq-team-a"}
Haz clic en Agregar panel.
En el cuadro de consulta Expression, ingresa la siguiente consulta para crear otro panel que supervise las cargas de trabajo activas para la ClusterQueue
cq-team-b
:kueue_pending_workloads{cluster_queue="cq-team-b", status="active"} or kueue_admitted_active_workloads{cluster_queue="cq-team-b"}
Haz clic en Agregar panel.
En el cuadro de consulta Expression, ingresa la siguiente consulta para crear un panel que supervise la cantidad de nodos del clúster:
count(kube_node_info)
(Opcional) Supervisa cargas de trabajo con Google Cloud Managed Service para Prometheus
Puedes usar Google Cloud Managed Service para Prometheus para supervisar tus cargas de trabajo activas y pendientes de Kueue. Puedes encontrar una lista completa de las métricas en la documentación de Kueue.
Configura la identidad y el RBAC para el acceso a las métricas:
La siguiente configuración crea 4 recursos de Kubernetes que proporcionan acceso a las métricas para los recopiladores de Google Cloud Managed Service para Prometheus.
Se usará una ServiceAccount llamada
kueue-metrics-reader
dentro del espacio de nombreskueue-system
para autenticar el acceso a las métricas de Kueue.Un Secret asociado con la cuenta de servicio de
kueue-metrics-reader
almacena un token de autenticación que usa el recopilador para autenticarse con el extremo de métricas que expone 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 otorga a la cuenta de servicio
kueue-metrics-reader
el ClusterRolekueue-metrics-reader
.
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:
Según si usas un clúster de Autopilot o Standard, deberás crear el RoleBinding en el espacio de nombres
gke-gmp-system
ogmp-system
. Este recurso permite que la cuenta de servicio del recopilador acceda al secretokueue-metrics-reader-token
para autenticar y recuperar 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 PodMonitoring:
El siguiente recurso configura la supervisión de la implementación de Kueue y especifica que las métricas se exponen en la ruta /metrics a través de HTTPS. Utiliza el secreto
kueue-metrics-reader-token
para la autenticación cuando extrae 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
Consulta las métricas exportadas
Ejemplos de consultas de PromQL para supervisar sistemas basados en Kueue
Estas consultas de PromQL te permiten supervisar las métricas clave de Kueue, como el rendimiento del trabajo, la utilización de recursos por cola y los tiempos de espera de la carga de trabajo para comprender el rendimiento del sistema y detectar posibles cuellos de botella.
Capacidad de procesamiento de trabajos
Esto calcula la tasa por segundo de las cargas de trabajo admitidas durante 5 minutos para cada cluster_queue. Esta métrica puede ayudar a desglosarla por cola, lo que permite identificar los cuellos de botella, y su suma proporciona la capacidad de procesamiento general del sistema.
Consulta:
sum(rate(kueue_admitted_workloads_total[5m])) by (cluster_queue)
Uso de recursos
Esto supone que metrics.enableClusterQueueResources
está habilitado. Calcula la proporción del uso actual de la CPU con respecto a la cuota nominal de CPU para cada cola. Un valor cercano a 1 indica un uso alto. Puedes adaptar esto para la memoria o cualquier otro recurso cambiando la etiqueta del recurso.
Para instalar una versión lanzada de Kueue con 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)
Tiempos de espera en la fila
Esto proporciona el percentil 90 del tiempo de espera para las cargas de trabajo en una cola específica. Puedes modificar el valor del cuantil (p.ej., 0.5 para la mediana, 0.99 para el percentil 99) para comprender la distribución del tiempo de espera.
Consulta:
histogram_quantile(0.9, kueue_admission_wait_time_seconds_bucket{cluster_queue="QUEUE_NAME"})
Crea Jobs y observa las cargas de trabajo admitidas
En esta sección, crearás Jobs de Kubernetes en los espacios de nombres team-a
y team-b
. Un controlador de Job en Kubernetes crea uno o más Pods y garantiza que ejecuten correctamente una tarea específica.
Genera trabajos en ambas ClusterQueues que quedarán en espera durante 10 segundos, con tres trabajos paralelos y se completarán con tres finalizaciones. Luego, se limpiará después de 60 segundos.
job-team-a.yaml
crea trabajos en el espacio de nombres team-a
y apunta a la LocalQueue lq-team-a
y la ClusterQueue cq-team-a
.
De manera similar, job-team-b.yaml
crea trabajos en el espacio de nombres team-b
y apunta a la LocalQueue lq-team-b
y la ClusterQueue cq-team-b
.
Inicia una terminal nueva y ejecuta esta secuencia de comandos para generar un trabajo cada segundo:
./create_jobs.sh job-team-a.yaml 1
Inicia 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
El resultado debería ser similar al siguiente ejemplo:
NAME COHORT STRATEGY PENDING WORKLOADS ADMITTED WORKLOADS
cq-team-a all-teams BestEffortFIFO 0 5
cq-team-b all-teams BestEffortFIFO 0 4
Préstamo de cuotas sin uso con cohortes
Es posible que las ClusterQueues no estén a máxima capacidad en todo momento. El uso de cuotas no se maximiza cuando las cargas de trabajo no se distribuyen de manera uniforme entre las ClusterQueues. Si las ClusterQueues comparten la misma cohorte entre sí, las ClusterQueues pueden tomar prestadas las cuotas de otras ClusterQueues para maximizar el uso de la cuota.
Una vez que hay trabajos en cola para ambas ClusterQueues
cq-team-a
ycq-team-b
, detén la secuencia de comandos parateam-b
espacio de nombres presionandoCTRL+c
en la terminal correspondiente.Una vez que se procesen todos los trabajos pendientes del espacio de nombres
team-b
, los trabajos del espacio de nombresteam-a
pueden tomar prestados los recursos disponibles encq-team-b
:kubectl describe clusterqueue cq-team-a
Debido a que
cq-team-a
ycq-team-b
comparten la misma cohorte llamadaall-teams
, estas ClusterQueues pueden compartir recursos que no se usan.Flavors Usage: Name: on-demand Resources: Borrowed: 5 Name: cpu Total: 15 Borrowed: 5Gi Name: memory Total: 15Gi
Reanuda la secuencia de comandos para el 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
Aumenta la cuota con las VM Spot
Cuando la cuota deba aumentarse de forma temporal, por ejemplo, para satisfacer la alta demanda de las cargas de trabajo pendientes, puedes configurar Kueue a fin de que se adapte a la demanda. Para ello, agrega más ClusterQueues a la cohorte. Las ClusterQueues con recursos sin usar pueden compartir esos recursos con otras ClusterQueues que pertenezcan a la misma cohorte.
Al comienzo del instructivo, creaste un grupo de nodos llamado spot
mediante las VM Spot y un ResourceFlavor llamado spot
con la etiqueta configurada como cloud.google.com/gke-provisioning: spot
. Crea una ClusterQueue para usar este grupo de nodos y el ResourceFlavor que lo representa:
Crea una ClusterQueue nueva llamada
cq-spot
con la cohorte configurada comoall-teams
:Debido a que ClusterCluster comparte la misma cohorte con
cq-team-a
ycq-team-b
, tanto ClusterQueuecq-team-a
ycq-team-b
pueden tomar prestados recursos hasta 15 solicitudes de CPU y 15 Gi de memoria.kubectl apply -f cq-spot.yaml
En Prometheus, observa cómo aumentan las cargas de trabajo admitidas para
cq-team-a
ycq-team-b
, gracias a la cuota agregada decq-spot
que comparte la misma cohorte. O con este comando:watch -n 2 kubectl get clusterqueues -o wide
En Prometheus, observa la cantidad de nodos en el clúster. O con este comando:
watch -n 2 kubectl get nodes -o wide
Para detener ambas secuencias de comandos, presiona
CTRL+c
para los espacios de nombresteam-a
yteam-b
.