3.3. Placement de nacelles par rapport à d'autres nacelles à l'aide de règles d'affinité et d'anti-affinité


L'affinité est une propriété des modules qui contrôle les nœuds sur lesquels ils préfèrent être programmés. L'anti-affinité est une propriété des modules qui empêche un module d'être programmé sur un nœud.

Dans OpenShift Container Platform, pod affinity et pod anti-affinity vous permettent de limiter les nœuds sur lesquels votre pod peut être planifié en fonction des étiquettes clé/valeur des autres pods.

3.3.1. Comprendre l'affinité des pods

Pod affinity et pod anti-affinity vous permettent de limiter les nœuds sur lesquels votre module peut être planifié en fonction des étiquettes clé/valeur des autres modules.

  • L'affinité de pod peut indiquer à l'ordonnanceur de placer un nouveau pod sur le même nœud que d'autres pods si le sélecteur d'étiquette du nouveau pod correspond à l'étiquette du pod actuel.
  • L'anti-affinité des pods peut empêcher l'ordonnanceur de localiser un nouveau pod sur le même nœud que les pods ayant les mêmes étiquettes si le sélecteur d'étiquette du nouveau pod correspond à l'étiquette du pod actuel.

Par exemple, les règles d'affinité permettent de répartir ou de regrouper les modules au sein d'un service ou par rapport aux modules d'autres services. Les règles anti-affinité vous permettent d'empêcher les pods d'un service particulier d'être planifiés sur les mêmes nœuds que les pods d'un autre service dont on sait qu'ils interfèrent avec les performances des pods du premier service. Vous pouvez également répartir les modules d'un service entre les nœuds, les zones de disponibilité ou les ensembles de disponibilité afin de réduire les défaillances corrélées.

Note

Un sélecteur d'étiquettes peut faire correspondre des pods avec plusieurs déploiements de pods. Utilisez des combinaisons uniques d'étiquettes lors de la configuration des règles d'anti-affinité afin d'éviter de faire correspondre les pods.

Il existe deux types de règles d'affinité pour les pods : 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

En fonction des paramètres de priorité et de préemption des modules, il se peut que l'ordonnanceur ne soit pas en mesure de trouver un nœud approprié pour un module sans enfreindre les exigences d'affinité. Dans ce cas, il se peut qu'un module ne soit pas planifié.

Pour éviter cette situation, configurez soigneusement l'affinité des pods avec des pods de priorité égale.

Vous configurez l'affinité/anti-affinité des pods par le biais des fichiers spec de Pod. 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 montre une spécification Pod configurée pour l'affinité et l'anti-affinité des pods.

Dans cet exemple, la règle d'affinité des pods indique que le pod ne peut être programmé sur un nœud que si ce nœud possède au moins un pod déjà en cours d'exécution dont l'étiquette a la clé security et la valeur S1. La règle d'anti-affinité du pod indique que le pod préfère ne pas être programmé sur un nœud si ce nœud exécute déjà un pod avec une étiquette ayant la clé security et la valeur S2.

Exemple de fichier de configuration Pod avec pod affinity

apiVersion: v1
kind: Pod
metadata:
  name: with-pod-affinity
spec:
  affinity:
    podAffinity: 1
      requiredDuringSchedulingIgnoredDuringExecution: 2
      - labelSelector:
          matchExpressions:
          - key: security 3
            operator: In 4
            values:
            - S1 5
        topologyKey: failure-domain.beta.kubernetes.io/zone
  containers:
  - name: with-pod-affinity
    image: docker.io/ocpqe/hello-pod

1
Stanza pour configurer l'affinité des pods.
2
Définit une règle obligatoire.
3 5
La clé et la valeur (étiquette) qui doivent correspondre pour appliquer la règle.
4
L'opérateur représente la relation entre l'étiquette de la capsule existante et l'ensemble des valeurs des paramètres matchExpression dans la spécification de la nouvelle capsule. Il peut s'agir de In, NotIn, Exists ou DoesNotExist.

Exemple de fichier de configuration Pod avec pod anti-affinité

apiVersion: v1
kind: Pod
metadata:
  name: with-pod-antiaffinity
spec:
  affinity:
    podAntiAffinity: 1
      preferredDuringSchedulingIgnoredDuringExecution: 2
      - weight: 100  3
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: security 4
              operator: In 5
              values:
              - S2
          topologyKey: kubernetes.io/hostname
  containers:
  - name: with-pod-affinity
    image: docker.io/ocpqe/hello-pod

1
Stanza pour configurer l'anti-affinité du pod.
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
Description de l'étiquette du pod qui détermine quand la règle anti-affinité s'applique. Spécifiez une clé et une valeur pour l'étiquette.
5
L'opérateur représente la relation entre l'étiquette de la capsule existante et l'ensemble des valeurs des paramètres matchExpression dans la spécification de la nouvelle capsule. Il peut s'agir de In, NotIn, Exists ou DoesNotExist.
Note

Si les étiquettes d'un nœud changent au moment de l'exécution, de sorte que les règles d'affinité d'un module ne sont plus respectées, le module continue de fonctionner sur le nœud.

3.3.2. Configuration d'une règle d'affinité pour les pods

Les étapes suivantes illustrent une configuration simple à deux pods qui crée un pod avec une étiquette et un pod qui utilise l'affinité pour permettre la planification avec ce pod.

Procédure

  1. Créer un pod avec une étiquette spécifique dans la spécification Pod:

    $ cat team4.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: security-s1
      labels:
        security: S1
    spec:
      containers:
      - name: security-s1
        image: docker.io/ocpqe/hello-pod
  2. Lors de la création d'autres pods, modifiez la spécification Pod comme suit :

    1. Utilisez la strophe podAffinity pour configurer le paramètre requiredDuringSchedulingIgnoredDuringExecution ou le paramètre preferredDuringSchedulingIgnoredDuringExecution:
    2. Spécifiez la clé et la valeur qui doivent être respectées. Si vous souhaitez que le nouveau module soit programmé avec l'autre module, utilisez les mêmes paramètres key et value que l'étiquette du premier module.

          podAffinity:
            requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                - key: security
                  operator: In
                  values:
                  - S1
              topologyKey: failure-domain.beta.kubernetes.io/zone
    3. operatorL'opérateur peut être In, NotIn, Exists ou DoesNotExist. Par exemple, utilisez l'opérateur In pour exiger que l'étiquette soit dans le nœud.
    4. Spécifiez un topologyKey, qui est un label Kubernetes prérempli que le système utilise pour désigner un tel domaine topologique.
  3. Créer la capsule.

    oc create -f <pod-spec>.yaml

3.3.3. Configuration d'une règle d'anti-affinité pour les pods

Les étapes suivantes illustrent une configuration simple à deux pods qui crée un pod avec une étiquette et un pod qui utilise une règle préférentielle anti-affinité pour tenter d'empêcher l'ordonnancement avec ce pod.

Procédure

  1. Créer un pod avec une étiquette spécifique dans la spécification Pod:

    $ cat team4.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: security-s2
      labels:
        security: S2
    spec:
      containers:
      - name: security-s2
        image: docker.io/ocpqe/hello-pod
  2. Lorsque vous créez d'autres pods, modifiez la spécification Pod pour définir les paramètres suivants :
  3. Utilisez la strophe podAntiAffinity pour configurer le paramètre requiredDuringSchedulingIgnoredDuringExecution ou le paramètre preferredDuringSchedulingIgnoredDuringExecution:

    1. Spécifiez un poids pour le nœud, 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 ne soit pas programmé avec l'autre module, utilisez les mêmes paramètres key et value que l'étiquette du premier module.

          podAntiAffinity:
            preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 100
              podAffinityTerm:
                labelSelector:
                  matchExpressions:
                  - key: security
                    operator: In
                    values:
                    - S2
                topologyKey: kubernetes.io/hostname
    3. Pour une règle préférentielle, spécifiez un poids, 1-100.
    4. operatorL'opérateur peut être In, NotIn, Exists ou DoesNotExist. Par exemple, utilisez l'opérateur In pour exiger que l'étiquette soit dans le nœud.
  4. Spécifiez un topologyKey, qui est un label Kubernetes prérempli que le système utilise pour désigner un tel domaine topologique.
  5. Créer la capsule.

    oc create -f <pod-spec>.yaml

3.3.4. Exemple de règles d'affinité et d'anti-affinité pour les pods

Les exemples suivants illustrent l'affinité et l'anti-affinité des pods.

3.3.4.1. Pod Affinity

L'exemple suivant illustre l'affinité des pods avec des étiquettes et des sélecteurs d'étiquettes correspondants.

  • Le pod team4 porte l'étiquette team:4.

    $ cat team4.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: team4
      labels:
         team: "4"
    spec:
      containers:
      - name: ocp
        image: docker.io/ocpqe/hello-pod
  • Le pod team4a a le sélecteur d'étiquettes team:4 sous podAffinity.

    $ cat pod-team4a.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: team4a
    spec:
      affinity:
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: team
                operator: In
                values:
                - "4"
            topologyKey: kubernetes.io/hostname
      containers:
      - name: pod-affinity
        image: docker.io/ocpqe/hello-pod
  • Le module team4a est programmé sur le même nœud que le module team4.

3.3.4.2. Pod Anti-affinité

L'exemple suivant illustre l'anti-affinité des pods pour les pods dont les étiquettes et les sélecteurs d'étiquettes correspondent.

  • Le pod pod-s1 porte l'étiquette security:s1.

    cat pod-s1.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-s1
      labels:
        security: s1
    spec:
      containers:
      - name: ocp
        image: docker.io/ocpqe/hello-pod
  • Le pod pod-s2 a le sélecteur d'étiquettes security:s1 sous podAntiAffinity.

    cat pod-s2.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-s2
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: security
                operator: In
                values:
                - s1
            topologyKey: kubernetes.io/hostname
      containers:
      - name: pod-antiaffinity
        image: docker.io/ocpqe/hello-pod
  • Le pod pod-s2 ne peut pas être programmé sur le même nœud que pod-s1.

3.3.4.3. Affinité podale sans étiquettes correspondantes

L'exemple suivant illustre l'affinité des pods pour les pods ne correspondant pas aux étiquettes et aux sélecteurs d'étiquettes.

  • Le pod pod-s1 porte l'étiquette security:s1.

    $ cat pod-s1.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-s1
      labels:
        security: s1
    spec:
      containers:
      - name: ocp
        image: docker.io/ocpqe/hello-pod
  • Le pod pod-s2 possède le sélecteur d'étiquettes security:s2.

    $ cat pod-s2.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-s2
    spec:
      affinity:
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: security
                operator: In
                values:
                - s2
            topologyKey: kubernetes.io/hostname
      containers:
      - name: pod-affinity
        image: docker.io/ocpqe/hello-pod
  • Le pod pod-s2 n'est pas planifié à moins qu'il n'y ait un nœud avec un pod ayant le label security:s2. S'il n'y a pas d'autre pod avec ce label, le nouveau pod reste en attente :

    Exemple de sortie

    NAME      READY     STATUS    RESTARTS   AGE       IP        NODE
    pod-s2    0/1       Pending   0          32s       <none>

3.3.5. Utilisation de l'affinité et de l'anti-affinité du pod pour contrôler l'endroit où un opérateur est installé

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 une affinité ou une anti-affinité de pod à l'objet Subscription de l'opérateur.

L'exemple suivant montre comment utiliser l'anti-affinité des pods pour empêcher l'installation de Custom Metrics Autoscaler Operator à partir de n'importe quel nœud ayant des pods avec une étiquette spécifique :

Exemple d'affinité de pod qui place le pod de l'opérateur sur un ou plusieurs nœuds spécifiques

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:
      podAffinity: 1
        requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values:
              - test
          topologyKey: kubernetes.io/hostname

1
Une affinité de pod qui place le pod de l'opérateur sur un nœud qui a des pods avec le label app=test.

Exemple d'anti-affinité de pods qui empêche le pod Operator d'accéder à un ou plusieurs nœuds spécifiques

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:
      podAntiAffinity: 1
        requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchExpressions:
            - key: cpu
              operator: In
              values:
              - high
          topologyKey: kubernetes.io/hostname
 ...

1
Une anti-affinité de pods qui empêche le pod de l'opérateur d'être planifié sur un nœud qui a des pods avec le label cpu=high.

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:
          podAntiAffinity: 1
            requiredDuringSchedulingIgnoredDuringExecution:
              podAffinityTerm:
                labelSelector:
                  matchExpressions:
                  - key: kubernetes.io/hostname
                    operator: In
                    values:
                    - ip-10-0-185-229.ec2.internal
                topologyKey: topology.kubernetes.io/zone
     ...
    1
    Ajouter un podAffinity ou un podAntiAffinity.

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>

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.