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.
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.
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 deIn
,NotIn
,Exists
ouDoesNotExist
.
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 deIn
,NotIn
,Exists
ouDoesNotExist
.
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
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
Lors de la création d'autres pods, modifiez la spécification
Pod
comme suit :-
Utilisez la strophe
podAffinity
pour configurer le paramètrerequiredDuringSchedulingIgnoredDuringExecution
ou le paramètrepreferredDuringSchedulingIgnoredDuringExecution
: 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
etvalue
que l'étiquette du premier module.podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: security operator: In values: - S1 topologyKey: failure-domain.beta.kubernetes.io/zone
-
operator
L'opérateur peut êtreIn
,NotIn
,Exists
ouDoesNotExist
. Par exemple, utilisez l'opérateurIn
pour exiger que l'étiquette soit dans le nœud. -
Spécifiez un
topologyKey
, qui est un label Kubernetes prérempli que le système utilise pour désigner un tel domaine topologique.
-
Utilisez la strophe
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
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
-
Lorsque vous créez d'autres pods, modifiez la spécification
Pod
pour définir les paramètres suivants : Utilisez la strophe
podAntiAffinity
pour configurer le paramètrerequiredDuringSchedulingIgnoredDuringExecution
ou le paramètrepreferredDuringSchedulingIgnoredDuringExecution
:- Spécifiez un poids pour le nœud, 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 ne soit pas programmé avec l'autre module, utilisez les mêmes paramètres
key
etvalue
que l'étiquette du premier module.podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: security operator: In values: - S2 topologyKey: kubernetes.io/hostname
- Pour une règle préférentielle, spécifiez un poids, 1-100.
-
operator
L'opérateur peut êtreIn
,NotIn
,Exists
ouDoesNotExist
. Par exemple, utilisez l'opérateurIn
pour exiger que l'étiquette soit dans le nœud.
-
Spécifiez un
topologyKey
, qui est un label Kubernetes prérempli que le système utilise pour désigner un tel domaine topologique. 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
souspodAffinity
.$ 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
souspodAntiAffinity
.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
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 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 :
- 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: 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 unpodAntiAffinity
.
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>