L'ordonnancement par priorité personnalisé des ressources élastiques vous permet de définir l'ordre de planification des pods 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 (mise à l'échelle horizontale), les pods sont affectés aux unités de ressources selon l'ordre défini ; lors d'un scale-in (réduction), les pods sont supprimés dans l'ordre inverse.
N'utilisez pas d'étiquettes réservées par le système, telles que alibabacloud.com/compute-class ou alibabacloud.com/compute-qos, dans les sélecteurs d'étiquettes de vos charges de travail (par exemple, le champ spec.selector.matchLabels d'un Deployment). Le système risque de modifier ces étiquettes lors de l'ordonnancement par priorité, ce qui provoquerait des reconstructions fréquentes des pods et nuirait à la stabilité.
Prérequis
Assurez-vous de disposer des éléments suivants :
Un cluster managé ACK Pro Edition, version 1,20.11 ou ultérieure (Mettre à niveau un cluster manuellement).
-
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 (Pour les ressources ECI uniquement) 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é repose sur une politique BestEffort. La suppression des pods lors d'un scale-in ne suit pas strictement l'ordre inverse de l'ordonnancement dans tous les cas.
À partir de la version v1.x.x-aliyun-6.4 du planificateur, la valeur par défaut de
ignorePreviousPodest passée àfalseet celle deignoreTerminatingPodà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 avec celle-ci.
Cette fonctionnalité est incompatible avec l'ordonnancement élastique des Elastic Container Instance (ECI) via ElasticResource (Utiliser ElasticResource pour l'ordonnancement élastique des pods ECI).
Le champ
maxest disponible uniquement sur les clusters de version 1,22 ou ultérieure disposant d'une version 5.0 ou ultérieure du planificateur.Lorsqu'elle est utilisée avec des pools de nœuds élastiques, cette fonctionnalité peut entraîner la création de nœuds invalides. Pour éviter cela, incluez le pool de nœuds élastique dans une unité et ne définissez pas
maxpour 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 existants avant la création de la ResourcePolicy seront 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.
En combinaison avec l'Auto Scaling, cette fonctionnalité doit être utilisée avec l'élasticité instantanée. À défaut, le Cluster Autoscaler pourrait déclencher un scale-in ou un scale-out incorrect des pools de nœuds.
Créer une ResourcePolicy
Définissez une ResourcePolicy à l'aide de 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 étiquettes correspondent dans le même namespace. Si ce champ est vide, tous les pods sont concerné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 étiquette. |
max |
Nombre maximal de réplicas de pods pour cette unité. Disponible à partir de la version 5.0 du planificateur. |
maxResources |
Ressources maximales allouées aux pods de cette unité. Disponible à partir de la version 6.9.5 du planificateur. |
podLabels |
Étiquettes ajoutées aux pods planifiés dans cette unité. Seuls les pods portant ces étiquettes 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 ressourceelasticest obsolète. Utilisez plutôt des pools de nœuds Auto Scaling en définissantk8s.aliyun.com/resource-policy-wait-for-ecs-scaling: "true"danspodLabels.
Le typeacsajoute par défaut les étiquettesalibabacloud.com/compute-class: defaultetalibabacloud.com/compute-class: general-purposeaux pods. Vous pouvez remplacer ces valeurs en spécifiant des valeurs différentes danspodLabels. Sialpha.alibabacloud.com/compute-qos-strategyest spécifié danspodAnnotations, l'étiquettealibabacloud.com/compute-class: defaultn'est pas ajoutée.
Les typesacseteciajoutent 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.
Dans les versions du planificateur antérieures à 6.8.3, vous ne pouvez pas utiliser plusieurs unités acs simultanément.
Si lespodLabelsd'une unité incluentk8s.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 danswhenTryNextUnits. L'étiquettek8s.aliyun.com/resource-policy-wait-for-ecs-scaling: "true"n'est pas appliquée au pod et n'est pas requise 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 d'étiquette et applique max par groupe. Les pods auxquels manque une étiquette déclarée 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 le scale-out 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 à l'unité suivante |
Scale-out du pool de nœuds avec repli sur 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 basculer vers l'unité suivante pendant la suppression des anciens pods |
Le paramètre timeout s'applique uniquement lorsque policy est défini sur TimeoutOrExceedMax. Valeur par défaut : 15 minutes. Non pris en charge pour les unités ACS (limité uniquement par max).
Si le pool de nœuds Auto Scaling ne parvient pas à créer de nœuds pendant une période prolongée, la politique ExceedMax peut laisser les pods en état Pending indéfiniment. Le Cluster Autoscaler ne respecte pas actuellement la limite max définie dans la 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.
Avec la politique TimeoutOrExceedMax, si un nœud est créé pendant la période de délai d'attente mais n'est pas encore Ready, et que le pod ne tolère pas le taint NotReady, le pod sera tout de même planifié sur ECI.
Exemples de scénarios
Les résultats sont fournis au mieux : la suppression lors d'un scale-in peut ne pas suivre strictement l'ordre inverse de l'ordonnancement.
Prioriser un pool de nœuds par rapport à un autre
Objectif : Déployer un Deployment sur deux pools de nœuds — Pool A en priorité, Pool B en débordement. Lors d'un 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, tandis que 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.
-
Créez une ResourcePolicy définissant l'ordre d'ordonnancement des pools de nœuds. Remplacez les valeurs
nodepool-idpar les ID réels de vos pools de nœuds, disponibles sur 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**** -
Créez un Deployment. L'étiquette du pod
app: nginxdoit correspondre auselectorde 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 -
Appliquez le Deployment et vérifiez le placement des pods.
-
Appliquez les fichiers YAML.
kubectl apply -f nginx.yamlRésultat attendu :
deployment.apps/nginx created -
Vérifiez sur quels nœuds les pods sont planifiés.
kubectl get pods -o wideRésultat attendu :
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>Comme prévu, les deux pods se trouvent sur des nœuds du Pool A.
-
-
Effectuez un scale-out vers quatre réplicas et vérifiez le débordement vers le Pool B.
-
Mettez à l'échelle le Deployment.
kubectl scale deployment nginx --replicas 4 -
Vérifiez le placement des pods.
kubectl get pods -o wideRésultat attendu :
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 sur les nœuds du Pool B, car le Pool A a atteint sa capacité maximale.
-
-
Effectuez un scale-in vers deux réplicas et vérifiez que les pods du Pool B sont supprimés en premier.
-
Mettez à l'échelle le Deployment.
kubectl scale deployment nginx --replicas 2 -
Vérifiez l'état des pods.
kubectl get pods -o wideRésultat attendu :
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, conformément à l'ordre inverse de l'ordonnancement.
-
Utiliser d'abord ECS Subscription, puis ECS Pay-As-You-Go, avec repli sur ECI
Objectif : Minimiser les coûts en remplissant d'abord la capacité ECS Subscription, puis ECS Pay-As-You-Go, et enfin ECI. Lors d'un scale-in, supprimez les pods dans l'ordre inverse : ECI d'abord, puis ECS Pay-As-You-Go, puis ECS Subscription.
Dans cet exemple, tous les nœuds disposent de 2 vCPU et de 4 Go de mémoire.
-
Étiquetez les nœuds par type de facturation. Si vous utilisez des pools de nœuds, configurez les étiquettes 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 -
Créez une ResourcePolicy ordonnant 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 -
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 -
Appliquez la configuration et vérifiez le placement initial sur les nœuds Subscription.
-
Appliquez les fichiers YAML.
kubectl apply -f nginx.yaml -
Vérifiez le placement des pods.
kubectl get pods -o wideRésultat attendu :
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 Subscription.
-
-
Effectuez un scale-out pour vérifier le débordement vers ECS Pay-As-You-Go, puis vers ECI.
-
Mettez à l'échelle vers quatre réplicas et vérifiez le placement des pods.
kubectl scale deployment nginx --replicas 4kubectl get pods -o wideRésultat attendu :
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 Pay-As-You-Go.
-
Mettez à l'échelle vers six réplicas et vérifiez le placement des pods.
kubectl scale deployment nginx --replicas 6kubectl get pods -o wideRésultat attendu :
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).
-
-
Effectuez un scale-in pour vérifier l'ordre de suppression inverse.
-
Mettez à l'échelle vers quatre réplicas. Les pods ECI sont supprimés en premier.
kubectl scale deployment nginx --replicas 4kubectl get pods -o wideRésultat attendu :
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.
-
Mettez à l'échelle vers deux réplicas. Les pods ECS Pay-As-You-Go sont ensuite supprimés.
kubectl scale deployment nginx --replicas 2kubectl get pods -o wideRésultat attendu :
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> -
Une fois la terminaison achevée, seuls les pods ECS Subscription subsistent.
kubectl get pods -o wideRésultat attendu :
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
Il se peut que le planificateur n'associe pas la ResourcePolicy aux bons pods. Vérifiez que le selector correspond exactement aux étiquettes des pods de votre charge de travail. Si le sélecteur utilise une étiquette réservée par le système (comme alibabacloud.com/compute-class), le système risque de la modifier, rompant ainsi l'association.
Confirmez également que la version de votre kube-scheduler respecte les exigences minimales 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 inverse strict 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 ordonnancement 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 de la même charge de travail, 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 la 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
Pour utiliser uniquement ECS ou ECI, ou pour demander ECI lorsque ECS est insuffisant, configurez les tolérations et l'affinité de nœud (Spécifier l'allocation des ressources pour ECS et ECI).
Dans ACK Managed Cluster Pro Edition, mettez en œuvre la discrétisation basée sur les zones et l'ordonnancement par affinité pour les pods ECI.