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.
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
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.
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
maxest 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
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 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 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 labelsalibabacloud.com/compute-class: defaultetalibabacloud.com/compute-class: general-purposeaux pods. Remplacez ces valeurs en spécifiant des valeurs différentes danspodLabels. Sialpha.alibabacloud.com/compute-qos-strategyest spécifié danspodAnnotations, le labelalibabacloud.com/compute-class: defaultn'est pas ajouté.
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. Le labelk8s.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).
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.
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.
-
Créez une ResourcePolicy qui définit l'ordre de planification des pools de nœuds. Remplacez les valeurs
nodepool-idpar 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**** -
Créez un Deployment. Le label 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 l'emplacement des pods.
-
Appliquez les fichiers YAML.
kubectl apply -f nginx.yamlSortie attendue :
deployment.apps/nginx created -
Vérifiez sur quels nœuds les pods sont planifiés.
kubectl get pods -o wideSortie 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.
-
-
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 l'emplacement des pods.
kubectl get pods -o wideSortie 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é.
-
-
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 wideSortie 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.
-
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 -
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 -
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 et vérifiez le placement initial sur les nœuds sous abonnement.
-
Appliquez les fichiers YAML.
kubectl apply -f nginx.yaml -
Vérifiez l'emplacement des pods.
kubectl get pods -o wideSortie 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.
-
-
Effectuez un scale-out pour vérifier le débordement vers ECS à la demande, puis vers ECI.
-
Mettez à l'échelle vers quatre réplicas et vérifiez l'emplacement des pods.
kubectl scale deployment nginx --replicas 4kubectl get pods -o wideSortie 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.
-
Mettez à l'échelle vers six réplicas et vérifiez l'emplacement des pods.
kubectl scale deployment nginx --replicas 6kubectl get pods -o wideSortie 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).
-
-
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 wideSortie 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.
-
Mettez à l'échelle vers deux réplicas. Les pods ECS à la demande sont ensuite supprimés.
kubectl scale deployment nginx --replicas 2kubectl get pods -o wideSortie 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> -
Une fois la terminaison terminée, seuls les pods ECS sous abonnement restent.
kubectl get pods -o wideSortie 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
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 l'édition Pro du cluster ACK managé, mettez en œuvre la discrétisation basée sur les zones et la planification par affinité pour les pods ECI.