Neste tutorial, usamos o Kueue para mostrar como implementar um sistema de enfileiramento de jobs, configurar o recurso de carga de trabalho e o compartilhamento de cota entre diferentes namespaces no Google Kubernetes Engine (GKE) e maximizar a utilização do cluster.
Contexto
Como engenheiro de infraestrutura ou administrador de cluster, maximizar a utilização entre namespaces é muito importante. Um lote de jobs em um namespace pode não utilizar totalmente a cota completa atribuída ao namespace, enquanto outro namespace pode ter vários jobs pendentes. Para utilizar com eficiência os recursos do cluster entre jobs em namespaces diferentes e aumentar a flexibilidade do gerenciamento de cotas, configure coortes no Kueue. Uma coorte é um grupo de ClusterQueues que podem pedir emprestados cotas não utilizadas uns dos outros. Um ClusterQueue controla um conjunto de recursos, como aceleradores de hardware, memória e CPU.
Você pode encontrar uma definição mais detalhada de todos esses conceitos na documentação do Kueue
Objetivos
Este tutorial é para engenheiros de infraestrutura ou administradores de cluster que querem implementar um sistema de enfileiramento de jobs no Kubernetes usando o Kueue com compartilhamento de cota.Este tutorial imitará duas equipes em dois namespaces diferentes, em que cada uma tem recursos dedicados, mas pode usar as outras. Um terceiro conjunto de recursos pode ser usado como sobrecarga quando os jobs se acumulam.
Use o operador Prometheus para monitorar jobs e alocação de recursos em namespaces diferentes.
Este tutorial inclui as etapas a seguir:
- Criar um cluster do GKE
- Crie os ResourceFlavors.
- Para cada equipe, crie um ClusterQueue e um LocalQueue
- (Opcional) Implantar o kube-prometheus e monitorar as cargas de trabalho usando o Prometheus
- Criar Jobs e observar as cargas de trabalho admitidas
- Pedir emprestado a cota não utilizada com coortes
- Adicionar um spilover ClusterQueue que rege as VMs spot
Custos
Neste tutorial, usamos o seguinte componente faturável do Google Cloud:Use a calculadora de preços para gerar uma estimativa de custo com base no uso previsto.
Ao concluir este tutorial, exclua os recursos criados para evitar o faturamento contínuo. Para mais informações, consulte Limpeza.
Antes de começar
Crie o projeto
- 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.
Definir padrões para a Google Cloud CLI
No console do Google Cloud, inicie uma instância do Cloud Shell:
Abrir o Cloud ShellFaça o download do código-fonte para este app de amostra:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
Defina as variáveis de ambiente padrão:
gcloud config set project PROJECT_ID gcloud config set compute/region COMPUTE_REGION
Substitua os seguintes valores:
- PROJECT_ID: é o ID do projeto do Google Cloud.
- COMPUTE_REGION: a região do Compute Engine.
Criar um cluster do GKE
Crie um Cluster do GKE chamado
kueue-cohort
:Você vai criar um cluster com seis nós (dois por zona) no pool padrão e sem escalonamento automático. Esses serão todos os recursos disponíveis para as equipes no início, então elas precisarão competir por elas.
Você verá como o Kueue gerencia as cargas de trabalho que as duas equipes enviarão às respectivas filas.
gcloud container clusters create kueue-cohort --region COMPUTE_REGION \ --release-channel rapid --machine-type e2-standard-4 --num-nodes 2
Após a criação do cluster, o resultado será semelhante a este:
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
Em que a
STATUS
éRUNNING
para akueue-cluster
.Crie um pool de nós chamado
spot
.Este pool de nós usa a VM do Spot, e o escalonamento automático está ativado. Ele começa com 0 nós, mas depois você o disponibilizará para as equipes para uso como capacidade de sobrecarga.
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
Instale a versão de lançamento do Kueue no cluster:
VERSION=VERSION kubectl apply -f \ https://github.com/kubernetes-sigs/kueue/releases/download/$VERSION/manifests.yaml
Substitua VERSION pela letra v após a versão mais recente do Kueue, por exemplo,
v0.4.0
. Para conferir mais informações sobre as versões do Kueue, consulte as Versões do Kueue.Aguarde até que o controlador do Kueue esteja pronto:
watch kubectl -n kueue-system get pods
A saída será semelhante a esta antes de continuar:
NAME READY STATUS RESTARTS AGE kueue-controller-manager-6cfcbb5dc5-rsf8k 2/2 Running 0 3m
Crie dois novos namespaces chamados
team-a
eteam-b
:kubectl create namespace team-a kubectl create namespace team-b
Os jobs serão gerados em cada namespace.
Criar o ResourceFlavors
Um ResourceFlavor representa variações de recursos nos nós do cluster, como VMs diferentes (por exemplo, spot versus sob demanda), arquiteturas (por exemplo, CPUs x86 x ARM), marcas e modelos (por exemplo, Nvidia A100 versus GPUs T4).
Os ResourceFlavors usam rótulos e taints de nós para fazer a correspondência com um conjunto de nós no cluster.
Nesse manifesto:
- O ResourceFlavor
on-demand
tem o rótulo definido comocloud.google.com/gke-provisioning: standard
. - O ResourceFlavor
spot
tem o rótulo definido comocloud.google.com/gke-provisioning: spot
.
Quando uma carga de trabalho é atribuída a um ResourceFlavor, o Kueue atribui os pods da carga aos nós que correspondem aos rótulos de nós definidos para o ResourceFlavor.
Implantar o ResourceFlavor:
kubectl apply -f flavors.yaml
Criar o ClusterQueue e a LocalQueue
Crie duas ClusterQueues cq-team-a
e cq-team-b
e as LocalQueues lq-team-a
e lq-team-b
correspondentes com os namespaces team-a
e team-b
, respectivamente.
ClusterQueues são objetos com escopo de cluster que controlam um pool de recursos, como aceleradores de hardware, memória e CPU. Os administradores em lote podem restringir a visibilidade desses objetos a usuários em lote.
LocalQueues são objetos com namespace que os usuários em lote podem listar. Eles apontam para CluterQueues, a partir dos quais os recursos são alocados para executar as cargas de trabalho da LocalQueue.
ClusterQueues permite que os recursos tenham diversas variações. Nesse caso, as duas
QueueQueues têm duas variações, on-demand
e spot
, cada uma fornecendo recursos cpu
.
A cota de spot
do ResourceFlavor está definida como 0
e não será usada no momento.
As duas ClusterQueues compartilham a mesma coorte chamada all-teams
, definida em .spec.cohort
.
Quando duas ou mais ClusterQueues compartilham a mesma coorte, é possível pedir emprestado uma cota não utilizada entre si.
Saiba mais sobre como as coortes funcionam e a semântica do empréstimo na documentação do Kueue
Implante as ClusterQueues e LocalQueues:
kubectl apply -f cq-team-a.yaml
kubectl apply -f cq-team-b.yaml
(Opcional) Implantar o kube-prometheus e monitorar as cargas de trabalho usando o Prometheus
É possível usar o Prometheus para monitorar cargas de trabalho pendentes e ativas do Kueue. Para monitorar as cargas de trabalho que estão sendo criadas e observar a carga em cada ClusterQueue, configure o Prometheus para o cluster no monitoramento de namespace.
Faça o download do código-fonte do operador do Prometheus para monitoramento:
cd git clone https://github.com/prometheus-operator/kube-prometheus.git
Crie os CustomResourceDefinitions(CRDs):
kubectl create -f kube-prometheus/manifests/setup
Crie os componentes de monitoramento:
kubectl create -f kube-prometheus/manifests
Permita que o operador prometheus colete as 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
Inicie um novo terminal para acessar o Prometheus encaminhando a porta do serviço:
kubectl --namespace monitoring port-forward svc/prometheus-k8s 9090
Abra o Prometheus no localhost:9090 no navegador.
Se estiver usando o Cloud Shell, clique em Visualização da Web, selecione "Alterar porta", defina o número da porta como 9090 e selecione
Change and Preview
.Insira a consulta do primeiro painel que monitora o ClusterQueue ativo
cq-team-a
:kueue_pending_workloads{cluster_queue="cq-team-a", status="active"} or kueue_admitted_active_workloads{cluster_queue="cq-team-a"}
Adicione outro painel e insira a consulta que monitora o
cq-team-b
da ClusterQueue ativa:kueue_pending_workloads{cluster_queue="cq-team-b", status="active"} or kueue_admitted_active_workloads{cluster_queue="cq-team-b"}
Adicione outro painel e insira a consulta que monitora o número de nós no cluster:
count(kube_node_info)
Criar Jobs e observar as cargas de trabalho admitidas
Gerar jobs para os ClusterQueues que ficarão suspensos por 10 segundos, com três jobs em paralelo e com três conclusões concluídas. Em seguida, ele será limpo após 60 segundos.
job-team-a.yaml
cria jobs no namespace team-a
e aponta para o LocalQueue lq-team-a
e o ClusterQueue cq-team-a
.
Da mesma forma, job-team-b.yaml
cria jobs no namespace team-b
e aponta para o LocalQueue lq-team-b
e a ClusterQueue cq-team-b
.
Inicie um novo terminal e execute este script para gerar um job a cada segundo:
./create_jobs.sh job-team-a.yaml 1
Inicie outro terminal e crie jobs para o namespace
team-b
:./create_jobs.sh job-team-b.yaml 1
Observe os jobs que estão sendo enfileirados no Prometheus. Ou com este comando:
watch -n 2 kubectl get clusterqueues -o wide
A saída será semelhante a esta:
NAME COHORT STRATEGY PENDING WORKLOADS ADMITTED WORKLOADS
cq-team-a all-teams BestEffortFIFO 0 5
cq-team-b all-teams BestEffortFIFO 0 4
Pedir emprestado cota não utilizada com coortes
As ClusterQueues podem não estar com capacidade total o tempo todo. O uso de cotas não é maximizado quando as cargas de trabalho não são distribuídas uniformemente entre os ClusterQueues. Se ClusterQueues compartilharem a mesma coorte entre si, elas poderão pegar emprestado cotas de outras ClusterQueues para maximizar a utilização da cota.
Quando houver jobs enfileirados para os ClusterQueues
cq-team-a
ecq-team-b
, interrompa o script do namespaceteam-b
pressionandoCTRL+c
no terminal correspondente.Depois que todos os jobs pendentes do namespace
team-b
forem processados, os jobs do namespaceteam-a
poderão usar os recursos disponíveis emcq-team-b
:kubectl describe clusterqueue cq-team-a
Como
cq-team-a
ecq-team-b
compartilham a mesma coorte chamadaall-teams
, essas ClusterQueues podem compartilhar 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 namespace
team-b
../create_jobs.sh job-team-b.yaml 3
Observe como os recursos emprestados de
cq-team-a
retornam a0
, enquanto os recursos decq-team-b
são usados para as 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
Aumentar a cota com VMs do Spot
Quando a cota precisar ser aumentada temporariamente, por exemplo, para atender à alta demanda em cargas de trabalho pendentes, é possível configurar o Kueue para acomodar a demanda adicionando mais ClusterQueues à coorte. ClusterQueues com recursos não utilizados podem compartilhá-los com outras ClusterQueues que pertencem à mesma coorte.
No início do tutorial, você criou um pool de nós chamado spot
usando VMs do Spot e um ResourceFlavor chamado spot
com o rótulo definido como cloud.google.com/gke-provisioning: spot
. Crie um ClusterQueue para usar este pool de nós e o ResourceFlavor que o representa:
Crie um novo ClusterQueue chamado
cq-spot
com a coorte definida comoall-teams
:Como essa ClusterQueue compartilha a mesma coorte com
cq-team-a
ecq-team-b
, acq-team-a
e acq-team-b
podem receber recursos de até 15 solicitações de CPU e 15 Gi de memória.kubectl apply -f cq-spot.yaml
No Prometheus, observe como as cargas de trabalho admitidas aumentam para
cq-team-a
ecq-team-b
graças à cota adicionada porcq-spot
que compartilha a mesma coorte. Ou com este comando:watch -n 2 kubectl get clusterqueues -o wide
No Prometheus, observe o número de nós no cluster. Ou com este comando:
watch -n 2 kubectl get nodes -o wide
Interrompa os dois scripts pressionando
CTRL+c
para os namespacesteam-a
eteam-b
.
Limpar
Para evitar cobranças na sua conta do Google Cloud pelos recursos usados no tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.
Excluir o projeto
- 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.
Excluir o recurso individual
Excluir o sistema de cotas do 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
Excluir o manifesto do Kueue:
VERSION=VERSION kubectl delete -f \ https://github.com/kubernetes-sigs/kueue/releases/download/$VERSION/manifests.yaml
Exclua o cluster:
gcloud container clusters delete kueue-cohort --region=COMPUTE_REGION
A seguir
Saiba mais sobre Implantar um sistema em lote usando o Kueue.
Saiba mais sobre os jobs no GKE.