
Un DaemonSet garantit qu'un Pod s'exécute sur chaque nœud éligible de votre cluster Kubernetes. Contrairement à un Deployment qui répartit un nombre variable de répliques, le DaemonSet assure exactement un Pod par nœud correspondant aux critères de sélection.
Ce guide couvre la création, le ciblage de nœuds spécifiques avec nodeSelector
et tolerations, les stratégies de mise à jour, et le dépannage, tout ce qu'il
faut pour la certification CKAD.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Créer un DaemonSet et observer son déploiement automatique sur tous les nœuds
- Cibler des nœuds spécifiques avec
nodeSelectoretaffinity - Gérer les nœuds taintés avec
tolerations(control-plane, GPU, etc.) - Mettre à jour un DaemonSet avec les stratégies
RollingUpdateetOnDelete - Diagnostiquer pourquoi un Pod ne s'exécute pas sur un nœud
Qu'est-ce qu'un DaemonSet ?
Section intitulée « Qu'est-ce qu'un DaemonSet ? »Un DaemonSet est un contrôleur Kubernetes qui garantit qu'un Pod spécifique tourne sur tous les nœuds éligibles d'un cluster, ou sur un sous-ensemble défini par des règles de sélection.
Ce que "nœuds éligibles" signifie
Section intitulée « Ce que "nœuds éligibles" signifie »Un DaemonSet ne garantit pas un Pod sur absolument tous les nœuds sans nuance. Il garantit un Pod sur tous les nœuds qui correspondent à :
nodeSelector: labels requis sur le nœudaffinity: règles d'affinité plus avancéestolerations: tolérance aux taints du nœud- Contraintes de ressources : CPU/mémoire disponibles
Si un nœud ne satisfait pas ces critères, aucun Pod du DaemonSet n'y sera schedulé.
Comportement automatique
Section intitulée « Comportement automatique »La force du DaemonSet est qu'il réagit seul aux changements de topologie du cluster, sans que vous touchiez au nombre de répliques. Le tableau liste les trois événements qui déclenchent une action du contrôleur. Le premier est le plus utile au quotidien : ajoutez un nœud, un Pod de l'agent y apparaît automatiquement, ce qui garantit qu'aucune machine ne reste sans surveillance.
| Événement | Action du DaemonSet |
|---|---|
| Nouveau nœud rejoint le cluster | Un Pod est automatiquement créé sur ce nœud |
| Nœud supprimé du cluster | Le Pod correspondant est automatiquement supprimé |
| Nœud devient inéligible (nouveau taint) | Le Pod est évicté si pas de toleration |
Cas d'usage courants
Section intitulée « Cas d'usage courants »Les DaemonSets sont essentiels pour les agents système qui doivent tourner partout :
| Catégorie | Exemples |
|---|---|
| Monitoring | Prometheus Node Exporter, Datadog Agent, Telegraf |
| Collecte de logs | Fluentd, Fluent Bit, Filebeat, Vector |
| Réseau (CNI) | Calico, Cilium, Flannel, Weave Net |
| Stockage (CSI) | NFS CSI Node Plugin, Longhorn, OpenEBS |
| Sécurité | Falco, Sysdig, Trivy Operator |
Créer un DaemonSet simple
Section intitulée « Créer un DaemonSet simple »Voici un DaemonSet minimal qui exécute un conteneur busybox affichant un
message toutes les 10 secondes :
apiVersion: apps/v1kind: DaemonSetmetadata: name: my-daemonset labels: app: daemon-examplespec: selector: matchLabels: app: daemon-example template: metadata: labels: app: daemon-example spec: containers: - name: busybox image: busybox:1.37@sha256:9db7b59979c38555a39def84a31fb98b5296952f9e3afd4f6f11f05b07adfab0 command: ["sh", "-c", "while true; do echo 'DaemonSet actif sur $(hostname)'; sleep 10; done"] resources: requests: cpu: 10m memory: 16Mi limits: cpu: 50m memory: 32MiAppliquer le DaemonSet :
kubectl apply -f daemonset-basic.yamlVérifier le déploiement :
kubectl get ds my-daemonset# NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE# my-daemonset 3 3 3 3 3 <none> 45sLes colonnes importantes :
| Colonne | Signification |
|---|---|
DESIRED | Nombre de nœuds éligibles |
CURRENT | Nombre de Pods créés |
READY | Nombre de Pods en état Ready |
UP-TO-DATE | Pods avec la spec à jour |
NODE SELECTOR | Sélecteur de nœuds (si défini) |
Voir sur quels nœuds les Pods tournent :
kubectl get pods -l app=daemon-example -o wide# NAME READY STATUS NODE# my-daemonset-7x2km 1/1 Running node-worker-1# my-daemonset-9f4np 1/1 Running node-worker-2# my-daemonset-kj8rt 1/1 Running node-control-planeCibler certains nœuds seulement
Section intitulée « Cibler certains nœuds seulement »Un DaemonSet peut être limité à un sous-ensemble de nœuds avec
nodeSelector ou affinity. C'est utile pour :
- Déployer uniquement sur les nœuds Linux (
kubernetes.io/os: linux) - Cibler un pool spécifique (GPU, infra, edge)
- Exclure les nœuds de développement
Avec nodeSelector
Section intitulée « Avec nodeSelector »La méthode la plus simple. Le DaemonSet ne crée des Pods que sur les nœuds ayant tous les labels spécifiés.
apiVersion: apps/v1kind: DaemonSetmetadata: name: infra-agentspec: selector: matchLabels: app: infra-agent template: metadata: labels: app: infra-agent spec: nodeSelector: kubernetes.io/os: linux nodepool: infra containers: - name: agent image: busybox:1.37@sha256:9db7b59979c38555a39def84a31fb98b5296952f9e3afd4f6f11f05b07adfab0 command: ["sh", "-c", "echo 'Agent infra'; sleep infinity"]Vérifier les labels d'un nœud :
kubectl get node node-worker-1 --show-labelsAjouter un label à un nœud :
kubectl label node node-worker-1 nodepool=infraAvec nodeAffinity (plus flexible)
Section intitulée « Avec nodeAffinity (plus flexible) »Pour des règles plus complexes (opérateurs In, NotIn, Exists) :
spec: template: spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/arch operator: In values: - amd64 - arm64Gérer les nœuds taintés
Section intitulée « Gérer les nœuds taintés »Par défaut, les Pods ne sont pas schedulés sur les nœuds portant un taint
NoSchedule. Pour qu'un DaemonSet s'exécute sur ces nœuds (par exemple les
control-plane), vous devez ajouter des tolerations.
Cas courant : control-plane nodes
Section intitulée « Cas courant : control-plane nodes »Les nœuds control-plane portent généralement le taint
node-role.kubernetes.io/control-plane:NoSchedule. Pour y déployer un agent de
monitoring :
apiVersion: apps/v1kind: DaemonSetmetadata: name: monitoring-agentspec: selector: matchLabels: app: monitoring-agent template: metadata: labels: app: monitoring-agent spec: tolerations: - key: "node-role.kubernetes.io/control-plane" operator: "Exists" effect: "NoSchedule" containers: - name: node-exporter image: prom/node-exporter:v1.10.2@sha256:3ac34ce007accad95afed72149e0d2b927b7e42fd1c866149b945b84737c62c3 ports: - containerPort: 9100 name: metricsTolérer tous les taints (agents critiques)
Section intitulée « Tolérer tous les taints (agents critiques) »Pour les agents système qui doivent absolument tourner partout (y compris sur des nœuds avec n'importe quel taint) :
tolerations: - operator: "Exists"Cette tolérance universelle a une portée qu'il faut mesurer : elle autorise le
Pod à rester même sur un nœud marqué NoExecute pour une maintenance en
cours, donc précisément sur un nœud qu'on cherche à vider. Réservez-la aux
agents dont l'absence casserait le nœud, un CNI ou un collecteur de journaux, et
pas à un exportateur de métriques qu'on peut perdre dix minutes.
L'effet d'une tolérance se mesure d'ailleurs directement sur DESIRED. Sur un
cluster à deux nœuds dont un control plane tainté, un DaemonSet sans tolérance
annonce 1. La même ressource, avec une tolérance sur
node-role.kubernetes.io/control-plane, annonce 2 et place un Pod sur chaque
nœud. La colonne ne compte pas les machines, elle compte les portes
ouvertes.
Vérifier les taints d'un nœud
Section intitulée « Vérifier les taints d'un nœud »Avant d'écrire une toleration, il faut connaître le taint exact que porte le nœud : sa clé, sa valeur et son effet (NoSchedule, NoExecute). La commande ci-dessous extrait cette ligne du describe, et c'est elle que vous recopiez ensuite champ par champ dans la toleration. Une faute de frappe sur la clé suffit à laisser le Pod bloqué en Pending.
kubectl describe node node-control-plane | grep -A 5 Taints# Taints: node-role.kubernetes.io/control-plane:NoScheduleObserver l'état d'un DaemonSet
Section intitulée « Observer l'état d'un DaemonSet »Ces commandes sont essentielles pour le dépannage et l'examen CKAD.
Commandes principales
Section intitulée « Commandes principales »Ces cinq commandes couvrent le suivi complet d'un DaemonSet, de la vue synthétique au détail. Commencez toujours par kubectl get ds : si la colonne DESIRED diffère de READY, vous savez qu'un nœud pose problème et vous enchaînez avec describe pour lire les événements. Les commandes de rollout ne servent que pendant une mise à jour en cours.
# Vue d'ensemble des DaemonSetskubectl get ds
# Détails complets (événements, sélecteur, stratégie)kubectl describe ds my-daemonset
# Pods du DaemonSet avec leurs nœudskubectl get pods -l app=daemon-example -o wide
# État du rollout en courskubectl rollout status ds/my-daemonset
# Historique des révisionskubectl rollout history ds/my-daemonsetLire get ds : sept colonnes, et une qui compte
Section intitulée « Lire get ds : sept colonnes, et une qui compte »kubectl get dsNAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGEagent 1 1 1 1 1 <none> 12sDESIRED n'est pas le nombre de nœuds du cluster, c'est le nombre de nœuds
que le contrôleur juge éligibles. Sur un cluster à deux nœuds dont le
control plane est tainté, un DaemonSet sans toleration affiche donc DESIRED 1,
et tout va bien. La colonne NODE SELECTOR vous rappelle la contrainte que
vous avez posée, ce qui évite de chercher ailleurs.
Les valeurs par défaut, relevées sur l'objet créé
Section intitulée « Les valeurs par défaut, relevées sur l'objet créé »| Champ | Défaut |
|---|---|
updateStrategy.type | RollingUpdate |
rollingUpdate.maxUnavailable | 1 |
rollingUpdate.maxSurge | 0 |
revisionHistoryLimit | 10 |
Le maxSurge: 0 est la différence de fond avec un Deployment : sur un nœud, il
n'y a de la place que pour un Pod du DaemonSet. Kubernetes doit donc
supprimer l'ancien avant de créer le nouveau, et la mise à jour d'un agent
implique par construction une courte interruption sur chaque nœud.
Comprendre la sortie de describe
Section intitulée « Comprendre la sortie de describe »kubectl describe ds my-daemonsetName: agentNamespace: lab-dsSelector: app=agentNode-Selector: <none>Desired Number of Nodes Scheduled: 1Current Number of Nodes Scheduled: 1Number of Nodes Scheduled with Up-to-date Pods: 1Number of Nodes Scheduled with Available Pods: 1Number of Nodes Misscheduled: 0Pods Status: 1 Running / 0 Waiting / 0 Succeeded / 0 FailedNumber of Nodes Misscheduled mérite un regard : il compte les nœuds qui
portent un Pod du DaemonSet alors qu'ils ne devraient plus, typiquement
après un changement de nodeSelector. Une valeur non nulle signale un ménage en
cours, pas une panne.
Mettre à jour un DaemonSet
Section intitulée « Mettre à jour un DaemonSet »Kubernetes propose deux stratégies de mise à jour pour les DaemonSets.
RollingUpdate (par défaut)
Section intitulée « RollingUpdate (par défaut) »C'est la stratégie par défaut depuis l'API apps/v1. Kubernetes remplace les
Pods progressivement, un par un, en respectant les contraintes configurées.
apiVersion: apps/v1kind: DaemonSetmetadata: name: my-daemonsetspec: updateStrategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 # Max de Pods indisponibles pendant la MAJ maxSurge: 0 # Pas de Pod supplémentaire créé avant suppression selector: matchLabels: app: daemon-example template: metadata: labels: app: daemon-example spec: containers: - name: busybox image: busybox:1.37@sha256:9db7b59979c38555a39def84a31fb98b5296952f9e3afd4f6f11f05b07adfab0 # Changez cette image pour déclencher un rolloutParamètres de contrôle :
| Paramètre | Description | Valeur par défaut |
|---|---|---|
maxUnavailable | Nombre max de Pods indisponibles pendant la mise à jour | 1 |
maxSurge | Nombre de Pods supplémentaires créés avant suppression (K8s 1.22+) | 0 |
minReadySeconds | Délai avant de considérer un Pod comme Ready | 0 |
Appliquer une mise à jour :
kubectl apply -f daemonset-rollingupdate.yamlSuivre la progression :
kubectl rollout status ds/my-daemonset# Waiting for daemon set "my-daemonset" rollout to finish: 1 out of 3 new pods have been updated...# daemon set "my-daemonset" successfully rolled outAnnuler en cas de problème :
kubectl rollout undo ds/my-daemonsetOnDelete (contrôle manuel)
Section intitulée « OnDelete (contrôle manuel) »Avec OnDelete, Kubernetes ne met pas à jour automatiquement les Pods
existants. Vous devez les supprimer manuellement pour qu'ils soient recréés avec
la nouvelle spec.
spec: updateStrategy: type: OnDeleteWorkflow :
-
Modifier la spec du DaemonSet
Fenêtre de terminal kubectl apply -f daemonset-updated.yaml -
Les Pods existants ne changent pas (vérifiez avec
kubectl get pods) -
Supprimer manuellement un Pod pour déclencher sa recréation
Fenêtre de terminal kubectl delete pod my-daemonset-7x2km -
Le nouveau Pod est créé avec la nouvelle spec
Cas d'usage de OnDelete :
- Mise à jour contrôlée nœud par nœud
- Validation manuelle avant chaque remplacement
- Environnements critiques avec approbation requise
Dépannage des DaemonSets
Section intitulée « Dépannage des DaemonSets »Le dépannage d'un DaemonSet se fait sur une colonne : DESIRED. Elle ne
compte pas les nœuds du cluster, mais les nœuds éligibles, c'est-à-dire ceux
que le nodeSelector retient et dont les taints sont tolérés. Un DESIRED plus
petit que le nombre de nœuds n'est donc pas une anomalie, c'est une réponse : il
vous dit combien de nœuds acceptent votre Pod.
Le piège, développé plus bas, est qu'un DESIRED à zéro n'a rien d'alarmant en
apparence, puisqu'il est alors égal à CURRENT.
Problèmes courants et solutions
Section intitulée « Problèmes courants et solutions »La panne la plus fréquente d'un DaemonSet n'est pas un Pod qui plante, c'est un Pod jamais créé. Et elle est difficile pour une raison précise : elle ne produit aucun signal.
Le contrôleur ne signale pas les nœuds qu'il ignore
Section intitulée « Le contrôleur ne signale pas les nœuds qu'il ignore »Un nodeSelector que personne ne satisfait ne fait pas diverger DESIRED et
CURRENT. Mesuré :
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTORagent-gpu 0 0 0 0 0 materiel=gpuLes deux colonnes valent 0, donc elles sont égales, donc tout a l'air
cohérent. Et kubectl describe ds rend :
Events: <none>Aucun FailedCreate, aucun avertissement. DESIRED compte les nœuds
éligibles, pas les nœuds du cluster : le contrôleur n'a rien tenté, donc il
n'a rien à signaler.
Le symptôme n'est donc pas DESIRED ≠ CURRENT, c'est DESIRED inférieur au
nombre de nœuds que vous attendiez. Il ne se voit qu'en comparant :
kubectl get nodes --no-headers | wc -lkubectl get ds agent-gpuPosez le libellé manquant sur un nœud et DESIRED passe à 1 dans la seconde,
sans qu'aucune commande n'ait à être rejouée.
| Symptôme | Cause probable | Diagnostic | Solution |
|---|---|---|---|
DESIRED < nombre de nœuds | Nœud tainté ou nodeSelector non satisfait | Comparer get nodes et get ds, puis get nodes --show-labels | Ajouter une toleration ou le libellé manquant |
Pod Pending | Pas de nœud éligible | kubectl describe pod | Vérifier labels/taints des nœuds |
ImagePullBackOff | Image introuvable ou registre inaccessible | kubectl logs <pod> | Vérifier le nom de l'image et les credentials |
CrashLoopBackOff | Application qui plante en boucle | kubectl logs <pod> --previous | Corriger l'application ou sa configuration |
| Pod non créé sur un nœud | NodeSelector ou affinity non satisfaits | kubectl get node --show-labels | Ajouter les labels requis au nœud |
Commandes de diagnostic
Section intitulée « Commandes de diagnostic »Quand DESIRED ne correspond pas au nombre de Pods, la méthode consiste à comparer la liste des nœuds à la liste des Pods pour repérer la machine orpheline. Les commandes ci-dessous font exactement cela : elles comptent d'un côté les nœuds, de l'autre les Pods du DaemonSet, puis inspectent le nœud suspect pour y lire ses taints et ses conditions.
# Voir pourquoi un DaemonSet n'a pas le bon nombre de Podskubectl describe ds my-daemonset
# Identifier les nœuds sans Pod du DaemonSetkubectl get nodes -o widekubectl get pods -l app=daemon-example -o wide
# Comparer nœuds et Podskubectl get nodes --no-headers | wc -l # Nombre de nœudskubectl get pods -l app=daemon-example --no-headers | wc -l # Nombre de Pods
# Vérifier un nœud spécifiquekubectl describe node node-worker-2 | grep -E "Taints|Conditions" -A 3Exemple de résolution : Pod manquant sur un nœud tainté
Section intitulée « Exemple de résolution : Pod manquant sur un nœud tainté »Symptôme : le cluster a 3 nœuds, le DaemonSet en annonce 2.
kubectl get nodes --no-headers | wc -lkubectl get ds my-daemonset3NAME DESIRED CURRENT READY NODE SELECTORmy-daemonset 2 2 2 <none>Notez bien : DESIRED et CURRENT sont égaux, et describe ne montre
aucun événement. Rien n'indique un problème, sinon l'écart avec le nombre de
nœuds.
Diagnostic : puisque le contrôleur ne parle pas, c'est aux nœuds qu'il faut demander lequel est écarté, et pourquoi.
kubectl get nodes -o custom-columns=NOM:.metadata.name,TAINTS:.spec.taints[*].keyNOM TAINTSdoc-k8s-control-plane node-role.kubernetes.io/control-planedoc-k8s-worker <none>noeud-gpu gpuSolution :
tolerations: - key: "gpu" operator: "Equal" value: "true" effect: "NoSchedule"DaemonSet vs Deployment vs StatefulSet
Section intitulée « DaemonSet vs Deployment vs StatefulSet »Choisir la bonne ressource est essentiel pour la CKAD. Voici un comparatif :
| Critère | DaemonSet | Deployment | StatefulSet |
|---|---|---|---|
| Nombre de Pods | 1 par nœud éligible | N répliques (variable) | N répliques ordonnées |
| Identité des Pods | Anonyme | Anonyme | Stable (pod-0, pod-1...) |
| Stockage | Généralement local/hostPath | PVC partagé ou sans état | PVC dédié par Pod |
| Cas d'usage | Agents système, CNI, logs | Applications stateless, APIs | Bases de données, queues |
| Scaling | Automatique (suit les nœuds) | kubectl scale ou HPA | kubectl scale |
| Mise à jour | RollingUpdate ou OnDelete | RollingUpdate | RollingUpdate ou OnDelete |
Quand choisir un DaemonSet ?
Section intitulée « Quand choisir un DaemonSet ? »Le critère de décision tient en une question : le nombre de Pods doit-il suivre le nombre de nœuds ? Si oui, le DaemonSet est le bon choix. Ces trois signaux confirment le besoin, ils tournent tous autour d'un accès aux ressources locales du nœud (fichiers de logs, interfaces réseau, métriques matérielles) qu'un Pod ordinaire ne peut pas garantir sur chaque machine.
- Vous avez besoin d'un agent sur chaque nœud (ou sous-ensemble)
- L'application doit accéder aux ressources locales du nœud (logs, métriques, réseau)
- Le nombre de répliques doit suivre automatiquement le nombre de nœuds
Quand NE PAS utiliser un DaemonSet ?
Section intitulée « Quand NE PAS utiliser un DaemonSet ? »À l'inverse, forcer un DaemonSet là où il n'a pas sa place gaspille des ressources et complique le scaling. Chaque ligne ci-dessous renvoie vers la ressource réellement adaptée : un Deployment pour une application sans dépendance au nœud, un StatefulSet dès qu'il faut une identité stable et du stockage persistant par Pod.
- Votre application ne dépend pas du nœud → Deployment
- Vous avez besoin d'identités stables et de stockage persistant → StatefulSet
- Vous voulez scaler indépendamment du nombre de nœuds → Deployment + HPA
À retenir
Section intitulée « À retenir »- Un DaemonSet garantit un Pod sur chaque nœud éligible, pas sur tous les nœuds sans distinction
- L'éligibilité dépend des
nodeSelector,affinity,tolerationset des ressources disponibles - La stratégie de mise à jour par défaut est RollingUpdate (pas OnDelete)
- Utilisez
maxUnavailablepour contrôler le rythme des mises à jour - Les tolerations sont nécessaires pour les nœuds control-plane ou taintés
kubectl describe dsest votre meilleur ami pour diagnostiquer les problèmes- Choisissez DaemonSet pour les agents système, Deployment pour les applications scalables
Contrôle de connaissances
Section intitulée « Contrôle de connaissances »Sept questions sur la seule notion qui compte vraiment ici, celle de nœud éligible, et sur la façon dont un DaemonSet le dit sans avoir l'air de signaler quoi que ce soit.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Profil de compétences
Quoi faire maintenant
Ressources pour progresser
Des indices pour retenter votre chance ?
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications
Mettre en pratique
Section intitulée « Mettre en pratique »Un DaemonSet qui oublie le control plane passe inaperçu jusqu'au jour où il manque une métrique. Ce lab vous fait déployer un agent sur tous les nœuds, taint du control plane compris, puis compte un Pod par nœud, vérifie que le taint est toujours en place et lit les logs de l'agent pour prouver qu'il travaille.
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Troubleshooting cluster : Le diagnostic d'un DaemonSet dont les Pods ne démarrent que sur une partie des nœuds.
- Observer la santé d'un cluster : Les commandes qui contrôlent l'état des agents de collecte déployés en DaemonSet.
- Gérer les nœuds : Le comportement d'un DaemonSet pendant un cordon, un drain ou l'ajout d'un nœud.