3.4. Contrôle du placement des pods sur les nœuds à l'aide de règles d'affinité des nœuds
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.
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écificationPod
. Cette valeur peut êtreIn
,NotIn
,Exists
, ouDoesNotExist
,Lt
, ouGt
.
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écificationPod
. Cette valeur peut êtreIn
,NotIn
,Exists
, ouDoesNotExist
,Lt
, ouGt
.
Il n'existe pas de concept explicite node anti-affinity, mais l'utilisation de l'opérateur NotIn
ou DoesNotExist
reproduit ce comportement.
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
etnodeAffinity
, 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 typesnodeAffinity
, le module peut être programmé sur un nœud si l'un desnodeSelectorTerms
est satisfait. -
Si vous spécifiez plusieurs
matchExpressions
associés ànodeSelectorTerms
, le module ne peut être programmé sur un nœud que si tous lesmatchExpressions
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.
Ajoutez une étiquette à un nœud à l'aide de la commande
oc label node
:$ oc label node node1 e2e-az-name=e2e-az1
AstuceVous 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
Dans la spécification
Pod
, utilisez la strophenodeAffinity
pour configurer le paramètrerequiredDuringSchedulingIgnoredDuringExecution
:-
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
etvalue
que l'étiquette du nœud. operator
L'opérateur peut êtreIn
,NotIn
,Exists
,DoesNotExist
,Lt
ouGt
. Par exemple, utilisez l'opérateurIn
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
-
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
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.
Ajoutez une étiquette à un nœud à l'aide de la commande
oc label node
:$ oc label node node1 e2e-az-name=e2e-az3
Dans la spécification
Pod
, utilisez la strophenodeAffinity
pour configurer le paramètrepreferredDuringSchedulingIgnoredDuringExecution
:- 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é.
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
etvalue
que l'étiquette du nœud :spec: affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: e2e-az-name operator: In values: - e2e-az3
-
operator
L'opérateur peut êtreIn
,NotIn
,Exists
,DoesNotExist
,Lt
ouGt
. Par exemple, utilisez l'opérateurIn
pour exiger que l'étiquette soit dans le nœud.
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
AstuceVous 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
etus
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
AstuceVous 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
etus
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
ouarm64
- 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
etkubernetes.io/os=linux
.
Procédure
Pour contrôler l'emplacement d'une nacelle d'opérateur, procédez comme suit :
- Installez l'opérateur comme d'habitude.
- Si nécessaire, assurez-vous que vos nœuds sont étiquetés de manière à répondre correctement à l'affinité.
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
- Pour plus d'informations sur la modification des étiquettes de nœuds, voir Comment mettre à jour les étiquettes des nœuds.