Passer au contenu

Comment résoudre les problèmes de mise à l’échelle de clusters avec l’autoscaling Karpenter dans Amazon EKS ?

Lecture de 13 minute(s)
0

Je souhaite résoudre les problèmes de mise à l’échelle de clusters à l'aide de l’autoscaler Karpenter dans Amazon Elastic Kubernetes Service (Amazon EKS).

Résolution

Remédiez à votre problème en fonction du message d'erreur reçu.

Impossible de planifier des Karpenter Pods en raison d'un nombre insuffisant d'instances de groupes de nœuds Amazon EKS

Remarque : Si des erreurs surviennent lorsque vous exécutez des commandes de l'interface de la ligne de commande AWS (AWS CLI), consultez la section Résoudre des erreurs liées à l’AWS CLI. Vérifiez également que vous utilisez bien la version la plus récente de l'AWS CLI.

Dans les versions 0.16.0 et ultérieures de Karpenter, le nombre de réplicas par défaut est passé de 1 à 2. Pour en savoir plus, consultez la page v0.16.0 sur le site Web de GitHub. Si la capacité des nœuds du cluster est insuffisante pour prendre en charge le nombre de réplicas configuré, vous ne pouvez pas planifier de Karpenter Pods. Étant donné que Karpenter ne peut pas provisionner de nœuds pour gérer ses propres pods, il échoue en raison d'une capacité insuffisante et entraîne des pods non planifiés. Puis, le message d’erreur suivant s’affiche :

« Warning FailedScheduling 3m default-scheduler 0/1 nodes are available: 1 Insufficient memory. »

Pour résoudre cette erreur, effectuez l’une des opérations suivantes :

Réduisez le nombre de réplicas de déploiement Karpenter à un

Si votre déploiement Karpenter ne nécessite pas de redondance, modifiez-le pour utiliser un seul réplica. Exécutez la commande suivante :

kubectl scale deployment karpenter --replicas=1

Augmentez la capacité des nœuds pour les Karpenter Pods

Pour exécuter deux réplicas de Karpenter, assurez-vous que la capacité est suffisante pour deux réplicas. Choisissez l’une des options suivantes :

Augmenter horizontalement le groupe Auto Scaling

  1. Augmentez le nombre minimum d'instances dans le groupe Auto Scaling. Exécutez la commande suivante :
    aws autoscaling update-auto-scaling-group --auto-scaling-group-name your-node-group-name --min-size 2 --desired-capacity 2
    Remarque : Remplacez your-node-group-name par le nom de votre groupe Auto Scaling.
  2. Assurez-vous qu'il existe des nœuds non gérés par Karpenter. Vérifiez les étiquettes de nœuds pour les étiquettes Karpenter, telles que karpenter.sh/nodepool. Exécutez la commande suivante :
    kubectl get nodes --show-labels | grep karpenter.sh/nodepool

Utiliser les nœuds existants

Si le ou les nœuds existants cibles utilisent des étiquettes Karpenter telles que karpenter.sh/nodepool, supprimez les étiquettes. Exécutez la commande suivante :

kubectl label nodes your-node-name karpenter.sh/nodepool-

Remarque : Remplacez your-node-name par le nom de votre nœud.

Attachements et échecs de montage des volumes

Lorsque plusieurs pods utilisant des réclamations de volume persistant (PVC) sont planifiés sur le même nœud, le nœud peut dépasser son attachement de volume attaché. L'un des messages d'erreur suivants peut alors s’afficher :

« Warning FailedAttachVolume pod/example-pod AttachVolume. Attach failed for volume " " : rpc error: code = Internal desc = Could not attach volume " " to node " ": attachment of disk " " failed, expected device to be attached but was attaching »

« Warning FailedMount pod/example-pod Unable to attach or mount volumes: unmounted volumes=[], unattached volumes=[]: timed out waiting for the condition »

Pour résoudre les problèmes d’attachement et de montage des volumes pour les charges de travail comptant un grand nombre de PVC, procédez comme suit :

  1. Appliquez topologySpreadConstraints et podAntiAffinity pour empêcher la planification de pods comptant un grand nombre de PVC sur le même nœud. Pour plus d'informations, consultez les pages Champ topologySpreadConstraints et Exemple d’affinité de pod sur le site Web de Kubernetes. Cette action répartit les modules comptant un grand nombre de PVC sur différents nœuds afin d'éviter la concentration d’attachements de volumes sur un seul nœud.
  2. Utilisez des pilotes CSI tels que le pilote Container Storage Interface (CSI) Amazon Elastic Block Store (Amazon EBS) (aws-ebs-csi-driver) et ajoutez des rejets de start-up à votre NodePool. Ces actions garantissent que les pods ne sont pas planifiés prématurément sur les nœuds avant qu'ils ne soient entièrement prêts.
    Exemple de configuration des rejets de start-up dans Amazon EBS :
    --yaml--
    apiVersion: karpenter.sh/v1
    kind: NodePool
    spec:
      template:
        spec:
          startupTaints:
            - key: ebs.csi.aws.com/agent-not-ready
              effect: NoExecute
    

Erreur de plug-in de stockage obsolète

Karpenter ne prend pas en charge les plug-ins de stockage « in-tree » obsolètes tels qu'Amazon EBS. Si vous utilisez un volume persistant (PV) provisionné statiquement avec un plug-in « in-tree », Karpenter ne peut pas découvrir les limites d’attachement de volume du nœud. Ce scénario peut entraîner des échecs de planification et le message d'erreur suivant peut s'afficher :

« ERROR controller.node_state PersistentVolume source 'AWSElasticBlockStore' uses an in-tree storage plugin which is unsupported by Karpenter and is deprecated by Kubernetes. »

Pour résoudre ce problème, utilisez des pilotes CSI pour Amazon EBS et mettez à jour vos configurations PV pour utiliser le pilote CSI.

Échecs de planification ou de bin-pack dus à des demandes de ressources non spécifiées

Karpenter effectue un bin-packing des pods en fonction des demandes de ressources. Si les demandes sont trop faibles ou manquantes, Karpenter peut allouer un trop grand nombre de pods au même nœud. Ce scénario peut entraîner des conflits de ressources et une limitation du processeur. En outre, si des limites de mémoire sont définies et que les pods essaient d'utiliser plus de mémoire que leur limite, des résiliations de mémoire insuffisante (OOM) peuvent se produire. Le message d'erreur suivant peut s'afficher :

« Warning OOMKilled pod/your-pod-name Container "container-name" was killed due to OOM (Out of Memory). Memory limit: 512Mi, Memory usage: 513Mi »

Pour éviter ces problèmes, utilisez des configurations LimitRange pour définir les demandes de ressources minimales pour un bin-packing précis. Les configurations LimitRange contribuent à établir des limites maximales afin d'éviter une consommation excessive. Elles fournissent également des limites par défaut pour les pods non spécifiés. Pour plus d'informations, consultez la section Utiliser LimitRanges pour configurer les valeurs par défaut des demandes et des limites de ressources.

Les pods Windows ne parviennent pas à démarrer avec une erreur d'extraction d'image

Un pod ne démarre pas si la version du système d'exploitation (OS) de son conteneur ne correspond pas à la version du système d'exploitation Windows. Un message d'erreur similaire à l’exemple au suivant :

« Failed to pull image "mcr.microsoft.com/windows/servercore:xxx": rpc error: code = NotFound desc = failed to pull and unpack image "mcr.microsoft.com/windows/servercore:xxx": no match for platform in manifest: not found »

Pour résoudre ce problème, définissez le nodeSelector de votre pod pour vous assurer que vos conteneurs sont planifiés sur une version hôte de système d'exploitation compatible. Pour plus d'informations, consultez la page Compatibilité des versions de conteneurs Windows sur le site Web de Microsoft.

Les nœuds ne sont pas initialisés correctement

Le système détermine l'initialisation des nœuds en fonction de leur préparation, de l'enregistrement de ressources prévu et de la suppression des rejets de start-up du NodePool. Si l'une de ces conditions n'est pas remplie, le nœud Karpenter ne parvient pas à s'initialiser correctement et le nœud demeure à l’état NotReady. Par conséquent, le système ne peut pas utiliser le nœud pour planifier ou consolider les charges de travail. Le message d'erreur suivant peut s'afficher :

« Nodes provisioned by Karpenter are in a NotReady state »

Vérifiez que l'état du nœud est Prêt. Si tel n'est pas le cas, inspectez les journaux Kubelet pour identifier des problèmes potentiels liés aux autorisations, aux groupes de sécurité ou aux réseaux.

Vérifiez que toutes les ressources requises, telles que nvidia.com/gpu ou vpc.amazonaws.com/pod-eni, sont correctement enregistrées sur le nœud.

Pour vérifier les ressources nvidia.com/gpu sur le nœud, exécutez la commande suivante :

kubectl describe node your-node-name

Remarque : Remplacez your-node-name par le nom de votre nœud.

Exemple de sortie :

...
Capacity:
  nvidia.com/gpu.shared: 80
...

Si ces ressources sont manquantes, vérifiez que le daemonset ou les plug-ins appropriés sont en cours d'exécution. Pour vérifier la présence du daemonset, exécutez la commande suivante :

kubectl get ds -n your-daemonset-namespace

Remarque : Remplacez your-daemonset-namespace par votre espace de noms daemonset.

Échecs de planification en raison de diverses contraintes et limites

Le pod ne peut pas être planifié en raison de contraintes d'affinité, d'anti-affinité ou de répartition de la topologie

Un pod n'est pas planifié si les contraintes d'affinité, d'anti-affinité ou de répartition de la topologie nécessitent des nœuds ou des zones spécifiques, mais qu'il n'existe pas de nœuds adéquats aux emplacements requis. Si le système ne parvient pas à placer un pod car les exigences relatives aux nœuds ou aux zones ne sont pas respectées, le message d'erreur suivant peut s'afficher :

« Warning FailedScheduling pod/"pod-name" 0/3 nodes are available: 1 node(s) didn't match pod affinity rules, 2 node(s) didn't match pod topology spread constraints rules, 3 nodes(s) didn't match inter-pod anti-affinity rules. »

Pour résoudre cette erreur, vérifiez et ajustez les paramètres d'affinité et d'anti-affinité du pod ou les contraintes de répartition de la topologie pour les aligner sur les nœuds disponibles. Vous pouvez assouplir ces contraintes ou approvisionner davantage de nœuds dans les zones requises.

Impossible de planifier le pod en raison de ressources insuffisantes

Les pods demeurent non planifiés en raison de demandes de ressources dépassant la capacité des nœuds disponibles. Si aucun nœud ne dispose d’un processeur, d’une mémoire ou d’autres ressources suffisants pour accepter le pod, le message d'erreur suivant peut s'afficher :

« Warning FailedScheduling 30s (x13 over 60m) default-scheduler 0/5 nodes are available: 1 Insufficient memory. preemption: 0/5 nodes are available: 5 No preemption victims found for incoming pod. »

Pour résoudre ce problème, assurez-vous que les demandes de ressources dans la spécification du pod reflètent l'utilisation réelle. Ajustez les demandes et les limites de ressources si nécessaire, ou provisionnez des nœuds de plus grande taille avec une capacité accrue pour répondre aux demandes de ressources.

Les rejets empêchent la planification des pods

Lorsque les administrateurs de clusters appliquent des rejets personnalisés à des nœuds spécifiques, les pods doivent présenter des tolérances correspondantes. S'ils n'ont pas de tolérances correspondantes, le système ne peut pas planifier de pods sur ces nœuds. Le message d’erreur suivant s’affiche :

« 0/5 nodes are available: 3 node(s) had taint {dedicated: gpu}, that the pod didn't tolerate, 2 node(s) had taint {dedicated: non-gpu}, that the pod didn't tolerate. »

Pour résoudre cette erreur, ajoutez les tolérances appropriées à la spécification du pod afin de lui permettre de tolérer les rejets. Vous pouvez également supprimer ou modifier les rejets personnalisés inutiles sur les nœuds s’ils sont trop restrictifs.

Pour supprimer un rejet d'un nœud, exécutez la commande suivante :

kubectl taint nodes your-node-name your-custom-taint-

Remarque : Remplacez your-node-name par le nom de votre nœud et your-custom-taint par le nom de votre rejet personnalisé.

Les contraintes NodeAffinity ou NodeSelector ne sont pas satisfaites

S'il existe des contraintes d'affinité de nœud ou de sélecteur de nœud qui ne correspondent à aucun nœud disponible dans le cluster, le planificateur ne peut pas placer de pods. Le message d’erreur suivant s’affiche :

« Warning FailedScheduling  3m    default-scheduler 0/4 nodes are available: 1 node(s) didn't match Pod's node affinity/selector, 3 node(s) didn't satisfy existing pods anti-affinity rules, 4 node(s) didn't match Pod's node affinity rules. »

Pour résoudre cette erreur, modifiez les exigences relatives à l'affinité de nœud ou au sélecteur de nœud du pod pour les rendre plus flexibles. Vous pouvez également mettre en service des nœuds supplémentaires qui répondent aux critères du pod si nécessaire. Pour plus d'informations, consultez les pages Affinité de nœud et nodeSelector sur le site Web de Kubernetes.

Adresses IP insuffisantes dans le sous-réseau

Lorsque Karpenter essaie de mettre en service de nouveaux nœuds, il échoue en raison d'adresses IP insuffisantes dans le sous-réseau. Ce scénario se produit lorsque la plage Routage inter-domaines sans classe (CIDR) du sous-réseau est épuisée et ne peut pas accueillir de nouvelles instances Amazon Elastic Compute Cloud (Amazon EC2). Le message d’erreur suivant s’affiche :

« error": "creating machine, creating instance, with fleet error(s), InsufficientFreeAddressesInSubnet: There are not enough free addresses in subnet 'subnet-a to satisfy the requested number of instances. »

Pour résoudre cette erreur, effectuez l’une des opérations suivantes :

Si les adresses IP du sous-réseau sont épuisées, ajoutez un bloc CIDR IPv4 supplémentaire en tant qu'adresse CIDR secondaire à votre Amazon Virtual Private Cloud (Amazon VPC).

-ou-

Utilisez la mise en réseau personnalisée pour attribuer des espaces d'adresses IP distincts à vos pods et nœuds. Pour activer la mise en réseau personnalisée, exécutez la commande suivante :

kubectl set env daemonset aws-node -n kube-system AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG=true

Pour plus d'informations sur la mise en réseau personnalisée, consultez la section Comment choisir des sous-réseaux d'adresses IP spécifiques pour les pods de mon cluster Amazon EKS ?

Impossible de planifier le pod en raison d'exigences incompatibles

Karpenter ne planifie pas les pods qui spécifient des étiquettes de groupes de nœuds tels que eks.amazonaws.com/nodegroup qui ne correspondent à aucune valeur définie dans les configurations du pool de nœuds. Si cette incompatibilité se produit, Karpenter ne peut pas placer de pods sur les nœuds en raison de l'absence d'étiquettes de nœuds requises. L'un des messages d'erreur suivants s'affiche :

« incompatible requirements, label \"eks.amazonaws.com/nodegroup\" does not have known values »

« incompatible requirements, key topology.kubernetes.io/zone, topology.kubernetes.io/zone In [us-east-1a] not in topology.kubernetes.io/zone In [us-east-1b us-east-1c] »

« incompatible requirements, key nodes.ktp.io/role, nodes.ktp.io/role In [ktp-atom-apps] not in nodes.ktp.io/role In [kube-apps] »

Si vous souhaitez que les pods puissent être planifiés par Karpenter, supprimez le nodeSelector spécifique au groupe de nœuds gérés pour résoudre cette erreur.

Exemple :

kubectl edit pod your-pod-name
or  
kubectl edit deployment your-deployment-name
or
kubectl edit daemonset your-daemonset-name

Remarque : Remplacez your-pod-name, your-deployment-name ou your-daemonset-name par le nom de votre pod, déploiement ou daemonset.

Échecs de consolidation des nœuds

La consolidation des nœuds de Karpenter peut échouer en raison de contraintes de planification ou de configurations spécifiques des pods qui empêchent la migration des pods.

Contraintes de planification

La consolidation des nœuds échoue lorsque les pods ne peuvent pas être migrés pour les raisons suivantes :

  • Affinité ou anti-affinité entre les pods : Pods nécessitant ou évitant la colocation avec d'autres pods.
  • Contraintes de répartition de la topologie : Pods qui doivent être répartis sur des zones, des nœuds ou des racks différents.
  • Autres restrictions de planification : Toute autre contrainte qui empêche le déplacement des pods vers d'autres nœuds.

Examinez et ajustez les règles d'affinité et d'anti-affinité des pods afin de les rendre moins restrictives. Ajustez les contraintes de répartition de la topologie pour permettre une plus grande flexibilité et d'autres restrictions de planification susceptibles d’être trop strictes.

Prévention spécifique au pod

Si certains types de pods s'exécutent sur vos nœuds, il est possible que Karpenter ne soit pas en mesure de consolider les nœuds. Karpenter ne peut pas expulser ces pods en raison d'annotations, de contraintes de planification, de budgets de perturbation des pods (PDB) ou de l'absence d’un propriétaire de contrôleur. La consolidation peut échouer car Karpenter ne violera pas ces préférences, même si kube-scheduler peut techniquement placer les pods ailleurs.

AWS OFFICIELA mis à jour il y a 2 mois