Sélectionner vos préférences de cookies

Nous utilisons des cookies essentiels et des outils similaires qui sont nécessaires au fonctionnement de notre site et à la fourniture de nos services. Nous utilisons des cookies de performance pour collecter des statistiques anonymes afin de comprendre comment les clients utilisent notre site et d’apporter des améliorations. Les cookies essentiels ne peuvent pas être désactivés, mais vous pouvez cliquer sur « Personnaliser » ou « Refuser » pour refuser les cookies de performance.

Si vous êtes d’accord, AWS et les tiers approuvés utiliseront également des cookies pour fournir des fonctionnalités utiles au site, mémoriser vos préférences et afficher du contenu pertinent, y compris des publicités pertinentes. Pour accepter ou refuser tous les cookies non essentiels, cliquez sur « Accepter » ou « Refuser ». Pour effectuer des choix plus détaillés, cliquez sur « Personnaliser ».

Placez des pods Kubernetes sur Amazon EKS en utilisant l'affinité, les entorses et les tolérances des nœuds - Recommandations AWS

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Placez des pods Kubernetes sur Amazon EKS en utilisant l'affinité, les entorses et les tolérances des nœuds

Créée par Hitesh Parikh (AWS) et Raghu Bhamidimarri (AWS)

Récapitulatif

Ce modèle illustre l'utilisation de l'affinité des nœuds Kubernetes, de l'altération des nœuds et des tolérances des pods pour planifier intentionnellement des pods d'application sur des nœuds de travail spécifiques d'un cluster Amazon Elastic Kubernetes Service (Amazon EKS) sur le cloud Amazon Web Services (AWS).

Une souillure est une propriété de nœud qui permet aux nœuds de rejeter un ensemble de modules. Une tolérance est une propriété de Pod qui permet au planificateur Kubernetes de planifier des Pods sur des nœuds présentant les mêmes caractéristiques.

Cependant, les tolérances ne peuvent à elles seules empêcher un planificateur de placer un Pod sur un nœud de travail qui ne présente aucune trace. Par exemple, un pod à forte intensité de calcul assorti d'une tolérance peut involontairement être programmé sur un nœud non contaminé à usage général. Dans ce scénario, la propriété d'affinité de nœud d'un Pod indique au planificateur de placer le Pod sur un nœud qui répond aux critères de sélection de nœuds spécifiés dans l'affinité de nœud.

Ensemble, les entailles, les tolérances et l'affinité des nœuds indiquent au planificateur de planifier les pods de manière cohérente sur les nœuds avec les taches correspondantes et les étiquettes des nœuds qui correspondent aux critères de sélection des nœuds d'affinité de nœud spécifiés sur le pod.

Ce modèle fournit un exemple de fichier manifeste de déploiement de Kubernetes, ainsi que les étapes à suivre pour créer un cluster EKS, déployer une application et valider le placement du Pod.

Conditions préalables et limitations

Prérequis

Limites

  • Ce modèle ne fournit pas le code Java et suppose que vous êtes déjà familiarisé avec Java. Pour créer un microservice Java de base, consultez Déployer un exemple de microservice Java sur Amazon EKS.

  • Les étapes décrites dans cet article créent des ressources AWS qui peuvent entraîner des coûts. Assurez-vous de nettoyer les ressources AWS une fois que vous avez terminé les étapes de mise en œuvre et de validation du modèle.

Architecture

Pile technologique cible

  • Amazon EKS

  • Java

  • Docker

  • Amazon Elastic Container Registry (Amazon ECR)

Architecture cible

Le schéma d'architecture de la solution montre Amazon EKS avec deux pods (déploiement 1 et déploiement 2) et deux groupes de nœuds (ng1 et ng2) avec deux nœuds chacun. Les pods et les nœuds possèdent les propriétés suivantes.

 

Déploiement : 1 pod

Déploiement 2 Pod

Groupe de nœuds 1 (ng1)

Groupe de nœuds 2 (ng2)

Tolérance

clé : classified_workload, valeur : true, effet : NoSchedule

clé : machine_learning_workload, valeur : vrai, effet : NoSchedule

Aucun

 

 

Affinité des nœuds

clé : alpha.eksctl.io/nodegroup-name = ng1 ;

Aucun

NodeGroups.name = ng1

 

Souillure

 

 

clé : classified_workload, valeur : true, effet : NoSchedule

clé : machine_learning_workload, valeur : vrai, effet : NoSchedule

Aucun

Configuration Amazon EKS avec deux pods et deux groupes de nœuds.
  1. Le pod Deployment 1 a des tolérances et une affinité de nœud définies, ce qui indique au planificateur Kubernetes de placer les pods de déploiement sur les nœuds du groupe de nœuds 1 (ng1).

  2. Le groupe de nœuds 2 (ng2) n'a pas d'étiquette de nœud correspondant à l'expression du sélecteur de nœuds d'affinité pour le déploiement 1. Les pods ne seront donc pas planifiés sur les nœuds ng2.

  3. Aucune tolérance ou affinité de nœud n'est définie dans le manifeste de déploiement pour le module Deployment 2. Le planificateur refusera de planifier le déploiement de 2 pods sur le groupe de nœuds 1 en raison des entorses sur les nœuds.

  4. Les pods Deployment 2 seront plutôt placés sur le groupe de nœuds 2, car les nœuds ne présentent aucune trace.

Ce modèle montre qu'en utilisant des nuances et des tolérances, associées à l'affinité des nœuds, vous pouvez contrôler le placement des pods sur des ensembles spécifiques de nœuds de travail.

Outils

Services AWS

Autres outils

  • Docker est un ensemble de produits de plateforme en tant que service (PaaS) qui utilisent la virtualisation au niveau du système d'exploitation pour fournir des logiciels dans des conteneurs.

  • kubectl est une interface de ligne de commande qui vous permet d'exécuter des commandes sur des clusters Kubernetes.

Épopées

TâcheDescriptionCompétences requises

Créez le fichier cluster.yaml.

Créez un fichier appelé cluster.yaml avec le code suivant.

apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: eks-taint-demo region: us-west-1 # Unmanaged nodegroups with and without taints. nodeGroups: - name: ng1 instanceType: m5.xlarge minSize: 2 maxSize: 3 taints: - key: classified_workload value: "true" effect: NoSchedule - key: machine_learning_workload value: "true" effect: NoSchedule - name: ng2 instanceType: m5.xlarge minSize: 2 maxSize: 3
Propriétaire de l'application, AWS DevOps, administrateur du cloud, DevOps ingénieur

Créez le cluster à l'aide de eksctl.

Exécutez le cluster.yaml fichier pour créer le cluster EKS. La création du cluster peut prendre quelques minutes.

eksctl create cluster -f cluster.yaml
AWS DevOps, administrateur système AWS, développeur d'applications

Création du cluster EKS

TâcheDescriptionCompétences requises

Créez le fichier cluster.yaml.

Créez un fichier appelé cluster.yaml avec le code suivant.

apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: eks-taint-demo region: us-west-1 # Unmanaged nodegroups with and without taints. nodeGroups: - name: ng1 instanceType: m5.xlarge minSize: 2 maxSize: 3 taints: - key: classified_workload value: "true" effect: NoSchedule - key: machine_learning_workload value: "true" effect: NoSchedule - name: ng2 instanceType: m5.xlarge minSize: 2 maxSize: 3
Propriétaire de l'application, AWS DevOps, administrateur du cloud, DevOps ingénieur

Créez le cluster à l'aide de eksctl.

Exécutez le cluster.yaml fichier pour créer le cluster EKS. La création du cluster peut prendre quelques minutes.

eksctl create cluster -f cluster.yaml
AWS DevOps, administrateur système AWS, développeur d'applications
TâcheDescriptionCompétences requises

Créez un référentiel privé Amazon ECR.

Pour créer un référentiel Amazon ECR, consultez Création d'un référentiel privé. Notez l'URI du dépôt.

AWS DevOps, DevOps ingénieur, développeur d'applications

Créez le Dockerfile.

Si vous avez une image de conteneur Docker existante que vous souhaitez utiliser pour tester le modèle, vous pouvez ignorer cette étape.

Pour créer un Dockerfile, utilisez l'extrait suivant comme référence. Si vous rencontrez des erreurs, consultez la section Dépannage.

FROM adoptopenjdk/openjdk11:jdk-11.0.14.1_1-alpine RUN apk add maven WORKDIR /code # Prepare by downloading dependencies ADD pom.xml /code/pom.xml RUN ["mvn", "dependency:resolve"] RUN ["mvn", "verify"] # Adding source, compile and package into a fat jar ADD src /code/src RUN ["mvn", "package"] EXPOSE 4567 CMD ["java", "-jar", "target/eksExample-jar-with-dependencies.jar"]
AWS DevOps, DevOps ingénieur

Créez le fichier pom.xml et les fichiers source, puis créez et publiez l'image Docker.

Pour créer le pom.xml fichier et le fichier source Java, consultez la section Déployer un exemple de microservice Java sur le modèle Amazon EKS.

Utilisez les instructions de ce modèle pour créer et envoyer l'image Docker.

AWS DevOps, DevOps ingénieur, développeur d'applications

Créez une image et chargez-la sur Amazon ECR

TâcheDescriptionCompétences requises

Créez un référentiel privé Amazon ECR.

Pour créer un référentiel Amazon ECR, consultez Création d'un référentiel privé. Notez l'URI du dépôt.

AWS DevOps, DevOps ingénieur, développeur d'applications

Créez le Dockerfile.

Si vous avez une image de conteneur Docker existante que vous souhaitez utiliser pour tester le modèle, vous pouvez ignorer cette étape.

Pour créer un Dockerfile, utilisez l'extrait suivant comme référence. Si vous rencontrez des erreurs, consultez la section Dépannage.

FROM adoptopenjdk/openjdk11:jdk-11.0.14.1_1-alpine RUN apk add maven WORKDIR /code # Prepare by downloading dependencies ADD pom.xml /code/pom.xml RUN ["mvn", "dependency:resolve"] RUN ["mvn", "verify"] # Adding source, compile and package into a fat jar ADD src /code/src RUN ["mvn", "package"] EXPOSE 4567 CMD ["java", "-jar", "target/eksExample-jar-with-dependencies.jar"]
AWS DevOps, DevOps ingénieur

Créez le fichier pom.xml et les fichiers source, puis créez et publiez l'image Docker.

Pour créer le pom.xml fichier et le fichier source Java, consultez la section Déployer un exemple de microservice Java sur le modèle Amazon EKS.

Utilisez les instructions de ce modèle pour créer et envoyer l'image Docker.

AWS DevOps, DevOps ingénieur, développeur d'applications
TâcheDescriptionCompétences requises

Créez le fichier deployment.yaml.

Pour créer le deployment.yaml fichier, utilisez le code de la section Informations supplémentaires.

Dans le code, la clé de l'affinité des nœuds est toute étiquette que vous créez lors de la création de groupes de nœuds. Ce modèle utilise l'étiquette par défaut créée par eksctl. Pour plus d'informations sur la personnalisation des étiquettes, consultez la section Affectation de pods à des nœuds dans la documentation de Kubernetes.

La valeur de la clé d'affinité de nœud est le nom du groupe de nœuds créé parcluster.yaml.

Pour obtenir la clé et la valeur de la tache, exécutez la commande suivante.

kubectl get nodes -o json | jq '.items[].spec.taints'

L'image est l'URI du référentiel Amazon ECR que vous avez créé lors d'une étape précédente.

AWS DevOps, DevOps ingénieur, développeur d'applications

Déployez le fichier.

Pour effectuer un déploiement sur Amazon EKS, exécutez la commande suivante.

kubectl apply -f deployment.yaml
Développeur d'applications, DevOps ingénieur, AWS DevOps

Vérifiez le déploiement.

  1. Pour vérifier si les pods sont prêts, exécutez la commande suivante.

    kubectl get pods -o wide

    Si le POD est prêt, la sortie doit ressembler à ce qui suit, avec le code « STATUS En cours d'exécution ».

    NAME        READY    STATUS    RESTARTS   AGE   IP  NODE  NOMINATED NODE   READINESS GATES <pod_name>   1/1     Running   0          12d   192.168.18.50   ip-192-168-20-110.us-west-1.compute.internal   <none>           <none>

    Notez le nom du Pod et le nom du nœud. Vous pouvez ignorer l'étape suivante.

  2. (Facultatif) Pour obtenir des informations supplémentaires sur le Pod et vérifier les tolérances sur le Pod, exécutez la commande suivante.

    kubectl describe pod <pod_name>

    Un exemple de sortie se trouve dans la section Informations supplémentaires.

  3. Pour vérifier que le placement du Pod sur le nœud est correct, exécutez la commande suivante.

    kubectl describe node <node name> | grep -A 1 "Taints"

    Vérifiez que la souillure du nœud correspond à la tolérance et que l'étiquette du nœud correspond à l'affinité du nœud définie dans. deployment.yaml

    Le pod avec les tolérances et l'affinité des nœuds doit être placé sur un nœud avec les teintes correspondantes et les étiquettes d'affinité des nœuds. La commande précédente vous indique les taches sur le nœud. Voici un exemple de sortie.

    kubectl describe node ip-192-168-29-181.us-west-1.compute.internal | grep -A 1 "Taints" Taints:             classifled_workload=true:NoSchedule                     machine_learning_workload=true:NoSchedule

    En outre, exécutez la commande suivante pour vérifier que le nœud sur lequel le Pod est placé possède une étiquette correspondant à celle du nœud d'affinité du nœud.

    kubectl get node <node name> --show-labels
  4. Pour vérifier que l'application fait ce qu'elle est censée faire, consultez les journaux du Pod en exécutant la commande suivante.

    kubectl logs -f <name-of-the-pod>
Développeur d'applications, DevOps ingénieur, AWS DevOps

Créez un deuxième fichier de déploiement .yaml sans tolérance ni affinité de nœud.

Cette étape supplémentaire consiste à valider que lorsqu'aucune affinité ou tolérance de nœud n'est spécifiée dans le fichier manifeste de déploiement, le Pod résultant n'est pas planifié sur un nœud présentant des entaches. (Il doit être planifié sur un nœud qui ne présente aucune trace). Utilisez le code suivant pour créer un nouveau fichier de déploiement appelédeploy_no_taint.yaml.

apiVersion: apps/v1 kind: Deployment metadata: name: microservice-deployment-non-tainted spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: java-microservice-no-taint template: metadata: labels: app.kubernetes.io/name: java-microservice-no-taint spec: containers: - name: java-microservice-container-2 image: <account_number>.dkr.ecr<region>.amazonaws.com/<repository_name>:latest ports: - containerPort: 4567
Développeur d'applications, AWS DevOps, DevOps ingénieur

Déployez le deuxième fichier .yaml de déploiement et validez le placement du Pod

  1. Exécutez la commande suivante.

    kubectl apply -f deploy_no_taint.yaml
  2. Une fois le déploiement réussi, exécutez les mêmes commandes que celles que vous avez exécutées précédemment pour vérifier le placement du Pod dans un groupe de nœuds sans aucune altération.

    kubectl describe node <node_name> | grep "Taints"

    Le résultat doit être le suivant.

    Taints: <none>

    Ceci termine le test.

Développeur d'applications, AWS DevOps, DevOps ingénieur

Déploiement sur Amazon EKS

TâcheDescriptionCompétences requises

Créez le fichier deployment.yaml.

Pour créer le deployment.yaml fichier, utilisez le code de la section Informations supplémentaires.

Dans le code, la clé de l'affinité des nœuds est toute étiquette que vous créez lors de la création de groupes de nœuds. Ce modèle utilise l'étiquette par défaut créée par eksctl. Pour plus d'informations sur la personnalisation des étiquettes, consultez la section Affectation de pods à des nœuds dans la documentation de Kubernetes.

La valeur de la clé d'affinité de nœud est le nom du groupe de nœuds créé parcluster.yaml.

Pour obtenir la clé et la valeur de la tache, exécutez la commande suivante.

kubectl get nodes -o json | jq '.items[].spec.taints'

L'image est l'URI du référentiel Amazon ECR que vous avez créé lors d'une étape précédente.

AWS DevOps, DevOps ingénieur, développeur d'applications

Déployez le fichier.

Pour effectuer un déploiement sur Amazon EKS, exécutez la commande suivante.

kubectl apply -f deployment.yaml
Développeur d'applications, DevOps ingénieur, AWS DevOps

Vérifiez le déploiement.

  1. Pour vérifier si les pods sont prêts, exécutez la commande suivante.

    kubectl get pods -o wide

    Si le POD est prêt, la sortie doit ressembler à ce qui suit, avec le code « STATUS En cours d'exécution ».

    NAME        READY    STATUS    RESTARTS   AGE   IP  NODE  NOMINATED NODE   READINESS GATES <pod_name>   1/1     Running   0          12d   192.168.18.50   ip-192-168-20-110.us-west-1.compute.internal   <none>           <none>

    Notez le nom du Pod et le nom du nœud. Vous pouvez ignorer l'étape suivante.

  2. (Facultatif) Pour obtenir des informations supplémentaires sur le Pod et vérifier les tolérances sur le Pod, exécutez la commande suivante.

    kubectl describe pod <pod_name>

    Un exemple de sortie se trouve dans la section Informations supplémentaires.

  3. Pour vérifier que le placement du Pod sur le nœud est correct, exécutez la commande suivante.

    kubectl describe node <node name> | grep -A 1 "Taints"

    Vérifiez que la souillure du nœud correspond à la tolérance et que l'étiquette du nœud correspond à l'affinité du nœud définie dans. deployment.yaml

    Le pod avec les tolérances et l'affinité des nœuds doit être placé sur un nœud avec les teintes correspondantes et les étiquettes d'affinité des nœuds. La commande précédente vous indique les taches sur le nœud. Voici un exemple de sortie.

    kubectl describe node ip-192-168-29-181.us-west-1.compute.internal | grep -A 1 "Taints" Taints:             classifled_workload=true:NoSchedule                     machine_learning_workload=true:NoSchedule

    En outre, exécutez la commande suivante pour vérifier que le nœud sur lequel le Pod est placé possède une étiquette correspondant à celle du nœud d'affinité du nœud.

    kubectl get node <node name> --show-labels
  4. Pour vérifier que l'application fait ce qu'elle est censée faire, consultez les journaux du Pod en exécutant la commande suivante.

    kubectl logs -f <name-of-the-pod>
Développeur d'applications, DevOps ingénieur, AWS DevOps

Créez un deuxième fichier de déploiement .yaml sans tolérance ni affinité de nœud.

Cette étape supplémentaire consiste à valider que lorsqu'aucune affinité ou tolérance de nœud n'est spécifiée dans le fichier manifeste de déploiement, le Pod résultant n'est pas planifié sur un nœud présentant des entaches. (Il doit être planifié sur un nœud qui ne présente aucune trace). Utilisez le code suivant pour créer un nouveau fichier de déploiement appelédeploy_no_taint.yaml.

apiVersion: apps/v1 kind: Deployment metadata: name: microservice-deployment-non-tainted spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: java-microservice-no-taint template: metadata: labels: app.kubernetes.io/name: java-microservice-no-taint spec: containers: - name: java-microservice-container-2 image: <account_number>.dkr.ecr<region>.amazonaws.com/<repository_name>:latest ports: - containerPort: 4567
Développeur d'applications, AWS DevOps, DevOps ingénieur

Déployez le deuxième fichier .yaml de déploiement et validez le placement du Pod

  1. Exécutez la commande suivante.

    kubectl apply -f deploy_no_taint.yaml
  2. Une fois le déploiement réussi, exécutez les mêmes commandes que celles que vous avez exécutées précédemment pour vérifier le placement du Pod dans un groupe de nœuds sans aucune altération.

    kubectl describe node <node_name> | grep "Taints"

    Le résultat doit être le suivant.

    Taints: <none>

    Ceci termine le test.

Développeur d'applications, AWS DevOps, DevOps ingénieur
TâcheDescriptionCompétences requises

Nettoyez les ressources.

Pour éviter d'avoir à payer des frais AWS pour les ressources qui restent en cours d'exécution, utilisez la commande suivante.

eksctl delete cluster --name <Name of the cluster> --region <region-code>
AWS DevOps, développeur d'applications

Nettoyage des ressources

TâcheDescriptionCompétences requises

Nettoyez les ressources.

Pour éviter d'avoir à payer des frais AWS pour les ressources qui restent en cours d'exécution, utilisez la commande suivante.

eksctl delete cluster --name <Name of the cluster> --region <region-code>
AWS DevOps, développeur d'applications

Résolution des problèmes

ProblèmeSolution

Certaines de ces commandes risquent de ne pas s'exécuter si votre système utilise l'architecture arm64 (en particulier si vous l'exécutez sur un Mac M1). Il se peut que la ligne suivante comporte une erreur.

FROM adoptopenjdk/openjdk11:jdk-11.0.14.1_1-alpine

Si vous rencontrez des erreurs lors de l'exécution du Dockerfile, remplacez la FROM ligne par la ligne suivante.

FROM bellsoft/liberica-openjdk-alpine-musl:17

Ressources connexes

Informations supplémentaires

deployment.yaml

apiVersion: apps/v1 kind: Deployment metadata: name: microservice-deployment spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: java-microservice template: metadata: labels: app.kubernetes.io/name: java-microservice spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: alpha.eksctl.io/nodegroup-name operator: In values: - <node-group-name-from-cluster.yaml> tolerations: #only this pod has toleration and is viable to go to ng with taint - key: "<Taint key>" #classified_workload in our case operator: Equal value: "<Taint value>" #true effect: "NoSchedule" - key: "<Taint key>" #machine_learning_workload in our case operator: Equal value: "<Taint value>" #true effect: "NoSchedule" containers: - name: java-microservice-container image: <account_number>.dkr.ecr<region>.amazonaws.com/<repository_name>:latest ports: - containerPort: 4567

décrire un exemple de sortie du pod

Name: microservice-deployment-in-tainted-nodes-5684cc495b-vpcfx Namespace: default Priority: 0 Node: ip-192-168-29-181.us-west-1.compute.internal/192.168.29.181 Start Time: Wed, 14 Sep 2022 11:06:47 -0400 Labels: app.kubernetes.io/name=java-microservice-taint pod-template-hash=5684cc495b Annotations: kubernetes.io/psp: eks.privileged Status: Running IP: 192.168.13.44 IPs: IP: 192.168.13.44 Controlled By: ReplicaSet/microservice-deployment-in-tainted-nodes-5684cc495b Containers: java-microservice-container-1: Container ID: docker://5c158df8cc160de8f57f62f3ee16b12725a87510a809d90a1fb9e5d873c320a4 Image: 934188034500.dkr.ecr.us-east-1.amazonaws.com/java-eks-apg Image ID: docker-pullable://934188034500.dkr.ecr.us-east-1.amazonaws.com/java-eks-apg@sha256:d223924aca8315aab20d54eddf3443929eba511b6433017474d01b63a4114835 Port: 4567/TCP Host Port: 0/TCP State: Running Started: Wed, 14 Sep 2022 11:07:02 -0400 Ready: True Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-ddvvw (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: kube-api-access-ddvvw: Type: Projected (a volume that contains injected data from multiple sources) TokenExpirationSeconds: 3607 ConfigMapName: kube-root-ca.crt ConfigMapOptional: <nil> DownwardAPI: true QoS Class: BestEffort Node-Selectors: <none> Tolerations: classifled_workload=true:NoSchedule machine_learning_workload=true:NoSchedule node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: <none>
ConfidentialitéConditions d'utilisation du sitePréférences de cookies
© 2025, Amazon Web Services, Inc. ou ses affiliés. Tous droits réservés.