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.
Objetivos
Este instructivo es para ingenieros de infraestructura o administradores de clústeres que deseen implementar un sistema de cola de trabajos en Kubernetes mediante Kueue con uso compartido de cuotas.En este instructivo, se imitan dos equipos en dos espacios de nombres diferentes, en los que cada equipo tiene sus recursos dedicados, pero pueden tomar recursos prestados entre sí. Un tercer conjunto de recursos se puede usar como desbordamiento cuando se acumulan los trabajos.
Usa el operador de Prometheus para supervisar los trabajos y la asignación de recursos en diferentes espacios de nombres.
En este instructivo, se abordan los siguientes pasos necesarios:
- Crea un clúster de GKE
- Crea los ResourceFlavors.
- Para cada equipo, crea una ClusterQueue y una LocalQueue
- Crea Jobs y observa las cargas de trabajo admitidas
- Toma prestada la cuota sin usar con cohortes
- Agrega una ClusterQueue de desbordamiento que rija las VMs Spot
Costos
En este instructivo, se usan los siguientes componentes facturables de Google Cloud:Usa la calculadora de precios para generar una estimación de los costos según el uso previsto.
Cuando finalices este instructivo, puedes borrar los recursos creados para evitar que se te siga facturando. Para obtener más información, consulta Cómo realizar una limpieza.
Antes de comenzar
Configura tu proyecto
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the GKE API.
-
In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the GKE API.
Establece valores predeterminados para Google Cloud CLI
En la consola de Google Cloud, inicia una instancia de Cloud Shell:
Abrir Cloud ShellDescarga el código fuente para esta app de ejemplo:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
Configura las variables de entorno predeterminadas:
gcloud config set project PROJECT_ID gcloud config set compute/region COMPUTE_REGION
Reemplaza los siguientes valores:
- PROJECT_ID: Es el Google Cloud ID de tu proyecto.
- COMPUTE_REGION: la región de Compute Engine
Crear un clúster de GKE
Crea un clúster de GKE llamado
kueue-cohort
:Crearás un clúster con 6 nodos (2 por zona) en el grupo predeterminado y sin ajuste de escala automático. Esos serán todos los recursos disponibles para los equipos al principio, por lo que tendrán que competir por ellos.
Más adelante, verás cómo Kueue administra las cargas de trabajo que ambos equipos enviarán a las colas correspondientes.
gcloud container clusters create kueue-cohort --region COMPUTE_REGION \ --release-channel rapid --machine-type e2-standard-4 --num-nodes 2
El resultado es similar al siguiente una vez que se crea el clúster:
kubeconfig entry generated for kueue-cohort. NAME: kueue-cohort LOCATION: us-central1 MASTER_VERSION: 1.26.2-gke.1000 MASTER_IP: 35.224.108.58 MACHINE_TYPE: e2-medium NODE_VERSION: 1.26.2-gke.1000 NUM_NODES: 6 STATUS: RUNNING
En el ejemplo anterior,
STATUS
esRUNNING
parakueue-cluster
.Crea un grupo de nodos llamado
spot
.Este grupo de nodos usa VM Spot y tiene habilitado el ajuste de escala automático. Comienza con 0 nodos, pero, luego, lo pondrás a disposición de los equipos para que los usen como capacidad de desbordamiento.
gcloud container node-pools create spot --cluster=kueue-cohort --region COMPUTE_REGION \ --spot --enable-autoscaling --max-nodes 20 --num-nodes 0 \ --machine-type e2-standard-4
Instala la versión de actualización de Kueue en el clúster:
VERSION=VERSION kubectl apply -f \ https://github.com/kubernetes-sigs/kueue/releases/download/$VERSION/manifests.yaml
Reemplaza VERSION por la letra v seguida de la versión más reciente de Kueue, por ejemplo,
v0.4.0
. Para obtener más información sobre las versiones de Kueue, consulta Versiones de Kueue.Espera hasta que el controlador de Kueue esté listo:
watch kubectl -n kueue-system get pods
El resultado debería ser similar al siguiente antes de que puedas continuar:
NAME READY STATUS RESTARTS AGE kueue-controller-manager-6cfcbb5dc5-rsf8k 2/2 Running 0 3m
Crear dos espacios de nombres nuevos llamados
team-a
yteam-b
:kubectl create namespace team-a kubectl create namespace team-b
Los trabajos se generarán en cada espacio de nombres.
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 en 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 Expresión, ingresa la siguiente consulta para crear el primer panel que supervise 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 Agregar panel.
En el cuadro de consulta Expresión, ingresa la siguiente consulta para crear otro panel que supervise 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 Agregar panel.
En el cuadro de consulta Expresión, 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 Identity y 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 cuenta de servicio llamada
kueue-metrics-reader
dentro del espacio de nombreskueue-system
para autenticar cuando se acceda a las métricas de Kueue.Un Secret asociado con la cuenta de servicio
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 servicioUn 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 raspar 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 supervisión de pods:
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. Usa 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: https interval: 30s path: /metrics scheme: https tls: insecureSkipVerify: true authorization: type: Bearer credentials: secret: name: kueue-metrics-reader-token key: token
Cómo consultar métricas exportadas
Consultas de PromQL de muestra para supervisar sistemas basados en Kueue
Estas consultas de PromQL te permiten supervisar métricas clave de Kueue, como la capacidad de procesamiento de trabajos, 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 para identificar los cuellos de botella y sumarla para proporcionar la capacidad de procesamiento general del sistema.
Consulta:
sum(rate(kueue_admitted_workloads_total[5m])) by (cluster_queue)
Uso de recursos
Se da por sentado que metrics.enableClusterQueueResources
está habilitado. Calcula la proporción del uso actual de la CPU con respecto a la cuota nominal de CPU de cada cola. Un valor cercano a 1 indica una alta utilización. Puedes adaptar esto para la memoria o para otros recursos cambiando la etiqueta del recurso.
Para instalar una versión publicada de Kueue configurada de forma 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 de la cola
Esto proporciona el tiempo de espera del percentil 90 para las cargas de trabajo en una cola específica. Puedes modificar el valor del cuantile (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 trabajos de Kubernetes en el espacio de nombres team-a
y team-b
. Un controlador de trabajos en Kubernetes crea uno o más Pods y se asegura de 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
.
Limpia
Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo, borra el proyecto que contiene los recursos o conserva el proyecto y borra los recursos individuales.
Borra el proyecto
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
Borra el recurso individual
Borra el sistema de cuotas de Kueue:
kubectl delete -n team-a localqueue lq-team-a kubectl delete -n team-b localqueue lq-team-b kubectl delete clusterqueue cq-team-a kubectl delete clusterqueue cq-team-b kubectl delete clusterqueue cq-spot kubectl delete resourceflavor default kubectl delete resourceflavor on-demand kubectl delete resourceflavor spot
Borra el manifiesto de Kueue:
VERSION=VERSION kubectl delete -f \ https://github.com/kubernetes-sigs/kueue/releases/download/$VERSION/manifests.yaml
Borra el clúster:
gcloud container clusters delete kueue-cohort --region=COMPUTE_REGION
¿Qué sigue?
Obtén más información sobre cómo implementar un sistema por lotes con Kueue.
Obtén más información sobre los trabajos en GKE.