Este tutorial usa o Kueue para mostrar como implementar um sistema de colocação em fila de tarefas, configurar a partilha de recursos e quotas de cargas de trabalho entre diferentes espaços de nomes no Google Kubernetes Engine (GKE) e maximizar a utilização do seu cluster.
Contexto
Como engenheiro de infraestrutura ou administrador de clusters, maximizar a utilização entre espaços de nomes é muito importante. Um lote de trabalhos num espaço de nomes pode não usar totalmente a quota atribuída ao espaço de nomes, enquanto outro espaço de nomes pode ter vários trabalhos pendentes. Para usar eficientemente os recursos do cluster entre tarefas em diferentes espaços de nomes e aumentar a flexibilidade da gestão de quotas, pode configurar coortes no Kueue. Uma coorte é um grupo de ClusterQueues que podem pedir emprestado quota não utilizada entre si. Uma ClusterQueue rege um conjunto de recursos, como a CPU, a memória e os aceleradores de hardware.
Pode encontrar uma definição mais detalhada de todos estes conceitos na documentação do Kueue
Crie os ResourceFlavors
Um ResourceFlavor representa variações de recursos nos nós do cluster, como VMs diferentes (por exemplo, spot versus a pedido), arquiteturas (por exemplo, CPUs x86 vs ARM), marcas e modelos (por exemplo, GPUs Nvidia A100 versus T4).
Os ResourceFlavors usam etiquetas de nós e taints para corresponder a um conjunto de nós no cluster.
Neste manifesto:
- O ResourceFlavor
on-demand
tem a etiqueta definida comocloud.google.com/gke-provisioning: standard
. - O ResourceFlavor
spot
tem a etiqueta definida comocloud.google.com/gke-provisioning: spot
.
Quando é atribuído um ResourceFlavor a uma carga de trabalho, o Kueue atribui os pods da carga de trabalho a nós que correspondem às etiquetas de nós definidas para o ResourceFlavor.
Implemente o ResourceFlavor:
kubectl apply -f flavors.yaml
Crie o ClusterQueue e o LocalQueue
Crie duas ClusterQueues cq-team-a
e cq-team-b
, e as respetivas LocalQueues lq-team-a
e lq-team-b
com espaço de nomes team-a
e team-b
, respetivamente.
As ClusterQueues são objetos com âmbito de cluster que regem um conjunto de recursos, como CPU, memória e aceleradores de hardware. Os administradores de lotes podem restringir a visibilidade destes objetos aos utilizadores de lotes.
LocalQueues são objetos com espaço de nomes que os utilizadores podem listar em lote. Apontam para CluterQueues, a partir dos quais são alocados recursos para executar as cargas de trabalho LocalQueue.
O ClusterQueues permite que os recursos tenham vários tipos. Neste caso, ambas as ClusterQueues têm duas variantes, on-demand
e spot
, cada uma a fornecer recursos cpu
.
A quota do ResourceFlavor spot
está definida como 0
e não vai ser usada por agora.
Ambas as ClusterQueues partilham a mesma coorte denominada all-teams
, definida em .spec.cohort
.
Quando duas ou mais ClusterQueues partilham a mesma coorte, podem pedir emprestada quota não utilizada umas às outras.
Pode saber mais sobre como funcionam as coortes e a semântica de empréstimo na documentação do Kueue
Implemente as ClusterQueues e as LocalQueues:
kubectl apply -f cq-team-a.yaml
kubectl apply -f cq-team-b.yaml
(Opcional) Monitorize cargas de trabalho com o kube-prometheus
Pode usar o Prometheus para monitorizar as cargas de trabalho ativas e pendentes do Kueue.
Para monitorizar as cargas de trabalho que estão a ser iniciadas e observar a carga em cada ClusterQueue, implemente o kube-prometheus no cluster no espaço de nomes monitoring
:
Transfira o código-fonte do operador do Prometheus:
cd git clone https://github.com/prometheus-operator/kube-prometheus.git
Crie as CustomResourceDefinitions(CRDs):
kubectl create -f kube-prometheus/manifests/setup
Crie os componentes de monitorização:
kubectl create -f kube-prometheus/manifests
Permitir que o
prometheus-operator
extraia métricas dos componentes do Kueue:kubectl apply -f https://github.com/kubernetes-sigs/kueue/releases/download/$VERSION/prometheus.yaml
Mude para o diretório de trabalho:
cd kubernetes-engine-samples/batch/kueue-cohort
Configure o encaminhamento de portas para o serviço Prometheus em execução no seu cluster do GKE:
kubectl --namespace monitoring port-forward svc/prometheus-k8s 9090
Abra a IU Web do Prometheus em localhost:9090 no navegador.
No Cloud Shell:
Clique em Pré-visualização Web.
Clique em Alterar porta e defina o número da porta para
9090
.Clique em Alterar e pré-visualizar.
É apresentada a seguinte IU Web do Prometheus.
Na caixa de consulta Expressão, introduza a seguinte consulta para criar o primeiro painel que monitoriza as cargas de trabalho ativas para
cq-team-a
ClusterQueue:kueue_pending_workloads{cluster_queue="cq-team-a", status="active"} or kueue_admitted_active_workloads{cluster_queue="cq-team-a"}
Clique em Adicionar painel.
Na caixa de consulta Expressão, introduza a seguinte consulta para criar outro painel que monitorize as cargas de trabalho ativas para
cq-team-b
ClusterQueue:kueue_pending_workloads{cluster_queue="cq-team-b", status="active"} or kueue_admitted_active_workloads{cluster_queue="cq-team-b"}
Clique em Adicionar painel.
Na caixa de consulta Expressão, introduza a seguinte consulta para criar um painel que monitorize o número de nós no cluster:
count(kube_node_info)
(Opcional) Monitorize cargas de trabalho com o serviço gerido do Google Cloud para Prometheus
Pode usar o serviço gerido do Google Cloud para Prometheus para monitorizar as suas cargas de trabalho do Kueue ativas e pendentes. Pode encontrar uma lista completa de métricas na documentação do Kueue.
Configure a identidade e o RBAC para o acesso às métricas:
A seguinte configuração cria 4 recursos do Kubernetes que fornecem acesso a métricas para os coletores do Google Cloud Managed Service for Prometheus.
Uma ServiceAccount denominada
kueue-metrics-reader
no espaço de nomeskueue-system
é usada para autenticar o acesso às métricas do Kueue.Um segredo associado à conta de serviço
kueue-metrics-reader
, armazena um token de autenticação que é usado pelo coletor para fazer a autenticação no ponto final de métricas exposto pela implementação do Kueue.Uma função denominada
kueue-secret-reader
no espaço de nomeskueue-system
, que permite ler o segredo que contém o token da conta de serviço.Um ClusterRoleBinding que concede à conta de serviço
kueue-metrics-reader
o 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
Configure RoleBinding para o serviço gerido do Google Cloud para Prometheus:
Consoante esteja a usar um cluster do Autopilot ou padrão, tem de criar o RoleBinding no espaço de nomes
gke-gmp-system
ougmp-system
. Este recurso permite que a conta de serviço do coletor aceda ao segredokueue-metrics-reader-token
para autenticar e extrair as métricas do Kueue.Piloto automático
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
Standard
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
Configure o recurso de monitorização de pods:
O recurso seguinte configura a monitorização da implementação do Kueue. Especifica que as métricas são expostas no caminho /metrics através de HTTPS. Usa o segredo
kueue-metrics-reader-token
para autenticação ao extrair as 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
Consulte métricas exportadas
Exemplos de consultas PromQL para monitorizar sistemas baseados em Kueue
Estas consultas PromQL permitem-lhe monitorizar as principais métricas do Kueue, como o débito de tarefas, a utilização de recursos por fila e os tempos de espera da carga de trabalho, para compreender o desempenho do sistema e identificar potenciais estrangulamentos.
Tráfego transmitido de tarefas
Isto calcula a taxa por segundo de cargas de trabalho admitidas durante 5 minutos para cada cluster_queue. Esta métrica pode ajudar a discriminar por fila, o que ajuda a identificar gargalos, e a somá-la fornece o débito geral do sistema.
Consulta:
sum(rate(kueue_admitted_workloads_total[5m])) by (cluster_queue)
Utilização de recursos
Isto pressupõe que a funcionalidade metrics.enableClusterQueueResources
está ativada. Calcula a relação entre a utilização atual da CPU e a quota nominal da CPU para cada fila. Um valor
próximo de 1 indica uma utilização elevada. Pode adaptar isto para a memória ou outros recursos alterando a etiqueta do recurso.
Para instalar uma versão lançada do Kueue configurada de forma personalizada no seu cluster, siga a documentação do Kueue.
Consulta:
sum(kueue_cluster_queue_resource_usage{resource="cpu"}) by (cluster_queue) / sum(kueue_cluster_queue_nominal_quota{resource="cpu"}) by (cluster_queue)
Tempos de espera na fila
Isto indica o tempo de espera do percentil 90 para cargas de trabalho numa fila específica. Pode modificar o valor do quantil (por exemplo, 0,5 para a mediana, 0,99 para o percentil 99) para compreender a distribuição do tempo de espera.
Consulta:
histogram_quantile(0.9, kueue_admission_wait_time_seconds_bucket{cluster_queue="QUEUE_NAME"})
Crie tarefas e observe as cargas de trabalho admitidas
Nesta secção, cria tarefas do Kubernetes no espaço de nomes team-a
e team-b
. Um controlador de tarefas no Kubernetes cria um ou mais pods e garante que executam com êxito uma tarefa específica.
Gere tarefas para ambas as ClusterQueues que vão ficar inativas durante 10 segundos, com três tarefas paralelas e que vão ser concluídas com três conclusões. Em seguida, é limpa após 60 segundos.
job-team-a.yaml
cria tarefas no espaço de nomes team-a
e aponta para
LocalQueue lq-team-a
e ClusterQueue cq-team-a
.
Da mesma forma, job-team-b.yaml
cria tarefas no espaço de nomes team-b
e aponta
para LocalQueue lq-team-b
e ClusterQueue cq-team-b
.
Inicie um novo terminal e execute este script para gerar uma tarefa a cada segundo:
./create_jobs.sh job-team-a.yaml 1
Inicie outro terminal e crie trabalhos para o espaço de nomes
team-b
:./create_jobs.sh job-team-b.yaml 1
Observe as tarefas que estão a ser colocadas em fila no Prometheus. Em alternativa, com este comando:
watch -n 2 kubectl get clusterqueues -o wide
O resultado deve ser semelhante ao seguinte:
NAME COHORT STRATEGY PENDING WORKLOADS ADMITTED WORKLOADS
cq-team-a all-teams BestEffortFIFO 0 5
cq-team-b all-teams BestEffortFIFO 0 4
Peça emprestada quota não usada com coortes
As ClusterQueues podem não estar sempre com capacidade total. A utilização de quotas não é maximizada quando as cargas de trabalho não estão distribuídas uniformemente entre as ClusterQueues. Se os ClusterQueues partilharem a mesma coorte entre si, podem pedir emprestadas quotas a outros ClusterQueues para maximizar a utilização das quotas.
Quando existirem tarefas em fila para as ClusterQueues
cq-team-a
ecq-team-b
, pare o script para o espaço de nomesteam-b
premindoCTRL+c
no terminal correspondente.Assim que todas as tarefas pendentes do espaço de nomes
team-b
forem processadas, as tarefas do espaço de nomesteam-a
podem usar os recursos disponíveis emcq-team-b
:kubectl describe clusterqueue cq-team-a
Uma vez que
cq-team-a
ecq-team-b
partilham a mesma coorte denominadaall-teams
, estas ClusterQueues podem partilhar recursos que não são utilizados.Flavors Usage: Name: on-demand Resources: Borrowed: 5 Name: cpu Total: 15 Borrowed: 5Gi Name: memory Total: 15Gi
Retome o script para o espaço de nomes
team-b
../create_jobs.sh job-team-b.yaml 3
Observe como os recursos emprestados de
cq-team-a
regressam a0
, enquanto os recursos decq-team-b
são usados para as suas próprias cargas de trabalho:kubectl describe clusterqueue cq-team-a
Flavors Usage: Name: on-demand Resources: Borrowed: 0 Name: cpu Total: 9 Borrowed: 0 Name: memory Total: 9Gi
Aumente a quota com VMs do Spot
Quando a quota tem de ser aumentada temporariamente, por exemplo, para satisfazer a elevada procura em cargas de trabalho pendentes, pode configurar o Kueue para satisfazer a procura adicionando mais ClusterQueues ao grupo. As ClusterQueues com recursos não usados podem partilhar esses recursos com outras ClusterQueues que pertencem à mesma coorte.
No início do tutorial, criou um conjunto de nós denominado spot
com VMs de Spot e um ResourceFlavor denominado spot
com a etiqueta definida como cloud.google.com/gke-provisioning: spot
. Crie uma ClusterQueue para usar este node pool e o ResourceFlavor que o representa:
Crie uma nova ClusterQueue denominada
cq-spot
com o conjunto de coortes definido comoall-teams
:Uma vez que esta ClusterQueue partilha a mesma coorte com
cq-team-a
ecq-team-b
, tanto a ClusterQueuecq-team-a
como acq-team-b
podem pedir emprestados recursos até 15 pedidos de CPU e 15 Gi de memória.kubectl apply -f cq-spot.yaml
No Prometheus, observe como os volumes de trabalho admitidos aumentam para
cq-team-a
ecq-team-b
graças à quota adicionada porcq-spot
, que partilha a mesma coorte. Em alternativa, com este comando:watch -n 2 kubectl get clusterqueues -o wide
No Prometheus, observe o número de nós no cluster. Em alternativa, com este comando:
watch -n 2 kubectl get nodes -o wide
Pare ambos os scripts premindo
CTRL+c
para o espaço de nomesteam-a
eteam-b
.