
Eviter certains noeuds : Taints et Tolerations
Maîtrisez les Taints et Tolerations dans Kubernetes pour empêcher ou autoriser l'ordonnancement de Pods sur des noeuds spécifiques et gérer l'éviction.
La logique inverse : repousser les Pods
Dans la section précédente, nous avons vu comment utiliser Node Affinity pour attirer les Pods vers des noeuds spécifiques en fonction de leurs labels. Kubernetes offre également un mécanisme complémentaire fonctionnant sur le principe inverse : les Taints et les Tolerations. Ce système permet de marquer des noeuds (avec des Taints) pour qu'ils repoussent les Pods, et de marquer des Pods (avec des Tolerations) pour leur permettre d'ignorer ces marques de répulsion et d'être quand même ordonnancés sur ces noeuds.
Cette approche est particulièrement utile pour :
- Dédier des noeuds à des usages spécifiques : Par exemple, marquer des noeuds avec GPU pour qu'ils n'acceptent que les Pods nécessitant explicitement des GPU (et ayant la tolérance appropriée).
- Gérer la maintenance des noeuds : Marquer un noeud comme étant en maintenance pour empêcher l'ordonnancement de nouveaux Pods et potentiellement évincer les Pods existants.
- Gérer automatiquement les conditions des noeuds : Kubernetes utilise lui-même ce mécanisme pour marquer les noeuds non prêts (
NotReady) ou sous pression (MemoryPressure) afin d'éviter d'y placer de nouvelles charges de travail.
Les Taints sont appliqués aux Noeuds, tandis que les Tolerations sont définies dans la spécification des Pods.
Taints : marquer les noeuds pour repousser les Pods
Un Taint est une propriété appliquée à un Noeud qui indique qu'il ne devrait pas accepter de Pods ne le tolérant pas spécifiquement. Un Taint est composé de trois éléments :
- Clé (Key) : Un nom pour le taint (ex: `gpu`, `dedicated`, `node.kubernetes.io/memory-pressure`).
- Valeur (Value) : Une valeur associée à la clé (ex: `true`, `nvidia-tesla-v100`, `team-a`). La valeur est facultative.
- Effet (Effect) : Définit ce qui arrive aux Pods qui ne tolèrent pas ce taint.
On ajoute un taint à un noeud à l'aide de la commande `kubectl taint` :
# Taint simple clé=valeur:Effet
kubectl taint node key1=value1:Effect
# Taint avec seulement une clé:Effet (pas de valeur)
kubectl taint node key2:Effect
# Exemple concret : Dédier un noeud à la team A
kubectl taint node node-gpu-1 dedicated=team-a:NoSchedule
# Pour supprimer un taint, on utilise la même commande avec un '-' à la fin
kubectl taint node node-gpu-1 dedicated=team-a:NoSchedule-
Les effets des Taints (`NoSchedule`, `PreferNoSchedule`, `NoExecute`)
L'effet d'un Taint détermine son impact sur les Pods :
NoSchedule: C'est l'effet le plus courant pour dédier des noeuds. Le Scheduler n'ordonnancera pas de nouveau Pod sur ce noeud, à moins que le Pod n'ait une tolérance correspondante pour ce taint. Cela n'affecte pas les Pods déjà en cours d'exécution sur le noeud.PreferNoSchedule: C'est une version 'douce' deNoSchedule. Le Scheduler essaiera d'éviter de placer un Pod qui ne tolère pas ce taint sur le noeud, mais il le fera s'il n'y a pas d'autre alternative viable (par exemple, si tous les autres noeuds ne sont pas faisables).NoExecute: C'est l'effet le plus fort. Non seulement il empêche l'ordonnancement de nouveaux Pods (commeNoSchedule), mais il provoque également l'éviction (suppression) des Pods déjà en cours d'exécution sur le noeud s'ils ne tolèrent pas ce taint. L'éviction peut être immédiate ou se produire après un certain délai défini dans la tolérance du Pod (tolerationSeconds). Kubernetes utilise cet effet pour les taints automatiques liés à l'état du noeud (ex:node.kubernetes.io/not-ready,node.kubernetes.io/unreachable).
Tolerations : permettre aux Pods d'ignorer les Taints
Une Toleration est une propriété définie dans la spécification d'un Pod (spec.tolerations) qui lui permet d'être ordonnancé (ou de rester en cours d'exécution) sur un noeud possédant un Taint correspondant.
Une tolérance doit correspondre au Taint qu'elle est censée tolérer. Une tolérance est définie par :
key: La clé du Taint à tolérer.operator: L'opérateur de correspondance. Peut êtreEqual(la valeur doit correspondre, c'est la valeur par défaut) ouExists(la clé doit exister, la valeur est ignorée).value: La valeur du Taint à tolérer (utilisée uniquement si `operator` est `Equal`).effect: L'effet du Taint à tolérer (NoSchedule,PreferNoSchedule,NoExecute). Si omis, la tolérance correspond à tous les effets pour la clé/valeur donnée.tolerationSeconds: Utilisé uniquement avec l'effetNoExecute. Spécifie la durée (en secondes) pendant laquelle le Pod restera lié au noeud après l'ajout du Taint (ou après que le noeud soit devenu non prêt). Passé ce délai, si le Taint est toujours présent, le Pod sera évincé. Une valeur nulle ou absente signifie une éviction immédiate.
Syntaxe et opérateurs des Tolerations
Voici comment définir des tolérances dans un manifeste de Pod :
apiVersion: v1
kind: Pod
metadata:
name: my-app-with-tolerations
spec:
containers:
- name: myapp
image: myapp
tolerations:
# Tolérance pour un taint spécifique key=value:Effect
- key: "dedicated"
operator: "Equal"
value: "team-a"
effect: "NoSchedule"
# Tolérance pour un taint avec une clé spécifique, peu importe la valeur (operator Exists)
- key: "special-hardware"
operator: "Exists"
effect: "NoSchedule"
# Tolérance pour un taint NoExecute (ex: noeud non prêt) avec délai d'attente
- key: "node.kubernetes.io/not-ready"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 300 # Attend 5 minutes avant éviction
# Tolérance générique pour tous les taints NoExecute (peut être risqué)
- operator: "Exists"
effect: "NoExecute"
# Tolérance générique pour un taint avec une clé spécifique, peu importe l'effet
- key: "example.com/important-key"
operator: "Exists"
Points clés sur la correspondance :
- Une tolérance avec
operator: Equalcorrespond à un Taint si lakey, lavalueet l'effectsont identiques. - Une tolérance avec
operator: Existscorrespond à un Taint si lakeyet l'effectsont identiques (la valeur du Taint est ignorée). - Si
keyest omise dans la tolérance (avecoperator: Exists), elle correspond à n'importe quelle clé de Taint avec l'effectspécifié (ou tous les effets sieffectest aussi omis). - Si
effectest omis dans la tolérance, elle correspond à tous les effets pour lakey(et lavaluesioperator: Equal) spécifiée.
Cas d'usage et bonnes pratiques
Les Taints et Tolerations sont puissants mais doivent être utilisés judicieusement :
- Dédier des noeuds : C'est le cas d'usage principal. Taintez les noeuds spéciaux (GPU, etc.) avec
key=feature:NoScheduleet ajoutez la tolérance correspondante uniquement aux Pods qui ont besoin de cette fonctionnalité. - Isolation de charges de travail : Vous pouvez tainter un groupe de noeuds pour une équipe ou un environnement (
environment=prod:NoSchedule) et vous assurer que seuls les Pods avec la bonne tolérance y sont déployés. - Gestion des conditions de noeuds : Kubernetes ajoute automatiquement des taints comme
node.kubernetes.io/not-ready:NoExecute. Les Pods système (comme ceux du CNI ou de CoreDNS) ont souvent des tolérances par défaut pour ces taints afin de pouvoir s'exécuter même sur des noeuds problématiques ou de rester pendant une certaine période. Les StatefulSets bénéficient souvent d'une tolérance par défaut avectolerationSecondspournot-readyetunreachablepour éviter une éviction immédiate en cas de problème réseau temporaire. - Maintenance de noeuds : Avant une maintenance, vous pouvez ajouter un taint
maintenance=true:NoSchedulepour empêcher de nouveaux déploiements, puis potentiellement un taintmaintenance=true:NoExecutepour évincer les Pods existants (après avoir vérifié qu'ils ont des réplicas ailleurs ou qu'ils peuvent être interrompus).
Il est important de noter que les Taints/Tolerations ne garantissent pas qu'un Pod sera ordonnancé sur un noeud tainté; ils permettent simplement au Pod de l'être. Pour garantir le placement sur ces noeuds dédiés, vous devez combiner les Taints/Tolerations avec Node Affinity ou nodeSelector pour attirer activement les Pods vers ces noeuds spécifiques.