Por padrão, o agendamento de pods considera os recursos solicitados, e não a carga real dos nós. Ative o agendamento com base na carga em um cluster ACK managed Pro para direcionar os pods a nós com menor carga efetiva. Isso equilibra a utilização e reduz o risco de falhas causadas pela sobrecarga de um único nó.
Como funciona o agendamento com base na carga
O agendamento com base na carga é um plugin que o agendador do Container Service for Kubernetes (ACK) implementa sobre o Kubernetes Scheduling Framework. A política nativa do Kubernetes posiciona os pods principalmente com base na alocação de recursos. Já o agendador do ACK detecta a carga real de recursos de cada nó: ele consulta estatísticas históricas de carga, estima a demanda do pod a ser agendado e o posiciona no nó com menor carga. Essa abordagem equilibra as cargas entre os nós e ajuda a prevenir falhas em aplicações ou nós decorrentes da sobrecarga isolada de um único nó.
Esse recurso exige tanto o componente kube-scheduler quanto o add-on ack-koordinator. O add-on ack-koordinator coleta e relata a utilização de recursos dos nós, enquanto o agendador do ACK utiliza esses dados para pontuar e classificar os nós, priorizando aqueles com cargas mais baixas. Para obter detalhes sobre o design do add-on, consulte ack-koordinator architecture.
Na figura a seguir, "Requested" representa a quantidade de recursos solicitados e "Usage" indica a quantidade realmente utilizada. Apenas os recursos em uso contam como carga efetiva. Considerando condições idênticas entre os nós, o agendador do ACK atribui o novo pod ao Nó B, pois este apresenta a menor carga.

A utilização dos nós varia dinamicamente ao longo do tempo, influenciada pelo ambiente do cluster, tráfego das cargas de trabalho e volume de requisições. Para minimizar o risco de desequilíbrio após o agendamento dos pods, o add-on ack-koordinator também oferece funcionalidade de desescalonamento. Utilize o agendamento com base na carga em conjunto com use hotspot-aware descheduling to balance node loads para manter o equilíbrio das cargas nos nós de forma contínua.
Como a carga do nó é medida
As estatísticas de carga podem ser agregadas de diversas formas, incluindo médias e percentis. Por padrão, o agendador do ACK utiliza a média dos últimos 5 minutos. Para alterar o tipo de agregação, defina o parâmetro loadAwareAggregatedUsageAggragationType. Para mais detalhes, consulte Custom kube-scheduler parameters.
No caso da memória, os dados de uso excluem o page cache, já que o sistema operacional pode recuperar essa área. A utilização retornada pelo comando kubectl top node inclui o page cache. Para verificar o uso real de memória de um nó, consulte Configure Managed Service for Prometheus.
Políticas de agendamento
O agendamento com base na carga oferece as políticas descritas abaixo. Ambas utilizam as estatísticas agregadas de carga dos nós mencionadas na seção anterior.
|
Política |
Descrição |
|
Filtragem de nós |
Filtra os nós candidatos com base na carga real. Se a carga efetiva de um nó ultrapassar o limiar configurado, o agendador não posicionará pods nesse nó. A filtragem vem desativada por padrão. Para ativá-la, defina o parâmetro |
|
Pontuação de nós |
Avalia os nós candidatos nas dimensões de CPU e memória, selecionando primeiro aqueles com maiores pontuações. O cálculo segue a fórmula |
Pré-requisitos
Tipo de cluster — Apenas clusters ACK managed Pro são suportados. Para o procedimento, consulte Create an ACK Pro cluster.
Add-on ack-koordinator — Instale a versão 1.1.1-ack.1 ou superior do add-on ack-koordinator. Para o procedimento de instalação, consulte ack-koordinator (FKA ack-slo-manager).
Versão do agendador ACK — O agendador do ACK deve atender aos requisitos de versão correspondentes à versão do Kubernetes do seu cluster, conforme listado na tabela a seguir.
|
Versão do Kubernetes |
Versão necessária do agendador ACK |
|
1,26 e posteriores |
Todas as versões |
|
1,24 |
v1.24.6-ack-4.0 ou posterior |
|
1,22 |
v1.22.15-ack-4.0 ou posterior |
Essas versões são necessárias para configurar o agendamento com base na carga por meio dos parâmetros do kube-scheduler. Algumas versões anteriores do agendador suportam apenas o protocolo de anotação de pods. Para a matriz completa de compatibilidade, consulte FAQ.
Faturamento
A instalação e o uso do add-on ack-koordinator são gratuitos. No entanto, custos podem ser gerados nos seguintes cenários:
Recursos de nós de trabalho — O ack-koordinator é um add-on não gerenciado que consome recursos dos nós de trabalho após a instalação. É possível configurar solicitações de recursos para cada módulo durante a instalação.
Métricas personalizadas — Por padrão, o ack-koordinator expõe métricas de monitoramento para recursos como perfilamento de recursos e agendamento refinado no formato Prometheus. Se você selecionar Enable Prometheus monitoring metrics for ack-koordinator e utilizar o Managed Service for Prometheus, essas métricas serão faturadas como custom metrics. Os valores variam conforme fatores como tamanho do cluster e quantidade de aplicações. Antes de ativar esse recurso, consulte Billing of Prometheus instances para entender o nível gratuito e os preços das métricas personalizadas. Para monitorar e gerenciar o uso de recursos, utilize usage query.
Etapa 1: Ativar o agendamento com base na carga
O agendamento com base na carga só entra em vigor se o add-on ack-koordinator e o agendador do ACK atenderem aos requisitos de versão descritos em Prerequisites.
Faça login no console ACK. No painel de navegação à esquerda, clique em Clusters.
Na página Clusters, clique no nome do seu cluster. No painel de navegação à esquerda, clique em Components and Add-ons .
Localize o kube-scheduler e clique em Configuration.
-
Na caixa de diálogo de parâmetros do kube-scheduler, configure os parâmetros descritos na tabela a seguir e clique em OK.
A tabela abaixo descreve os principais parâmetros para o agendamento com base na carga. Para a referência completa de configurações e as versões do add-on exigidas para cada parâmetro, consulte kube-scheduler e .
Parâmetro
Tipo
Descrição
Valores válidos
Valor padrão
Exemplo
loadAwareThresholdUma lista composta pelo nome do recurso
resourceNamee pelo limiarthreshold.Limiar do tipo de recurso correspondente, utilizado pela política de filtragem de nós.
resourceName:cpuememorysão suportados.threshold: [0,100].Vazio, o que significa que a filtragem de nós está desativada.
resourceName: cpuethreshold: 80loadAwareResourceWeightUma lista composta pelo nome do recurso
resourceNamee pelo pesoresourceWeight.Peso de pontuação do tipo de recurso correspondente, utilizado pela política de pontuação de nós. Você deve selecionar Specifies whether to enable load-aware node scoring during pod scheduling.
resourceName: apenascpuememorysão suportados.resourceWeight: um inteiro no intervalo [1,100].cpu: 1ememory: 1resourceName: cpueresourceWeight: 1loadAwareAggregatedUsageAggragationTypeenum
Tipo de agregação da estatística de carga.
avg: valor médio.p50: 50º percentil (mediana).p90,p95ep99: 90º, 95º e 99º percentis.avg,p50,p90,p95ep99avgp90ImportanteSe o auto scaling de nós já estiver ativado para os nós do cluster, um limiar de filtragem com base na carga pode acionar scale-out ou scale-in inesperados. Isso ocorre porque o auto scaling de nós realiza scale-out quando há pods pendentes e scale-in com base no nível de alocação do cluster. Para usar o auto scaling de nós junto com a filtragem de nós baseada em carga, ajuste a configuração para corresponder à capacidade e utilização do seu cluster, conforme descrito em Enable node auto scaling.
No painel de navegação à esquerda, clique em Cluster Information. Na página exibida, clique na aba Basic Information e aguarde até que o cluster entre no estado Running, o que indica que o agendamento com base na carga foi ativado.
Etapa 2: Verificar o agendamento com base na carga
O exemplo a seguir utiliza um cluster com três nós, cada um com 4 núcleos e 16 GiB de memória. Primeiro, o exemplo desequilibra as cargas entre os nós e depois verifica onde os novos pods são agendados.
-
Crie um arquivo chamado stress-demo.yaml com o seguinte conteúdo.
apiVersion: apps/v1 kind: Deployment metadata: name: stress-demo namespace: default labels: app: stress-demo spec: replicas: 1 selector: matchLabels: app: stress-demo template: metadata: name: stress-demo labels: app: stress-demo spec: containers: - args: - '--vm' - '2' - '--vm-bytes' - '1600M' - '-c' - '2' - '--vm-hang' - '2' command: - stress image: polinux/stress imagePullPolicy: Always name: stress resources: limits: cpu: '2' memory: 4Gi requests: cpu: '2' memory: 4Gi restartPolicy: Always -
Execute o comando kubectl a seguir para criar o pod. Esse pod aumentará a carga do nó que o hospeda.
kubectl create -f stress-demo.yamldeployment.apps/stress-demo created -
Execute o comando kubectl a seguir para verificar o status do pod até que ele esteja em execução.
kubectl get pod -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES stress-demo-7fdd89cc6b-g**** 1/1 Running 0 82s 10.XX.XX.112 cn-beijing.10.XX.XX.112 <none> <none>O pod
stress-demo-7fdd89cc6b-g****foi agendado para o nócn-beijing.10.XX.XX.112. Aguarde cerca de 3 minutos até que o pod conclua a inicialização e a carga do nó tenha aumentado. -
Execute o comando kubectl a seguir para verificar a carga de cada nó.
kubectl top nodeNAME CPU(cores) CPU% MEMORY(bytes) MEMORY% cn-beijing.10.XX.XX.110 92m 2% 1158Mi 9% cn-beijing.10.XX.XX.111 77m 1% 1162Mi 9% cn-beijing.10.XX.XX.112 2105m 53% 3594Mi 28%O nó
cn-beijing.10.XX.XX.111apresenta a menor carga, enquanto o nócn-beijing.10.XX.XX.112tem a maior carga. As cargas entre os nós do cluster estão agora desequilibradas. -
Crie um arquivo chamado nginx-with-loadaware.yaml com o seguinte conteúdo.
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-with-loadaware namespace: default labels: app: nginx spec: replicas: 6 selector: matchLabels: app: nginx template: metadata: name: nginx labels: app: nginx spec: containers: - name: nginx image: nginx resources: limits: cpu: 500m requests: cpu: 500m -
Execute o comando kubectl a seguir para criar os pods.
kubectl create -f nginx-with-loadaware.yamldeployment/nginx-with-loadawre created -
Execute o comando kubectl a seguir para visualizar os detalhes de agendamento dos pods.
kubectl get pods | grep nginxnginx-with-loadaware-5646666d56-2**** 1/1 Running 0 18s 10.XX.XX.118 cn-beijing.10.XX.XX.110 <none> <none> nginx-with-loadaware-5646666d56-7**** 1/1 Running 0 18s 10.XX.XX.115 cn-beijing.10.XX.XX.110 <none> <none> nginx-with-loadaware-5646666d56-k**** 1/1 Running 0 18s 10.XX.XX.119 cn-beijing.10.XX.XX.110 <none> <none> nginx-with-loadaware-5646666d56-q**** 1/1 Running 0 18s 10.XX.XX.113 cn-beijing.10.XX.XX.111 <none> <none> nginx-with-loadaware-5646666d56-s**** 1/1 Running 0 18s 10.XX.XX.120 cn-beijing.10.XX.XX.111 <none> <none> nginx-with-loadaware-5646666d56-z**** 1/1 Running 0 18s 10.XX.XX.116 cn-beijing.10.XX.XX.111 <none> <none>A saída esperada mostra que, após a ativação do agendamento com base na carga, o agendador detecta as cargas dos nós e usa a estratégia de agendamento para posicionar preferencialmente os pods em nós diferentes de cn-beijing.10.XX.XX.112.
Perguntas frequentes
Por que os pods de um lote recém-criado não são todos agendados para o nó com a menor carga?
Novos pods aumentam a carga de um nó após iniciarem. Se o agendador colocasse todo um lote de novos pods no nó que atualmente tem a menor carga, esse nó poderia rapidamente se tornar um ponto crítico de carga.
Portanto, quando o plugin de agendamento com base na carga pontua os nós, ele ajusta a pontuação de um nó que hospeda novos pods cuja utilização ainda não foi relatada. Isso evita que o excesso de agendamento crie um novo ponto crítico.
Além da carga do nó, o que mais afeta o resultado do agendamento?
O agendador do Kubernetes consiste em vários plugins, e muitos deles contribuem para a pontuação dos nós durante o agendamento, como o plugin de afinidade e o plugin de distribuição de topologia. A classificação final dos nós reflete todos esses plugins, e você pode ajustar o peso de pontuação de cada plugin conforme necessário.
Após a atualização do agendador para uma nova versão, o agendamento com base na carga ainda funciona através do protocolo anterior?
A resposta depende da versão do Kubernetes do cluster. Na versão 1,22, o agendador do ACK permanece compatível com o protocolo anterior. Para a versão 1,24, o período de compatibilidade terminou em 30 de agosto de 2023. Para a versão 1,26 e posteriores, o protocolo de anotação de pods não é suportado.
Em uma versão que ainda suporta o protocolo anterior, adicione a anotação alibabacloud.com/loadAwareScheduleEnabled: "true" ao pod. Como o agendador do ACK é compatível com o protocolo anterior, você pode atualizar o agendador para a nova versão sem interrupções. Após a atualização, use Custom kube-scheduler parameters para ativar uma política de agendamento de balanceamento de carga em todo o cluster, o que reduz as alterações necessárias nas configurações dos pods.
Atualize o cluster para uma versão mais recente e use o novo método de configuração para o agendamento com base na carga. Para mais informações, consulte manually upgrade a cluster.
As tabelas a seguir descrevem o suporte ao protocolo e os requisitos de versão do add-on para cada versão:
1,26 e posteriores
|
Versão do agendador ACK |
Versão necessária do ack-koordinator (ack-slo-manager) |
Protocolo de anotação de pods |
Interruptor de parâmetros do console |
|
Todas as versões do agendador ACK |
≥1.1.1-ack.1 |
Não suportado |
Suportado |
1,24
|
Versão do agendador ACK |
Versão necessária do ack-koordinator (ack-slo-manager) |
Protocolo de anotação de pods |
Interruptor de parâmetros do console |
|
≥v1.24.6-ack-4.0 |
≥1.1.1-ack.1 |
Suportado |
Suportado |
|
≥v1.24.6-ack-3.1 e <v1.24.6-ack-4.0 |
≥0.8.0 |
Suportado |
Não suportado |
|
Versão do agendador ACK |
Versão necessária do ack-koordinator (ack-slo-manager) |
Protocolo de anotação de pods |
Interruptor de parâmetros do console |
|
≥1.22.15-ack-4.0 |
≥1.1.1-ack.1 |
Suportado |
Suportado |
|
≥1.22.15-ack-2.0 e <1.22.15-ack-4.0 |
≥0.8.0 |
Suportado |
Não suportado |
|
≥v1.20.4-ack-4.0 e ≤v1.20.4-ack-8.0, ou v1.18-ack-4.0 |
≥0.3.0 e <0.8.0 |
Suportado |
Não suportado |