Rechercher

3.4. Contrôle du placement des pods sur les nœuds à l'aide de règles d'affinité des nœuds

download PDF

L'affinité est une propriété des pods qui contrôle les nœuds sur lesquels ils préfèrent être programmés.

Dans OpenShift Container Platform, l'affinité des nœuds est un ensemble de règles utilisées par le planificateur pour déterminer où un pod peut être placé. Les règles sont définies à l'aide d'étiquettes personnalisées sur les nœuds et de sélecteurs d'étiquettes spécifiés dans les pods.

3.4.1. Comprendre l'affinité des nœuds

L'affinité de nœud permet à un pod de spécifier une affinité envers un groupe de nœuds sur lesquels il peut être placé. Le nœud n'a pas de contrôle sur le placement.

Par exemple, vous pouvez configurer un module pour qu'il ne s'exécute que sur un nœud doté d'une unité centrale spécifique ou dans une zone de disponibilité spécifique.

Il existe deux types de règles d'affinité entre les nœuds : required et preferred.

Les règles obligatoires must doivent être respectées pour qu'un pod puisse être programmé sur un nœud. Les règles préférentielles précisent que, si la règle est respectée, l'ordonnanceur tente de l'appliquer, mais ne la garantit pas.

Note

Si les étiquettes d'un nœud changent au moment de l'exécution et que la règle d'affinité d'un nœud pour un module n'est plus respectée, le module continue de fonctionner sur le nœud.

Vous configurez l'affinité des nœuds par le biais du fichier Pod spec. Vous pouvez spécifier une règle obligatoire, une règle préférentielle ou les deux. Si vous spécifiez les deux, le nœud doit d'abord satisfaire à la règle requise, puis tente de satisfaire à la règle préférée.

L'exemple suivant est une spécification Pod avec une règle qui exige que le pod soit placé sur un nœud avec une étiquette dont la clé est e2e-az-NorthSouth et dont la valeur est soit e2e-az-North soit e2e-az-South:

Exemple de fichier de configuration d'un pod avec une règle d'affinité de nœud requise

apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity: 1
      requiredDuringSchedulingIgnoredDuringExecution: 2
        nodeSelectorTerms:
        - matchExpressions:
          - key: e2e-az-NorthSouth 3
            operator: In 4
            values:
            - e2e-az-North 5
            - e2e-az-South 6
  containers:
  - name: with-node-affinity
    image: docker.io/ocpqe/hello-pod

1
La strophe pour configurer l'affinité des nœuds.
2
Définit une règle obligatoire.
3 5 6
La paire clé/valeur (étiquette) qui doit être prise en compte pour appliquer la règle.
4
L'opérateur représente la relation entre l'étiquette du nœud et l'ensemble des valeurs des paramètres matchExpression dans la spécification Pod. Cette valeur peut être In, NotIn, Exists, ou DoesNotExist, Lt, ou Gt.

L'exemple suivant est une spécification de nœud avec une règle de préférence selon laquelle un nœud avec une étiquette dont la clé est e2e-az-EastWest et dont la valeur est soit e2e-az-East soit e2e-az-West est préféré pour le pod :

Exemple de fichier de configuration d'un pod avec une règle préférentielle d'affinité de nœud

apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity: 1
      preferredDuringSchedulingIgnoredDuringExecution: 2
      - weight: 1 3
        preference:
          matchExpressions:
          - key: e2e-az-EastWest 4
            operator: In 5
            values:
            - e2e-az-East 6
            - e2e-az-West 7
  containers:
  - name: with-node-affinity
    image: docker.io/ocpqe/hello-pod

1
La strophe pour configurer l'affinité des nœuds.
2
Définit une règle préférentielle.
3
Spécifie un poids pour une règle préférentielle. Le nœud ayant le poids le plus élevé est privilégié.
4 6 7
La paire clé/valeur (étiquette) qui doit être prise en compte pour appliquer la règle.
5
L'opérateur représente la relation entre l'étiquette du nœud et l'ensemble des valeurs des paramètres matchExpression dans la spécification Pod. Cette valeur peut être In, NotIn, Exists, ou DoesNotExist, Lt, ou Gt.

Il n'existe pas de concept explicite node anti-affinity, mais l'utilisation de l'opérateur NotIn ou DoesNotExist reproduit ce comportement.

Note

Si vous utilisez l'affinité de nœuds et les sélecteurs de nœuds dans la même configuration de pods, notez ce qui suit :

  • Si vous configurez à la fois nodeSelector et nodeAffinity, les deux conditions doivent être remplies pour que le pod soit planifié sur un nœud candidat.
  • Si vous spécifiez plusieurs nodeSelectorTerms associés à des types nodeAffinity, le module peut être programmé sur un nœud si l'un des nodeSelectorTerms est satisfait.
  • Si vous spécifiez plusieurs matchExpressions associés à nodeSelectorTerms, le module ne peut être programmé sur un nœud que si tous les matchExpressions sont satisfaits.

3.4.2. Configuration d'une règle d'affinité de nœud requise

Les règles requises must doivent être respectées avant qu'un pod puisse être programmé sur un nœud.

Procédure

Les étapes suivantes présentent une configuration simple qui crée un nœud et un module que l'ordonnanceur doit placer sur le nœud.

  1. Ajoutez une étiquette à un nœud à l'aide de la commande oc label node:

    $ oc label node node1 e2e-az-name=e2e-az1
    Astuce

    Vous pouvez également appliquer le code YAML suivant pour ajouter l'étiquette :

    kind: Node
    apiVersion: v1
    metadata:
      name: <node_name>
      labels:
        e2e-az-name: e2e-az1
  2. Dans la spécification Pod, utilisez la strophe nodeAffinity pour configurer le paramètre requiredDuringSchedulingIgnoredDuringExecution:

    1. Spécifiez la clé et les valeurs qui doivent être respectées. Si vous souhaitez que le nouveau module soit planifié sur le nœud que vous avez modifié, utilisez les mêmes paramètres key et value que l'étiquette du nœud.
    2. operatorL'opérateur peut être In, NotIn, Exists, DoesNotExist, Lt ou Gt. Par exemple, utilisez l'opérateur In pour exiger que l'étiquette soit dans le nœud :

      Exemple de sortie

      spec:
        affinity:
          nodeAffinity:
            requiredDuringSchedulingIgnoredDuringExecution:
              nodeSelectorTerms:
              - matchExpressions:
                - key: e2e-az-name
                  operator: In
                  values:
                  - e2e-az1
                  - e2e-az2

  3. Créer la capsule :

    $ oc create -f e2e-az2.yaml

3.4.3. Configuration d'une règle d'affinité pour les nœuds préférés

Les règles préférentielles précisent que, si la règle est respectée, l'ordonnanceur tente d'appliquer les règles, mais n'en garantit pas l'application.

Procédure

Les étapes suivantes présentent une configuration simple qui crée un nœud et un module que l'ordonnanceur tente de placer sur le nœud.

  1. Ajoutez une étiquette à un nœud à l'aide de la commande oc label node:

    $ oc label node node1 e2e-az-name=e2e-az3
  2. Dans la spécification Pod, utilisez la strophe nodeAffinity pour configurer le paramètre preferredDuringSchedulingIgnoredDuringExecution:

    1. Spécifiez un poids pour le nœud, sous la forme d'un nombre de 1 à 100. Le nœud ayant le poids le plus élevé est privilégié.
    2. Spécifiez la clé et les valeurs qui doivent être respectées. Si vous souhaitez que le nouveau module soit planifié sur le nœud que vous avez modifié, utilisez les mêmes paramètres key et value que l'étiquette du nœud :

      spec:
        affinity:
          nodeAffinity:
            preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 1
              preference:
                matchExpressions:
                - key: e2e-az-name
                  operator: In
                  values:
                  - e2e-az3
    3. operatorL'opérateur peut être In, NotIn, Exists, DoesNotExist, Lt ou Gt. Par exemple, utilisez l'opérateur In pour exiger que l'étiquette soit dans le nœud.
  3. Créer la capsule.

    $ oc create -f e2e-az3.yaml

3.4.4. Exemple de règles d'affinité entre les nœuds

Les exemples suivants illustrent l'affinité entre les nœuds.

3.4.4.1. Affinité des nœuds avec les étiquettes correspondantes

L'exemple suivant illustre l'affinité d'un nœud et d'un module avec des étiquettes correspondantes :

  • Le nœud Node1 porte l'étiquette zone:us:

    $ oc label node node1 zone=us
    Astuce

    Vous pouvez également appliquer le code YAML suivant pour ajouter l'étiquette :

    kind: Node
    apiVersion: v1
    metadata:
      name: <node_name>
      labels:
        zone: us
  • Le pod-s1 possède la paire clé/valeur zone et us en vertu d'une règle d'affinité de nœud requise :

    $ cat pod-s1.yaml

    Exemple de sortie

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-s1
    spec:
      containers:
        - image: "docker.io/ocpqe/hello-pod"
          name: hello-pod
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                - key: "zone"
                  operator: In
                  values:
                  - us

  • Le pod-s1 peut être programmé sur le nœud 1 :

    $ oc get pod -o wide

    Exemple de sortie

    NAME     READY     STATUS       RESTARTS   AGE      IP      NODE
    pod-s1   1/1       Running      0          4m       IP1     node1

3.4.4.2. Affinité des nœuds sans étiquettes correspondantes

L'exemple suivant illustre l'affinité de nœud pour un nœud et un module sans étiquettes correspondantes :

  • Le nœud Node1 porte l'étiquette zone:emea:

    $ oc label node node1 zone=emea
    Astuce

    Vous pouvez également appliquer le code YAML suivant pour ajouter l'étiquette :

    kind: Node
    apiVersion: v1
    metadata:
      name: <node_name>
      labels:
        zone: emea
  • Le pod-s1 possède la paire clé/valeur zone et us en vertu d'une règle d'affinité de nœud requise :

    $ cat pod-s1.yaml

    Exemple de sortie

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-s1
    spec:
      containers:
        - image: "docker.io/ocpqe/hello-pod"
          name: hello-pod
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                - key: "zone"
                  operator: In
                  values:
                  - us

  • Le pod-s1 ne peut pas être planifié sur le nœud 1 :

    $ oc describe pod pod-s1

    Exemple de sortie

    ...
    
    Events:
     FirstSeen LastSeen Count From              SubObjectPath  Type                Reason
     --------- -------- ----- ----              -------------  --------            ------
     1m        33s      8     default-scheduler Warning        FailedScheduling    No nodes are available that match all of the following predicates:: MatchNodeSelector (1).

3.4.5. Utilisation de l'affinité des nœuds pour contrôler l'emplacement d'installation d'un opérateur

Par défaut, lorsque vous installez un Operator, OpenShift Container Platform installe le pod Operator sur l'un de vos nœuds de travail de manière aléatoire. Cependant, il peut y avoir des situations où vous voulez que ce pod soit planifié sur un nœud spécifique ou un ensemble de nœuds.

Les exemples suivants décrivent des situations dans lesquelles vous pourriez vouloir planifier un pod opérateur sur un nœud ou un ensemble de nœuds spécifique :

  • Si un opérateur a besoin d'une plateforme particulière, telle que amd64 ou arm64
  • Si un opérateur nécessite un système d'exploitation particulier, tel que Linux ou Windows
  • Si vous souhaitez que les opérateurs qui travaillent ensemble soient programmés sur le même hôte ou sur des hôtes situés sur le même rack
  • Si vous souhaitez que les opérateurs soient dispersés dans l'infrastructure afin d'éviter les temps d'arrêt dus à des problèmes de réseau ou de matériel

Vous pouvez contrôler l'endroit où un pod d'opérateur est installé en ajoutant des contraintes d'affinité de nœud à l'objet Subscription de l'opérateur.

Les exemples suivants montrent comment utiliser l'affinité entre les nœuds pour installer une instance de Custom Metrics Autoscaler Operator sur un nœud spécifique de la grappe :

Exemple d'affinité de nœud qui place le pod de l'opérateur sur un nœud spécifique

apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: openshift-custom-metrics-autoscaler-operator
  namespace: openshift-keda
spec:
  name: my-package
  source: my-operators
  sourceNamespace: operator-registries
  config:
    affinity:
      nodeAffinity: 1
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
          - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
              - ip-10-0-163-94.us-west-2.compute.internal
 ...

1
Une affinité de nœud qui exige que le pod de l'opérateur soit programmé sur un nœud nommé ip-10-0-163-94.us-west-2.compute.internal.

Exemple d'affinité de nœud qui place le pod de l'opérateur sur un nœud avec une plate-forme spécifique

apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: openshift-custom-metrics-autoscaler-operator
  namespace: openshift-keda
spec:
  name: my-package
  source: my-operators
  sourceNamespace: operator-registries
  config:
    affinity:
      nodeAffinity: 1
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
          - matchExpressions:
            - key: kubernetes.io/arch
              operator: In
              values:
              - arm64
            - key: kubernetes.io/os
              operator: In
              values:
              - linux

1
Une affinité de nœud qui exige que le pod de l'opérateur soit programmé sur un nœud avec les étiquettes kubernetes.io/arch=arm64 et kubernetes.io/os=linux.

Procédure

Pour contrôler l'emplacement d'une nacelle d'opérateur, procédez comme suit :

  1. Installez l'opérateur comme d'habitude.
  2. Si nécessaire, assurez-vous que vos nœuds sont étiquetés de manière à répondre correctement à l'affinité.
  3. Modifiez l'objet Operator Subscription pour ajouter une affinité :

    apiVersion: operators.coreos.com/v1alpha1
    kind: Subscription
    metadata:
      name: openshift-custom-metrics-autoscaler-operator
      namespace: openshift-keda
    spec:
      name: my-package
      source: my-operators
      sourceNamespace: operator-registries
      config:
        affinity: 1
          nodeAffinity:
            requiredDuringSchedulingIgnoredDuringExecution:
              nodeSelectorTerms:
              - matchExpressions:
                - key: kubernetes.io/hostname
                  operator: In
                  values:
                  - ip-10-0-185-229.ec2.internal
     ...
    1
    Ajouter un nodeAffinity.

Vérification

  • Pour s'assurer que le pod est déployé sur le nœud spécifique, exécutez la commande suivante :

    $ oc get pods -o wide

    Exemple de sortie

    NAME                                                  READY   STATUS    RESTARTS   AGE   IP            NODE                           NOMINATED NODE   READINESS GATES
    custom-metrics-autoscaler-operator-5dcc45d656-bhshg   1/1     Running   0          50s   10.131.0.20   ip-10-0-185-229.ec2.internal   <none>           <none>

3.4.6. Ressources supplémentaires

Red Hat logoGithubRedditYoutubeTwitter

Apprendre

Essayez, achetez et vendez

Communautés

À propos de la documentation Red Hat

Nous aidons les utilisateurs de Red Hat à innover et à atteindre leurs objectifs grâce à nos produits et services avec un contenu auquel ils peuvent faire confiance.

Rendre l’open source plus inclusif

Red Hat s'engage à remplacer le langage problématique dans notre code, notre documentation et nos propriétés Web. Pour plus de détails, consultez leBlog Red Hat.

À propos de Red Hat

Nous proposons des solutions renforcées qui facilitent le travail des entreprises sur plusieurs plates-formes et environnements, du centre de données central à la périphérie du réseau.

© 2024 Red Hat, Inc.