Todos os produtos
Search
Central de documentação

Container Service for Kubernetes:Configure priority-based scheduling for elastic resources

Última atualização: Jun 27, 2026

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.

Aviso

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 ignorePreviousPod mudou para false e o de ignoreTerminatingPod para true. 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 max está 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 max para 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

selector

Seleciona pods com rótulos correspondentes no mesmo namespace. Se estiver vazio, corresponde a todos os pods.

strategy

Estratégia de agendamento. Apenas prefer é suportado.

units

Lista ordenada de unidades de agendamento. O scale-out segue a ordem da lista; o scale-in a inverte.

Campos units

Campo

Descrição

resource

Tipo de recurso. Valores válidos: ecs, eci, elastic (clusters 1.24+ com scheduler 6.4.3+), acs (clusters 1.26+ com scheduler 6.7.1+).

nodeSelector

Seleciona nós nesta unidade por rótulo.

max

Número máximo de réplicas de pods para esta unidade. Disponível no scheduler 5.0+.

maxResources

Recursos máximos para pods nesta unidade. Disponível no scheduler 6.9.5+.

podLabels

Rótulos adicionados aos pods agendados nesta unidade. Apenas pods com esses rótulos são contabilizados para esta unidade.

podAnnotations

Anotações adicionadas aos pods agendados nesta unidade. Apenas pods com essas anotações são contabilizados para esta unidade.

O tipo de recurso elastic está sendo descontinuado. Utilize pools de nós com auto-scaling definindo k8s.aliyun.com/resource-policy-wait-for-ecs-scaling: "true" em podLabels .
O tipo acs adiciona os rótulos alibabacloud.com/compute-class: default e alibabacloud.com/compute-class: general-purpose aos pods por padrão. Substitua-os especificando valores diferentes em podLabels . Se alpha.alibabacloud.com/compute-qos-strategy for especificado em podAnnotations , o rótulo alibabacloud.com/compute-class: default não será adicionado.
Os tipos acs e eci adicionam 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.
Importante

Em versões do scheduler anteriores à 6.8.3, não é possível usar múltiplas unidades acs simultaneamente.

Se os podLabels de uma unidade incluírem k8s.aliyun.com/resource-policy-wait-for-ecs-scaling: "true" , ou se a contagem de pods estiver abaixo de max , o scheduler mantém o pod na unidade atual até que uma condição seja atendida. Defina a duração da espera em whenTryNextUnits . O rótulo k8s.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

preemptPolicy

Scheduler v6.1

Controla quando a preempção é tentada entre unidades. BeforeNextUnit: tenta preempção sempre que uma unidade falhar. AfterAllUnits (padrão): tenta preempção apenas após todas as unidades falharem. Não aplicável a ACS (Ativar preempção).

ignorePreviousPod

Scheduler v6.1

Quando true, pods criados antes da ResourcePolicy são excluídos da contagem de pods. Deve ser usado com max.

ignoreTerminatingPod

Scheduler v6.1

Quando true, pods no estado Terminating são excluídos da contagem de pods. Deve ser usado com max.

matchLabelKeys

Scheduler v6.2

Agrupa pods por valores de rótulo e aplica max por grupo. Pods sem um rótulo declarado são rejeitados. Deve ser usado com max.

whenTryNextUnits

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

LackResourceOrExceedMax (padrão)

A unidade atual fica sem recursos ou a contagem de pods atinge max

Casos de uso mais gerais

ExceedMax

max e maxResources não estão definidos, ou a contagem de pods atinge max, ou adicionar o pod atual excederia maxResources

Priorizar o auto-scaling de pools de nós em vez de ECI

TimeoutOrExceedMax

(1) max está definido e a contagem de pods está abaixo de max, ou maxResources está definido e o uso atual mais os recursos do pod atual estão abaixo de maxResources; ou (2) max não está definido e podLabels contêm k8s.aliyun.com/resource-policy-wait-for-ecs-scaling: "true" — em ambos os casos, se a unidade tiver recursos insuficientes, o pod aguarda até timeout antes de prosseguir

Scale-out de pool de nós com fallback para ECI após timeout

LackResourceAndNoTerminating

Os recursos são insuficientes (ou max é atingido) e nenhum pod na unidade atual está em Terminating

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).

Importante

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.

Importante

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.

  1. Crie uma ResourcePolicy que defina a ordem de agendamento dos pools de nós. Substitua os valores de nodepool-id pelos 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****
  2. Crie um Deployment. O rótulo do pod app: nginx deve corresponder ao selector na 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
  3. Aplique o Deployment e verifique a alocação dos pods.

    1. Aplique os arquivos YAML.

      kubectl apply -f nginx.yaml

      Saída esperada:

      deployment.apps/nginx created
    2. Verifique em quais nós os pods foram agendados.

      kubectl get pods -o wide

      Saí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.

  4. Faça scale-out para quatro réplicas e verifique o transbordamento para o Pool B.

    1. Dimensione o Deployment.

      kubectl scale deployment nginx --replicas 4
    2. Verifique a alocação dos pods.

      kubectl get pods -o wide

      Saí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.

  5. Faça scale-in para duas réplicas e verifique se os pods do Pool B são removidos primeiro.

    1. Dimensione o Deployment.

      kubectl scale deployment nginx --replicas 2
    2. Verifique o status dos pods.

      kubectl get pods -o wide

      Saí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.

  1. 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
  2. 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
  3. 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
  4. Aplique e verifique a alocação inicial em nós por assinatura.

    1. Aplique os arquivos YAML.

      kubectl apply -f nginx.yaml
    2. Verifique a alocação dos pods.

      kubectl get pods -o wide

      Saí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.

  5. Faça scale-out para verificar o transbordamento para ECS pay-as-you-go e, em seguida, ECI.

    1. Dimensione para quatro réplicas e verifique a alocação dos pods.

      kubectl scale deployment nginx --replicas 4
      kubectl get pods -o wide

      Saí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.

    2. Dimensione para seis réplicas e verifique a alocação dos pods.

      kubectl scale deployment nginx --replicas 6
      kubectl get pods -o wide

      Saí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).

  6. Faça scale-in para verificar a ordem inversa de remoção.

    1. Dimensione para quatro réplicas. Os pods ECI são removidos primeiro.

      kubectl scale deployment nginx --replicas 4
      kubectl get pods -o wide

      Saí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.

    2. Dimensione para duas réplicas. Os pods ECS pay-as-you-go são removidos em seguida.

      kubectl scale deployment nginx --replicas 2
      kubectl get pods -o wide

      Saí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>
    3. Após a conclusão do encerramento, apenas os pods ECS por assinatura permanecem.

      kubectl get pods -o wide

      Saí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

Referências