Tous les produits
Search
Centre de documentation

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

Dernière mise à jour :Sep 21, 2026

L'ordonnancement prioritaire personnalisé des ressources élastiques vous permet de définir l'ordre dans lequel les pods sont planifiés sur différents types de ressources et pools de nœuds. Créez une ressource ResourcePolicy pour établir cet ordre : lors d'un scale-out, les pods sont attribués aux unités de ressources selon l'ordre défini ; lors d'un scale-in, les pods sont supprimés dans l'ordre inverse.

Avertissement

N'utilisez pas de labels réservés par le système, tels que alibabacloud.com/compute-class ou alibabacloud.com/compute-qos, dans les sélecteurs de labels de vos workloads (par exemple, le champ spec.selector.matchLabels d'un Deployment). Le système peut modifier ces labels lors de l'ordonnancement par priorité, ce qui entraîne des recréations fréquentes des pods et affecte la stabilité.

Prérequis

Assurez-vous de disposer des éléments suivants :

  • Un cluster ACK managé édition Pro, version 1.20.11 ou ultérieure (Mettre à niveau manuellement un cluster).

  • Une version de kube-scheduler compatible avec la version de votre cluster ACK (kube-scheduler).

    Version ACK Version du planificateur
    1.20 v1.20.4-ack-7.0 ou ultérieure
    1.22 v1.22.15-ack-2.0 ou ultérieure
    1,24 ou ultérieure Toutes les versions prises en charge
  • (Obligatoire pour les ressources ECI) Le module complémentaire ack-virtual-node est déployé dans votre cluster (Utiliser ECI dans ACK).

Notes d'utilisation

  • Ordre au mieux : Cette fonctionnalité utilise une politique BestEffort. La suppression des pods lors d'un scale-in ne suit pas strictement l'ordre inverse de planification dans tous les cas.

  • À partir de la version v1.x.x-aliyun-6.4 du planificateur, la valeur par défaut de ignorePreviousPod est passée à false et celle de ignoreTerminatingPod à true. Les objets ResourcePolicy existants et les mises à jour ultérieures ne sont pas affectés.

  • Cette fonctionnalité entre en conflit avec pod-deletion-cost et ne peut pas être utilisée conjointement.

  • Cette fonctionnalité ne peut pas être utilisée avec la planification élastique des Elastic Container Instance (ECI) via ElasticResource (Utiliser ElasticResource pour la planification élastique des pods ECI).

  • Le champ max est disponible uniquement dans les clusters de version 1.22 ou ultérieure avec une version du planificateur 5.0 ou ultérieure.

  • Lorsqu'elle est utilisée avec des pools de nœuds élastiques, cette fonctionnalité peut entraîner la création de nœuds invalides par les pools de nœuds. Pour éviter cela, incluez le pool de nœuds élastique dans une unité et ne définissez pas max pour cette unité.

  • Si la version de votre planificateur est antérieure à 5.0 ou si la version de votre cluster est 1,20 ou antérieure, les pods existant avant la création de la ResourcePolicy sont les premiers à faire l'objet d'un scale-in.

  • Si la version de votre planificateur est antérieure à 6.1 ou si la version de votre cluster est 1,20 ou antérieure, ne modifiez pas une ResourcePolicy tant que les pods associés ne sont pas complètement supprimés.

  • Lorsqu'elle est utilisée avec l'Auto Scaling, cette fonctionnalité doit être associée à l'élasticité instantanée. Sinon, le Cluster Autoscaler risque de déclencher un scaling incorrect du pool de nœuds.

Créer une ResourcePolicy

Définissez une ResourcePolicy avec la structure YAML suivante :

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

Champs spec

Champ Description
selector Sélectionne les pods dont les labels correspondent dans le même namespace. Si vide, tous les pods sont sélectionnés.
strategy Stratégie d'ordonnancement. Seule la valeur prefer est prise en charge.
units Liste ordonnée des unités d'ordonnancement. Le scale-out suit l'ordre de la liste ; le scale-in suit l'ordre inverse.

Champs units

Champ Description
resource Type de ressource. Valeurs valides : ecs, eci, elastic (clusters 1.24+ avec planificateur 6.4.3+), acs (clusters 1.26+ avec planificateur 6.7.1+).
nodeSelector Sélectionne les nœuds de cette unité par label.
max Nombre maximal de réplicas de pods pour cette unité. Disponible à partir de la version 5.0 du planificateur.
maxResources Ressources maximales pour les pods de cette unité. Disponible à partir de la version 6.9.5 du planificateur.
podLabels Labels ajoutés aux pods planifiés dans cette unité. Seuls les pods portant ces labels sont comptabilisés pour cette unité.
podAnnotations Annotations ajoutées aux pods planifiés dans cette unité. Seuls les pods portant ces annotations sont comptabilisés pour cette unité.
Le type de ressource elastic est obsolète. Utilisez plutôt des pools de nœuds Auto Scaling en définissant k8s.aliyun.com/resource-policy-wait-for-ecs-scaling: "true" dans podLabels .
Le type acs ajoute par défaut les labels alibabacloud.com/compute-class: default et alibabacloud.com/compute-class: general-purpose aux pods. Remplacez ces valeurs en spécifiant des valeurs différentes dans podLabels . Si alpha.alibabacloud.com/compute-qos-strategy est spécifié dans podAnnotations , le label alibabacloud.com/compute-class: default n'est pas ajouté.
Les types acs et eci ajoutent par défaut des tolérations pour les taints des nœuds virtuels. Ces tolérations sont ajoutées en interne — elles n'apparaissent pas dans la spécification du pod, et les pods peuvent être planifiés sur des nœuds virtuels sans configuration supplémentaire de tolération.
Important

Dans les versions du planificateur antérieures à 6.8.3, vous ne pouvez pas utiliser plusieurs unités acs simultanément.

Si les podLabels d'une unité incluent k8s.aliyun.com/resource-policy-wait-for-ecs-scaling: "true" , ou si le nombre de pods est inférieur à max , le planificateur maintient le pod dans l'unité actuelle jusqu'à ce qu'une condition soit remplie. Définissez la durée d'attente dans whenTryNextUnits . Le label k8s.aliyun.com/resource-policy-wait-for-ecs-scaling: "true" n'est pas appliqué au pod et n'est pas requis pour le comptage des pods.

Champs de configuration avancée

Champ Disponible à partir de Description
preemptPolicy Planificateur v6.1 Contrôle le moment où la préemption est tentée entre les unités. BeforeNextUnit : tente la préemption chaque fois qu'une unité échoue. AfterAllUnits (par défaut) : tente la préemption uniquement après l'échec de toutes les unités. Non applicable à ACS (Activer la préemption).
ignorePreviousPod Planificateur v6.1 Lorsque la valeur est true, les pods créés avant la ResourcePolicy sont exclus du comptage. Doit être utilisé avec max.
ignoreTerminatingPod Planificateur v6.1 Lorsque la valeur est true, les pods en état Terminating sont exclus du comptage. Doit être utilisé avec max.
matchLabelKeys Planificateur v6.2 Regroupe les pods par valeurs de label et applique max par groupe. Les pods auxquels il manque un label déclaré sont rejetés. Doit être utilisé avec max.
whenTryNextUnits Cluster 1.24+, planificateur 6.4+ Définit quand un pod passe à l'unité suivante (politiques whenTryNextUnits).

Politiques whenTryNextUnits

Politique Passe à l'unité suivante lorsque... Idéal pour
LackResourceOrExceedMax (par défaut) L'unité actuelle manque de ressources ou le nombre de pods atteint max La plupart des cas d'utilisation généraux
ExceedMax max et maxResources ne sont pas définis, ou le nombre de pods atteint max, ou l'ajout du pod actuel dépasserait maxResources Prioriser l'Auto Scaling des pools de nœuds par rapport à ECI
TimeoutOrExceedMax (1) max est défini et le nombre de pods est inférieur à max, ou maxResources est défini et l'utilisation actuelle plus les ressources du pod actuel sont inférieures à maxResources ; ou (2) max n'est pas défini et podLabels contient k8s.aliyun.com/resource-policy-wait-for-ecs-scaling: "true" — dans les deux cas, si l'unité manque de ressources, le pod attend jusqu'à timeout avant de passer Scale-out du pool de nœuds avec basculement vers ECI après expiration du délai
LackResourceAndNoTerminating Les ressources sont insuffisantes (ou max est atteint) et aucun pod de l'unité actuelle n'est en état Terminating Mises à jour progressives — empêche les nouveaux pods de déborder vers l'unité suivante pendant la terminaison des anciens pods

timeout s'applique uniquement lorsque policy est TimeoutOrExceedMax. Par défaut : 15 minutes. Non pris en charge pour les unités ACS (limité uniquement par max).

Important

Si le pool de nœuds Auto Scaling ne parvient pas à créer de nœuds pendant une longue période, ExceedMax peut laisser les pods en état Pending indéfiniment. Le Cluster Autoscaler ne respecte pas actuellement la limite max dans ResourcePolicy, de sorte que le nombre réel d'instances créées peut dépasser max. Ce problème sera résolu dans une prochaine version.

Important

Avec TimeoutOrExceedMax, si un nœud est créé pendant la période de délai d'attente mais n'est pas encore Ready, et si le pod ne tolère pas le taint NotReady, le pod est tout de même planifié sur ECI.

Exemples de scénarios

Les résultats sont fournis au mieux — la suppression lors du scale-in peut ne pas suivre strictement l'ordre inverse de planification.

Prioriser un pool de nœuds par rapport à un autre

Objectif : Déployer un Deployment sur deux pools de nœuds — Pool A en premier, Pool B en débordement. Lors du scale-in, supprimez d'abord les pods du Pool B.

Dans cet exemple, les nœuds cn-beijing.10.0.3.137 et cn-beijing.10.0.3.138 appartiennent au Pool A, et cn-beijing.10.0.6.47 et cn-beijing.10.0.6.46 appartiennent au Pool B. Tous les nœuds disposent de 2 vCPU et de 4 Go de mémoire.

  1. Créez une ResourcePolicy qui définit l'ordre de planification des pools de nœuds. Remplacez les valeurs nodepool-id par vos ID de pool de nœuds réels depuis la page Node Management > Node Pools (Créer et gérer un pool de nœuds).

    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. Créez un Deployment. Le label du pod app: nginx doit correspondre au selector de la 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. Appliquez le Deployment et vérifiez l'emplacement des pods.

    1. Appliquez les fichiers YAML.

      kubectl apply -f nginx.yaml

      Sortie attendue :

      deployment.apps/nginx created
    2. Vérifiez sur quels nœuds les pods sont planifiés.

      kubectl get pods -o wide

      Sortie attendue :

      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>

      Les deux pods se trouvent sur des nœuds du Pool A, comme prévu.

  4. Effectuez un scale-out vers quatre réplicas et vérifiez le débordement vers le Pool B.

    1. Mettez à l'échelle le Deployment.

      kubectl scale deployment nginx --replicas 4
    2. Vérifiez l'emplacement des pods.

      kubectl get pods -o wide

      Sortie attendue :

      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>

      Les deux nouveaux pods débordent vers les nœuds du Pool B, car le Pool A est saturé.

  5. Effectuez un scale-in vers deux réplicas et vérifiez que les pods du Pool B sont supprimés en premier.

    1. Mettez à l'échelle le Deployment.

      kubectl scale deployment nginx --replicas 2
    2. Vérifiez l'état des pods.

      kubectl get pods -o wide

      Sortie attendue :

      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>

      Les pods du Pool B sont supprimés en premier — l'inverse de l'ordre de planification.

Utiliser d'abord ECS sous abonnement, puis ECS à la demande, puis basculer sur ECI

Objectif : Minimiser les coûts en remplissant d'abord la capacité ECS sous abonnement, puis ECS à la demande, et enfin ECI. Lors du scale-in, supprimez les pods dans l'ordre inverse : ECI d'abord, puis ECS à la demande, puis ECS sous abonnement.

Dans cet exemple, tous les nœuds disposent de 2 vCPU et de 4 Go de mémoire.

  1. Ajoutez des labels aux nœuds selon leur type de facturation. Si vous utilisez des pools de nœuds, configurez les labels au niveau du pool de nœuds.

    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. Créez une ResourcePolicy qui ordonne les unités par type de facturation.

    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. Créez un Deployment avec deux 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. Appliquez et vérifiez le placement initial sur les nœuds sous abonnement.

    1. Appliquez les fichiers YAML.

      kubectl apply -f nginx.yaml
    2. Vérifiez l'emplacement des pods.

      kubectl get pods -o wide

      Sortie attendue :

      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>

      Les deux pods se trouvent sur des nœuds sous abonnement.

  5. Effectuez un scale-out pour vérifier le débordement vers ECS à la demande, puis vers ECI.

    1. Mettez à l'échelle vers quatre réplicas et vérifiez l'emplacement des pods.

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

      Sortie attendue :

      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>

      Les pods en débordement sont planifiés sur des nœuds à la demande.

    2. Mettez à l'échelle vers six réplicas et vérifiez l'emplacement des pods.

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

      Sortie attendue :

      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>

      Toute la capacité ECS étant épuisée, les pods restants sont planifiés sur ECI (nœuds virtual-kubelet).

  6. Effectuez un scale-in pour vérifier l'ordre de suppression inverse.

    1. Mettez à l'échelle vers quatre réplicas. Les pods ECI sont supprimés en premier.

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

      Sortie attendue :

      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>

      Les pods ECI sont supprimés en premier.

    2. Mettez à l'échelle vers deux réplicas. Les pods ECS à la demande sont ensuite supprimés.

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

      Sortie attendue :

      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. Une fois la terminaison terminée, seuls les pods ECS sous abonnement restent.

      kubectl get pods -o wide

      Sortie attendue :

      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>

Dépannage

Les pods restent bloqués en état Pending après l'application d'une ResourcePolicy

Le planificateur peut ne pas associer la ResourcePolicy aux bons pods. Vérifiez que le selector correspond exactement aux labels des pods de votre workload. Si le sélecteur utilise un label réservé par le système (tel que alibabacloud.com/compute-class), le système peut le modifier, rompant ainsi l'association.

Confirmez également que la version de votre kube-scheduler répond à l'exigence minimale pour la version de votre cluster (voir Prérequis).

Le scale-in ne suit pas l'ordre inverse attendu

Cette fonctionnalité fonctionne au mieux. L'ordre de suppression strictement inverse n'est pas garanti — par exemple, lorsque la préemption est active ou lorsque plusieurs pods deviennent éligibles à la suppression simultanément.

Si vous avez besoin d'un ordre plus strict, vérifiez le paramètre whenTryNextUnits.policy et envisagez d'utiliser LackResourceAndNoTerminating pour les scénarios de mise à jour progressive.

Conflit entre ResourcePolicy et pod-deletion-cost

Si des annotations pod-deletion-cost sont configurées sur les pods du même workload, les deux fonctionnalités entrent en conflit. Supprimez les annotations pod-deletion-cost avant d'appliquer une ResourcePolicy.

Le pool de nœuds crée des nœuds inattendus lorsqu'il est utilisé avec des pools de nœuds élastiques

Lorsqu'un pool de nœuds Auto Scaling se trouve dans une unité avec max défini, le Cluster Autoscaler peut créer plus de nœuds que la valeur max car il ne lit pas la limite max depuis ResourcePolicy. Pour éviter cela, incluez le pool de nœuds élastique dans une unité et ne définissez pas max pour cette unité.

Étapes suivantes

Références