O agendamento personalizado por prioridade de recursos elásticos permite definir a ordem em que os pods são agendados entre diferentes tipos de recursos e pools de nós. Crie uma ResourcePolicy para estabelecer essa ordem: durante o scale-out, os pods são agendados nas unidades de recurso na sequência definida; durante o scale-in, a remoção ocorre na ordem inversa.
Não use rótulos reservados pelo sistema, como alibabacloud.com/compute-class ou alibabacloud.com/compute-qos, nos seletores de rótulo da carga de trabalho (por exemplo, no campo spec.selector.matchLabels de um Deployment). O sistema pode modificar esses rótulos durante o agendamento por prioridade, causando reconstruções frequentes de pods e afetando a estabilidade.
Pré-requisitos
Verifique se você tem:
Um cluster gerenciado ACK Pro edition, versão 1.20.11 ou posterior (Atualizar manualmente um cluster).
-
Uma versão do kube-scheduler compatível com a versão do seu cluster ACK (kube-scheduler).
Versão do ACK
Versão do Scheduler
1.20
v1.20.4-ack-7.0 ou posterior
1.22
v1.22.15-ack-2.0 ou posterior
1,24 ou posterior
Todas as versões suportadas
(Obrigatório para recursos ECI) O componente ack-virtual-node está implantado no seu cluster (Usar ECI no ACK).
Observações de uso
Ordenação de melhor esforço: Este recurso utiliza uma política BestEffort. O scale-in de pods não segue estritamente a ordem inversa do agendamento em todos os casos.
A partir do scheduler v1.x.x-aliyun-6.4, o padrão de
ignorePreviousPodmudou parafalsee o deignoreTerminatingPodparatrue. Objetos ResourcePolicy existentes e atualizações subsequentes não são afetados.Este recurso entra em conflito com pod-deletion-cost e não pode ser usado simultaneamente.
Não é possível utilizar este recurso com o agendamento elástico de Elastic Container Instance (ECS) via ElasticResource (Usar ElasticResource para agendamento elástico de pods ECI).
O campo
maxestá disponível apenas em clusters da versão 1.22 ou posterior com scheduler versão 5,0 ou superior.Quando utilizado com pools de nós elásticos, este recurso pode fazer com que os pools criem nós inválidos. Para evitar isso, inclua o pool de nós elástico em uma unidade e não defina
maxpara essa unidade.Se a versão do seu scheduler for anterior à 5,0 ou a versão do seu cluster for 1.20 ou anterior, os pods existentes antes da criação da ResourcePolicy serão os primeiros a sofrer scale-in.
Caso a versão do seu scheduler seja anterior à 6,1 ou a versão do seu cluster seja 1.20 ou anterior, não modifique uma ResourcePolicy enquanto seus pods associados não estiverem completamente excluídos.
Ao usar auto-scaling, combine este recurso com elasticidade instantânea. Caso contrário, o Cluster Autoscaler poderá acionar o dimensionamento incorreto do pool de nós.
Criar uma ResourcePolicy
Defina uma ResourcePolicy com esta estrutura YAML:
apiVersion: scheduling.alibabacloud.com/v1alpha1
kind: ResourcePolicy
metadata:
name: test
namespace: default
spec:
selector:
key1: value1
strategy: prefer
units:
- nodeSelector:
unit: first
podLabels:
key1: value1
podAnnotations:
key1: value1
resource: ecs
- nodeSelector:
unit: second
max: 10
resource: ecs
- resource: eci
# Optional advanced configuration
preemptPolicy: AfterAllUnits
ignorePreviousPod: false
ignoreTerminatingPod: true
matchLabelKeys:
- pod-template-hash
whenTryNextUnits:
policy: TimeoutOrExceedMax
timeout: 1m
Campos spec
|
Campo |
Descrição |
|
|
Seleciona pods com rótulos correspondentes no mesmo namespace. Se estiver vazio, corresponde a todos os pods. |
|
|
Estratégia de agendamento. Apenas |
|
|
Lista ordenada de unidades de agendamento. O scale-out segue a ordem da lista; o scale-in a inverte. |
Campos units
|
Campo |
Descrição |
|
|
Tipo de recurso. Valores válidos: |
|
|
Seleciona nós nesta unidade por rótulo. |
|
|
Número máximo de réplicas de pods para esta unidade. Disponível no scheduler 5.0+. |
|
|
Recursos máximos para pods nesta unidade. Disponível no scheduler 6.9.5+. |
|
|
Rótulos adicionados aos pods agendados nesta unidade. Apenas pods com esses rótulos são contabilizados para esta unidade. |
|
|
Anotações adicionadas aos pods agendados nesta unidade. Apenas pods com essas anotações são contabilizados para esta unidade. |
O tipo de recursoelasticestá sendo descontinuado. Utilize pools de nós com auto-scaling definindok8s.aliyun.com/resource-policy-wait-for-ecs-scaling: "true"empodLabels.
O tipoacsadiciona os rótulosalibabacloud.com/compute-class: defaultealibabacloud.com/compute-class: general-purposeaos pods por padrão. Substitua-os especificando valores diferentes empodLabels. Sealpha.alibabacloud.com/compute-qos-strategyfor especificado empodAnnotations, o rótuloalibabacloud.com/compute-class: defaultnão será adicionado.
Os tiposacseeciadicionam tolerâncias para taints de nós virtuais por padrão. Essas tolerâncias são adicionadas internamente — elas não aparecem na especificação do pod, e os pods podem ser agendados em nós virtuais sem configuração adicional de tolerância.
Em versões do scheduler anteriores à 6.8.3, não é possível usar múltiplas unidades acs simultaneamente.
Se ospodLabelsde uma unidade incluíremk8s.aliyun.com/resource-policy-wait-for-ecs-scaling: "true", ou se a contagem de pods estiver abaixo demax, o scheduler mantém o pod na unidade atual até que uma condição seja atendida. Defina a duração da espera emwhenTryNextUnits. O rótulok8s.aliyun.com/resource-policy-wait-for-ecs-scaling: "true"não é aplicado ao pod e não é necessário para a contagem de pods.
Campos de configuração avançada
|
Campo |
Disponível a partir de |
Descrição |
|
|
Scheduler v6.1 |
Controla quando a preempção é tentada entre unidades. |
|
|
Scheduler v6.1 |
Quando |
|
|
Scheduler v6.1 |
Quando |
|
|
Scheduler v6.2 |
Agrupa pods por valores de rótulo e aplica |
|
|
Cluster 1.24+, scheduler 6.4+ |
Define quando um pod passa para a próxima unidade (Políticas whenTryNextUnits). |
Políticas whenTryNextUnits
|
Política |
Passa para a próxima unidade quando... |
Mais indicado para |
|
|
A unidade atual fica sem recursos ou a contagem de pods atinge |
Casos de uso mais gerais |
|
|
|
Priorizar o auto-scaling de pools de nós em vez de ECI |
|
|
(1) |
Scale-out de pool de nós com fallback para ECI após timeout |
|
|
Os recursos são insuficientes (ou |
Rolling updates — evita que novos pods transbordem para a próxima unidade enquanto pods antigos terminam |
timeout aplica-se apenas quando policy é TimeoutOrExceedMax. Padrão: 15 minutos. Não suportado para unidades ACS (limitado apenas por max).
Se o pool de nós com auto-scaling não conseguir criar nós por um longo período, ExceedMax pode deixar pods em Pending indefinidamente. O Cluster Autoscaler atualmente não respeita o limite max na ResourcePolicy, portanto, o número real de instâncias criadas pode exceder max. Isso será corrigido em uma versão futura.
Com TimeoutOrExceedMax, se um nó for criado durante o período de timeout mas ainda não estiver Ready, e o pod não tolerar o taint NotReady, o pod ainda será agendado no ECI.
Exemplos de cenários
Os resultados são de melhor esforço — a remoção durante o scale-in pode não reverter estritamente a ordem de agendamento.
Priorizar um pool de nós sobre outro
Objetivo: Implantar um Deployment em dois pools de nós — Pool A primeiro, Pool B como transbordamento. Durante o scale-in, remova os pods do Pool B primeiro.
Neste exemplo, os nós cn-beijing.10.0.3.137 e cn-beijing.10.0.3.138 pertencem ao Pool A, e cn-beijing.10.0.6.47 e cn-beijing.10.0.6.46 pertencem ao Pool B. Todos os nós possuem 2 vCPUs e 4 GB de memória.
-
Crie uma ResourcePolicy que defina a ordem de agendamento dos pools de nós. Substitua os valores de
nodepool-idpelos IDs reais dos seus pools de nós na página Node Management > Node Pools (Criar e gerenciar um pool de nós).apiVersion: scheduling.alibabacloud.com/v1alpha1 kind: ResourcePolicy metadata: name: nginx namespace: default spec: selector: app: nginx # Must match the pod label in the Deployment below strategy: prefer units: - resource: ecs nodeSelector: alibabacloud.com/nodepool-id: np7ec79f2235954e879de07b780058**** - resource: ecs nodeSelector: alibabacloud.com/nodepool-id: npab2df797738644e3a7b7cbf532bb**** -
Crie um Deployment. O rótulo do pod
app: nginxdeve corresponder aoselectorna ResourcePolicy.apiVersion: apps/v1 kind: Deployment metadata: name: nginx labels: app: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: name: nginx labels: app: nginx # Must match the ResourcePolicy selector spec: containers: - name: nginx image: nginx resources: limits: cpu: 2 requests: cpu: 2 -
Aplique o Deployment e verifique a alocação dos pods.
-
Aplique os arquivos YAML.
kubectl apply -f nginx.yamlSaída esperada:
deployment.apps/nginx created -
Verifique em quais nós os pods foram agendados.
kubectl get pods -o wideSaída esperada:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-9cdf7bbf9-b**** 1/1 Running 0 17s 172.29.112.216 cn-beijing.10.0.3.137 <none> <none> nginx-9cdf7bbf9-k**** 1/1 Running 0 17s 172.29.113.24 cn-beijing.10.0.3.138 <none> <none>Ambos os pods estão em nós do Pool A, conforme esperado.
-
-
Faça scale-out para quatro réplicas e verifique o transbordamento para o Pool B.
-
Dimensione o Deployment.
kubectl scale deployment nginx --replicas 4 -
Verifique a alocação dos pods.
kubectl get pods -o wideSaída esperada:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-9cdf7bbf9-b**** 1/1 Running 0 101s 172.29.112.216 cn-beijing.10.0.3.137 <none> <none> nginx-9cdf7bbf9-k**** 1/1 Running 0 101s 172.29.113.24 cn-beijing.10.0.3.138 <none> <none> nginx-9cdf7bbf9-m**** 1/1 Running 0 18s 172.29.113.156 cn-beijing.10.0.6.47 <none> <none> nginx-9cdf7bbf9-x**** 1/1 Running 0 18s 172.29.113.89 cn-beijing.10.0.6.46 <none> <none>Os dois novos pods transbordaram para nós do Pool B, pois o Pool A atingiu a capacidade máxima.
-
-
Faça scale-in para duas réplicas e verifique se os pods do Pool B são removidos primeiro.
-
Dimensione o Deployment.
kubectl scale deployment nginx --replicas 2 -
Verifique o status dos pods.
kubectl get pods -o wideSaída esperada:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-9cdf7bbf9-b**** 1/1 Running 0 2m41s 172.29.112.216 cn-beijing.10.0.3.137 <none> <none> nginx-9cdf7bbf9-k**** 1/1 Running 0 2m41s 172.29.113.24 cn-beijing.10.0.3.138 <none> <none> nginx-9cdf7bbf9-m**** 0/1 Terminating 0 78s 172.29.113.156 cn-beijing.10.0.6.47 <none> <none> nginx-9cdf7bbf9-x**** 0/1 Terminating 0 78s 172.29.113.89 cn-beijing.10.0.6.46 <none> <none>Os pods do Pool B são removidos primeiro — o inverso da ordem de agendamento.
-
Usar ECS por assinatura primeiro, depois ECS pay-as-you-go e, por fim, ECI
Objetivo: Minimizar custos preenchendo primeiro a capacidade de ECS por assinatura, depois ECS pay-as-you-go e, finalmente, ECI. Durante o scale-in, remova os pods na ordem inversa: ECI primeiro, depois ECS pay-as-you-go e, por último, ECS por assinatura.
Neste exemplo, todos os nós possuem 2 vCPUs e 4 GB de memória.
-
Rotule os nós por tipo de faturamento. Se você utilizar pools de nós, configure os rótulos no nível do pool de nós.
kubectl label node cn-beijing.10.0.3.137 paidtype=subscription kubectl label node cn-beijing.10.0.3.138 paidtype=subscription kubectl label node cn-beijing.10.0.6.46 paidtype=pay-as-you-go kubectl label node cn-beijing.10.0.6.47 paidtype=pay-as-you-go -
Crie uma ResourcePolicy que ordene as unidades por tipo de faturamento.
apiVersion: scheduling.alibabacloud.com/v1alpha1 kind: ResourcePolicy metadata: name: nginx namespace: default spec: selector: app: nginx # Must match the pod label in the Deployment below strategy: prefer units: - resource: ecs nodeSelector: paidtype: subscription - resource: ecs nodeSelector: paidtype: pay-as-you-go - resource: eci -
Crie um Deployment com duas réplicas.
apiVersion: apps/v1 kind: Deployment metadata: name: nginx labels: app: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: name: nginx labels: app: nginx # Must match the ResourcePolicy selector spec: containers: - name: nginx image: nginx resources: limits: cpu: 2 requests: cpu: 2 -
Aplique e verifique a alocação inicial em nós por assinatura.
-
Aplique os arquivos YAML.
kubectl apply -f nginx.yaml -
Verifique a alocação dos pods.
kubectl get pods -o wideSaída esperada:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-9cdf7bbf9-b**** 1/1 Running 0 66s 172.29.112.215 cn-beijing.10.0.3.137 <none> <none> nginx-9cdf7bbf9-r**** 1/1 Running 0 66s 172.29.113.23 cn-beijing.10.0.3.138 <none> <none>Ambos os pods estão em nós por assinatura.
-
-
Faça scale-out para verificar o transbordamento para ECS pay-as-you-go e, em seguida, ECI.
-
Dimensione para quatro réplicas e verifique a alocação dos pods.
kubectl scale deployment nginx --replicas 4kubectl get pods -o wideSaída esperada:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-9cdf7bbf9-4**** 1/1 Running 0 16s 172.29.113.155 cn-beijing.10.0.6.47 <none> <none> nginx-9cdf7bbf9-b**** 1/1 Running 0 3m48s 172.29.112.215 cn-beijing.10.0.3.137 <none> <none> nginx-9cdf7bbf9-f**** 1/1 Running 0 16s 172.29.113.88 cn-beijing.10.0.6.46 <none> <none> nginx-9cdf7bbf9-r**** 1/1 Running 0 3m48s 172.29.113.23 cn-beijing.10.0.3.138 <none> <none>Os pods excedentes foram agendados em nós pay-as-you-go.
-
Dimensione para seis réplicas e verifique a alocação dos pods.
kubectl scale deployment nginx --replicas 6kubectl get pods -o wideSaída esperada:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-9cdf7bbf9-4**** 1/1 Running 0 3m10s 172.29.113.155 cn-beijing.10.0.6.47 <none> <none> nginx-9cdf7bbf9-b**** 1/1 Running 0 6m42s 172.29.112.215 cn-beijing.10.0.3.137 <none> <none> nginx-9cdf7bbf9-f**** 1/1 Running 0 3m10s 172.29.113.88 cn-beijing.10.0.6.46 <none> <none> nginx-9cdf7bbf9-r**** 1/1 Running 0 6m42s 172.29.113.23 cn-beijing.10.0.3.138 <none> <none> nginx-9cdf7bbf9-s**** 1/1 Running 0 36s 10.0.6.68 virtual-kubelet-cn-beijing-j <none> <none> nginx-9cdf7bbf9-v**** 1/1 Running 0 36s 10.0.6.67 virtual-kubelet-cn-beijing-j <none> <none>Com toda a capacidade ECS esgotada, os pods restantes são agendados no ECI (nós virtual-kubelet).
-
-
Faça scale-in para verificar a ordem inversa de remoção.
-
Dimensione para quatro réplicas. Os pods ECI são removidos primeiro.
kubectl scale deployment nginx --replicas 4kubectl get pods -o wideSaída esperada:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-9cdf7bbf9-4**** 1/1 Running 0 4m59s 172.29.113.155 cn-beijing.10.0.6.47 <none> <none> nginx-9cdf7bbf9-b**** 1/1 Running 0 8m31s 172.29.112.215 cn-beijing.10.0.3.137 <none> <none> nginx-9cdf7bbf9-f**** 1/1 Running 0 4m59s 172.29.113.88 cn-beijing.10.0.6.46 <none> <none> nginx-9cdf7bbf9-r**** 1/1 Running 0 8m31s 172.29.113.23 cn-beijing.10.0.3.138 <none> <none> nginx-9cdf7bbf9-s**** 1/1 Terminating 0 2m25s 10.0.6.68 virtual-kubelet-cn-beijing-j <none> <none> nginx-9cdf7bbf9-v**** 1/1 Terminating 0 2m25s 10.0.6.67 virtual-kubelet-cn-beijing-j <none> <none>Os pods ECI são removidos primeiro.
-
Dimensione para duas réplicas. Os pods ECS pay-as-you-go são removidos em seguida.
kubectl scale deployment nginx --replicas 2kubectl get pods -o wideSaída esperada:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-9cdf7bbf9-4**** 0/1 Terminating 0 6m43s 172.29.113.155 cn-beijing.10.0.6.47 <none> <none> nginx-9cdf7bbf9-b**** 1/1 Running 0 10m 172.29.112.215 cn-beijing.10.0.3.137 <none> <none> nginx-9cdf7bbf9-f**** 0/1 Terminating 0 6m43s 172.29.113.88 cn-beijing.10.0.6.46 <none> <none> nginx-9cdf7bbf9-r**** 1/1 Running 0 10m 172.29.113.23 cn-beijing.10.0.3.138 <none> <none> -
Após a conclusão do encerramento, apenas os pods ECS por assinatura permanecem.
kubectl get pods -o wideSaída esperada:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-9cdf7bbf9-b**** 1/1 Running 0 11m 172.29.112.215 cn-beijing.10.0.3.137 <none> <none> nginx-9cdf7bbf9-r**** 1/1 Running 0 11m 172.29.113.23 cn-beijing.10.0.3.138 <none> <none>
-
Solução de problemas
Pods presos em Pending após aplicar uma ResourcePolicy
O scheduler pode não estar associando a ResourcePolicy aos pods corretos. Verifique se o selector corresponde exatamente aos rótulos dos pods da sua carga de trabalho. Se o seletor usar um rótulo reservado pelo sistema (como alibabacloud.com/compute-class), o sistema poderá modificá-lo, quebrando a associação.
Confirme também se a versão do seu kube-scheduler atende ao requisito mínimo para a versão do seu cluster (consulte Pré-requisitos).
O scale-in não segue a ordem inversa esperada
Este recurso opera em modo de melhor esforço. A remoção estrita em ordem inversa não é garantida — por exemplo, quando a preempção está ativa ou quando vários pods se tornam elegíveis para remoção simultaneamente.
Se você precisar de uma ordenação mais rigorosa, verifique a configuração whenTryNextUnits.policy e considere LackResourceAndNoTerminating para cenários de rolling update.
Conflito entre ResourcePolicy e pod-deletion-cost
Se anotações pod-deletion-cost estiverem configuradas em pods na mesma carga de trabalho, os dois recursos entrarão em conflito. Remova as anotações pod-deletion-cost antes de aplicar uma ResourcePolicy.
Pool de nós cria nós inesperados ao usar pools de nós elásticos
Quando um pool de nós com auto-scaling está em uma unidade com max definido, o Cluster Autoscaler pode criar mais nós do que o valor de max porque ele não lê o limite max da ResourcePolicy. Para evitar isso, inclua o pool de nós elástico em uma unidade e não defina max para essa unidade.
Próximos passos
Para usar apenas ECS ou ECI, ou solicitar ECI quando o ECS for insuficiente, configure tolerâncias e afinidade de nó (Especificar alocação de recursos para ECS e ECI).
No cluster gerenciado ACK Pro edition, implemente discretização baseada em zona e agendamento por afinidade para pods ECI.