Par défaut, les pods sont planifiés en fonction des ressources demandées plutôt que de la charge réelle des nœuds. Activez la planification tenant compte de la charge dans un cluster ACK Pro managé pour placer les pods sur des nœuds dont la charge effective est plus faible, équilibrer l'utilisation et réduire le risque de défaillance des nœuds causée par la surcharge d'un seul nœud.
Fonctionnement de la planification tenant compte de la charge
La planification tenant compte de la charge est un plugin du planificateur Container Service for Kubernetes (ACK), implémenté sur la base du framework de planification Kubernetes. La politique de planification native de Kubernetes place principalement les pods selon l'allocation des ressources. Le planificateur ACK détecte quant à lui la charge réelle des ressources de chaque nœud : il s'appuie sur les statistiques historiques de charge des nœuds, estime la charge du pod à planifier, puis place ce dernier sur un nœud moins chargé. Cette approche permet d'équilibrer la charge entre les nœuds et aide à prévenir les pannes d'application ou de nœud dues à la surcharge d'un nœud unique.
La planification tenant compte de la charge nécessite à la fois le composant kube-scheduler et le module complémentaire ack-koordinator. Le module complémentaire ack-koordinator collecte et rapporte l'utilisation des ressources des nœuds, tandis que le planificateur ACK utilise ces données pour noter et classer les nœuds, afin de sélectionner en priorité ceux qui sont les moins chargés. Pour plus de détails sur la conception du module complémentaire, consultez Architecture d'ack-koordinator.
Dans la figure ci-dessous, Requested représente la quantité de ressources demandées et Usage correspond à la quantité de ressources réellement utilisées. Seules les ressources effectivement consommées comptent comme charge réelle. Dans des conditions de nœud identiques, le planificateur ACK attribue le nouveau pod au nœud B, qui présente la charge la plus faible.

L'utilisation des nœuds évolue dynamiquement au fil du temps et en fonction de l'environnement du cluster, du trafic des charges de travail et du volume des requêtes. Pour réduire le risque que le cluster ne se déséquilibre à nouveau après la planification des pods, le module complémentaire ack-koordinator propose également une fonctionnalité de déplanification. Utilisez la planification tenant compte de la charge conjointement avec l'utilisation de la déplanification sensible aux points chauds pour équilibrer les charges des nœuds afin de maintenir l'équilibre des charges des nœuds dans le temps.
Mesure de la charge des nœuds
Les statistiques de charge peuvent être agrégées de plusieurs manières, notamment via des valeurs moyennes et des percentiles. Par défaut, le planificateur ACK utilise la moyenne calculée sur les 5 dernières minutes. Pour modifier le type d'agrégation, définissez le paramètre loadAwareAggregatedUsageAggragationType. Pour plus d'informations, consultez Personnalisation des paramètres de kube-scheduler.
Pour la mémoire, les données d'utilisation excluent le cache de pages, car le système d'exploitation peut le récupérer. L'utilisation renvoyée par la commande kubectl top node inclut le cache de pages. Pour afficher l'utilisation réelle de la mémoire d'un nœud, consultez Configuration de Managed Service for Prometheus.
Politiques de planification
La planification tenant compte de la charge propose les politiques suivantes. Toutes deux s'appuient sur la statistique de charge agrégée des nœuds décrite dans la section précédente.
|
Politique |
Description |
|
Filtrage des nœuds |
Filtre les nœuds candidats en fonction de leur charge réelle. Si la charge réelle d'un nœud dépasse le seuil de charge configuré, le planificateur n'y affecte pas de pods. Le filtrage des nœuds est désactivé par défaut. Pour l'activer, définissez le paramètre |
|
Notation des nœuds |
Attribue une note aux nœuds candidats selon les dimensions CPU et mémoire, puis sélectionne en priorité les nœuds ayant les scores les plus élevés. Le score est calculé comme suit : |
Prérequis
Type de cluster — Seul un cluster ACK Pro managé est pris en charge. Pour la procédure, consultez Création d'un cluster ACK Pro.
Module complémentaire ack-koordinator — Installez le module complémentaire ack-koordinator version 1.1.1-ack.1 ou ultérieure. Pour la procédure d'installation, consultez ack-koordinator (anciennement ack-slo-manager).
Version du planificateur ACK — Le planificateur ACK doit satisfaire aux exigences de version correspondant à la version Kubernetes de votre cluster, comme indiqué dans le tableau suivant.
|
Version Kubernetes |
Version requise du planificateur ACK |
|
1.26 et versions ultérieures |
Toutes les versions |
|
1,24 |
v1.24.6-ack-4.0 ou version ultérieure |
|
1,22 |
v1.22.15-ack-4.0 ou version ultérieure |
Ces versions sont nécessaires pour configurer la planification tenant compte de la charge via les paramètres de kube-scheduler. Certaines versions antérieures du planificateur ne prennent en charge que le protocole d'annotation de pod. Pour la matrice de compatibilité complète, consultez la section FAQ.
Facturation
L'installation et l'utilisation du module complémentaire ack-koordinator sont gratuites. Toutefois, des coûts peuvent être engagés dans les scénarios suivants :
Ressources des nœuds de travail — ack-koordinator est un module complémentaire non managé qui consomme des ressources des nœuds de travail après son installation. Les demandes de ressources peuvent être configurées pour chaque module lors de l'installation.
Métriques personnalisées — Par défaut, ack-koordinator expose des métriques de surveillance pour des fonctionnalités telles que le profilage des ressources et la planification granulaire au format Prometheus. Si vous sélectionnez Enable Prometheus monitoring metrics for ack-koordinator et utilisez Managed Service for Prometheus, ces métriques sont facturées en tant que métriques personnalisées. Les frais varient en fonction de facteurs tels que la taille du cluster et le nombre d'applications. Avant d'activer cette fonctionnalité, consultez Facturation des instances Prometheus pour comprendre l'offre gratuite et la tarification des métriques personnalisées. Pour surveiller et gérer votre utilisation des ressources, utilisez la requête d'utilisation.
Étape 1 : Activer la planification tenant compte de la charge
La planification tenant compte de la charge ne prend effet que si le module complémentaire ack-koordinator et le planificateur ACK satisfont aux exigences de version décrites dans la section Prérequis.
Connectez-vous à la console ACK. Dans le volet de navigation de gauche, cliquez sur Clusters.
Sur la page Clusters, cliquez sur le nom de votre cluster. Dans le volet de navigation de gauche, cliquez sur Components and Add-ons .
Recherchez kube-scheduler et cliquez sur Configuration.
-
Dans la boîte de dialogue des paramètres de kube-scheduler, configurez les paramètres décrits dans le tableau suivant et cliquez sur OK.
Le tableau suivant décrit les principaux paramètres de la planification tenant compte de la charge. Pour la référence complète des paramètres et les versions du module complémentaire requises pour chacun d'eux, consultez kube-scheduler et .
Paramètre
Type
Description
Valeurs valides
Valeur par défaut
Exemple
loadAwareThresholdListe composée du nom de la ressource
resourceNameet du seuilthreshold.Seuil du type de ressource correspondant, utilisé par la politique de filtrage des nœuds.
resourceName:cpuetmemorysont pris en charge.threshold: [0,100].Vide, ce qui signifie que le filtrage des nœuds est désactivé.
resourceName: cpuetthreshold: 80loadAwareResourceWeightListe composée du nom de la ressource
resourceNameet du poidsresourceWeight.Poids de notation du type de ressource correspondant, utilisé par la politique de notation des nœuds. Vous devez sélectionner Specifies whether to enable load-aware node scoring during pod scheduling.
resourceName: seulscpuetmemorysont pris en charge.resourceWeight: entier compris dans la plage [1,100].cpu: 1etmemory: 1resourceName: cpuetresourceWeight: 1loadAwareAggregatedUsageAggragationTypeenum
Type d'agrégation de la statistique de charge.
avg: valeur moyenne.p50: 50e percentile, soit la médiane.p90,p95etp99: 90e, 95e et 99e percentiles.avg,p50,p90,p95etp99avgp90ImportantSi la mise à l'échelle automatique des nœuds est déjà activée pour les nœuds du cluster, un seuil de filtrage tenant compte de la charge peut déclencher une mise à l'échelle horizontale ascendante ou descendante inattendue. En effet, la mise à l'échelle automatique des nœuds procède à une mise à l'échelle ascendante en fonction de l'état d'attente des pods et à une mise à l'échelle descendante en fonction du niveau d'allocation du cluster. Pour utiliser conjointement la mise à l'échelle automatique des nœuds et le filtrage des nœuds tenant compte de la charge, ajustez la configuration pour qu'elle corresponde à la capacité et à l'utilisation de votre cluster, comme décrit dans Activation de la mise à l'échelle automatique des nœuds.
Dans le volet de navigation de gauche, cliquez sur Cluster Information. Sur la page qui s'affiche, cliquez sur l'onglet Basic Information et attendez que le cluster passe à l'état Running, ce qui indique que la planification tenant compte de la charge est activée.
Étape 2 : Vérifier la planification tenant compte de la charge
L'exemple suivant utilise un cluster composé de trois nœuds, chacun disposant de 4 cœurs et de 16 Go de mémoire. L'exemple commence par déséquilibrer les charges entre les nœuds, puis vérifie où les nouveaux pods sont planifiés.
-
Créez un fichier nommé stress-demo.yaml avec le contenu suivant.
apiVersion: apps/v1 kind: Deployment metadata: name: stress-demo namespace: default labels: app: stress-demo spec: replicas: 1 selector: matchLabels: app: stress-demo template: metadata: name: stress-demo labels: app: stress-demo spec: containers: - args: - '--vm' - '2' - '--vm-bytes' - '1600M' - '-c' - '2' - '--vm-hang' - '2' command: - stress image: polinux/stress imagePullPolicy: Always name: stress resources: limits: cpu: '2' memory: 4Gi requests: cpu: '2' memory: 4Gi restartPolicy: Always -
Exécutez la commande kubectl suivante pour créer le pod. Le pod augmente la charge du nœud qui l'héberge.
kubectl create -f stress-demo.yamldeployment.apps/stress-demo created -
Exécutez la commande kubectl suivante pour vérifier l'état du pod jusqu'à ce qu'il soit en cours d'exécution.
kubectl get pod -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES stress-demo-7fdd89cc6b-g**** 1/1 Running 0 82s 10.XX.XX.112 cn-beijing.10.XX.XX.112 <none> <none>stress-demo-7fdd89cc6b-g****est planifié sur le nœudcn-beijing.10.XX.XX.112. Attendez environ 3 minutes que le pod termine son initialisation et que la charge du nœud ait augmenté. -
Exécutez la commande kubectl suivante pour vérifier la charge de chaque nœud.
kubectl top nodeNAME CPU(cores) CPU% MEMORY(bytes) MEMORY% cn-beijing.10.XX.XX.110 92m 2% 1158Mi 9% cn-beijing.10.XX.XX.111 77m 1% 1162Mi 9% cn-beijing.10.XX.XX.112 2105m 53% 3594Mi 28%cn-beijing.10.XX.XX.111présente la charge la plus faible et le nœudcn-beijing.10.XX.XX.112la charge la plus élevée. Les charges entre les nœuds du cluster sont désormais déséquilibrées. -
Créez un fichier nommé nginx-with-loadaware.yaml avec le contenu suivant.
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-with-loadaware namespace: default labels: app: nginx spec: replicas: 6 selector: matchLabels: app: nginx template: metadata: name: nginx labels: app: nginx spec: containers: - name: nginx image: nginx resources: limits: cpu: 500m requests: cpu: 500m -
Exécutez la commande kubectl suivante pour créer les pods.
kubectl create -f nginx-with-loadaware.yamldeployment/nginx-with-loadawre created -
Exécutez la commande kubectl suivante pour afficher les détails de la planification des pods.
kubectl get pods | grep nginxnginx-with-loadaware-5646666d56-2**** 1/1 Running 0 18s 10.XX.XX.118 cn-beijing.10.XX.XX.110 <none> <none> nginx-with-loadaware-5646666d56-7**** 1/1 Running 0 18s 10.XX.XX.115 cn-beijing.10.XX.XX.110 <none> <none> nginx-with-loadaware-5646666d56-k**** 1/1 Running 0 18s 10.XX.XX.119 cn-beijing.10.XX.XX.110 <none> <none> nginx-with-loadaware-5646666d56-q**** 1/1 Running 0 18s 10.XX.XX.113 cn-beijing.10.XX.XX.111 <none> <none> nginx-with-loadaware-5646666d56-s**** 1/1 Running 0 18s 10.XX.XX.120 cn-beijing.10.XX.XX.111 <none> <none> nginx-with-loadaware-5646666d56-z**** 1/1 Running 0 18s 10.XX.XX.116 cn-beijing.10.XX.XX.111 <none> <none>La sortie attendue montre qu'après l'activation de la planification tenant compte de la charge, le planificateur détecte les charges des nœuds et utilise la stratégie de planification pour affecter prioritairement les pods à des nœuds autres que cn-beijing.10.XX.XX.112.
FAQ
Pourquoi tous les pods d'un lot de pods nouvellement créés ne sont-ils pas planifiés sur le nœud ayant la charge la plus faible ?
Les nouveaux pods augmentent la charge d'un nœud après leur démarrage. Si le planificateur plaçait tout un lot de nouveaux pods sur le nœud actuellement le moins chargé, ce nœud pourrait rapidement devenir un point chaud de charge.
Par conséquent, lorsque le plugin de planification tenant compte de la charge note les nœuds, il ajuste le score d'un nœud hébergeant de nouveaux pods dont l'utilisation n'a pas encore été rapportée. Cela empêche une surplanification de créer un nouveau point chaud.
Outre la charge des nœuds, quels autres facteurs influencent le résultat de la planification ?
Le planificateur Kubernetes est composé de plusieurs plugins, et beaucoup d'entre eux contribuent à la notation des nœuds lors de la planification, tels que le plugin d'affinité et le plugin de répartition topologique. Le classement final des nœuds reflète l'ensemble de ces plugins, et vous pouvez ajuster le poids de notation de chaque plugin selon vos besoins.
Après la mise à niveau du planificateur vers une nouvelle version, la planification tenant compte de la charge fonctionne-t-elle toujours via l'ancien protocole ?
La réponse dépend de la version Kubernetes du cluster. Dans la version 1.22, le planificateur ACK reste compatible avec l'ancien protocole. Pour la version 1.24, la période de compatibilité a pris fin le 30 août 2023. Pour la version 1.26 et les versions ultérieures, le protocole d'annotation de pod n'est pas pris en charge.
Sur une version prenant toujours en charge l'ancien protocole, ajoutez l'annotation alibabacloud.com/loadAwareScheduleEnabled: "true" au pod. Comme le planificateur ACK est compatible avec l'ancien protocole, vous pouvez mettre à niveau le planificateur vers la nouvelle version de manière transparente. Après la mise à niveau, utilisez la personnalisation des paramètres de kube-scheduler pour activer une politique de planification d'équilibrage de charge à l'échelle du cluster, ce qui réduit les modifications nécessaires dans les configurations des pods.
Mettez à niveau un cluster vers une version ultérieure et utilisez la nouvelle méthode de configuration pour la planification tenant compte de la charge. Pour plus d'informations, consultez la mise à niveau manuelle d'un cluster.
Les tableaux suivants décrivent la prise en charge des protocoles et les exigences de version du module complémentaire pour chaque version :
1.26 et versions ultérieures
|
Version du planificateur ACK |
Version requise d'ack-koordinator (ack-slo-manager) |
Protocole d'annotation de pod |
Commutateur de paramètres de la console |
|
Toutes les versions du planificateur ACK |
≥1.1.1-ack.1 |
Non pris en charge |
Pris en charge |
1,24
|
Version du planificateur ACK |
Version requise d'ack-koordinator (ack-slo-manager) |
Protocole d'annotation de pod |
Commutateur de paramètres de la console |
|
≥v1.24.6-ack-4.0 |
≥1.1.1-ack.1 |
Pris en charge |
Pris en charge |
|
≥v1.24.6-ack-3.1 et <v1.24.6-ack-4.0 |
≥0.8.0 |
Pris en charge |
Non pris en charge |
|
Version du planificateur ACK |
Version requise d'ack-koordinator (ack-slo-manager) |
Protocole d'annotation de pod |
Commutateur de paramètres de la console |
|
≥1.22.15-ack-4.0 |
≥1.1.1-ack.1 |
Pris en charge |
Pris en charge |
|
≥1.22.15-ack-2.0 et <1.22.15-ack-4.0 |
≥0.8.0 |
Pris en charge |
Non pris en charge |
|
≥v1.20.4-ack-4.0 et ≤v1.20.4-ack-8.0, ou v1.18-ack-4.0 |
≥0.3.0 et <0.8.0 |
Pris en charge |
Non pris en charge |