Un label est une étiquette clé-valeur qui sert à sélectionner des objets ; une annotation est une note qui sert à les documenter. Vous avez déjà croisé les deux sans les nommer : le sélecteur d'un ReplicaSet retrouve ses Pods par leurs labels, et la leçon Rolling Updates et Rollbacks a posé l'annotation kubernetes.io/change-cause. Cette leçon vous apprend à les manipuler avec kubectl label et kubectl annotate, puis à filtrer avec -l. Elle prépare directement la leçon suivante : un Service trouve ses Pods exactement de cette façon.
Prérequis : les leçons Pods, Deployments et ReplicaSets, et un cluster kind avec kubectl configuré.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Distinguer un label d'une annotation, et choisir le bon des deux
- Ajouter, modifier et retirer un label avec
kubectl label - Filtrer des ressources avec un sélecteur de labels (
-l) - Comprendre pourquoi un label posé à la main sur un Pod disparaît avec lui
- Documenter un objet avec
kubectl annotateet relire ses annotations
Label ou annotation : quelle différence ?
Section intitulée « Label ou annotation : quelle différence ? »La question qui tranche tient en une ligne : Kubernetes ou un outil devra-t-il sélectionner des objets avec cette information ? Si oui, c'est un label, court et contraint, que les sélecteurs savent lire. Si non, c'est une annotation, du texte libre que personne ne filtre mais que tout le monde peut lire. Les deux vivent au même endroit, dans le bloc metadata de l'objet.
| Critère | Label | Annotation |
|---|---|---|
| Rôle | Identifier, regrouper, sélectionner | Documenter, configurer un outil |
Lu par un sélecteur (-l, Service, ReplicaSet) | Oui | Non |
| Taille de la valeur | 63 caractères au plus | Toutes les annotations d'un objet : 256 Kio au total |
| Caractères de la valeur | Lettres, chiffres, -, _, . | Texte libre |
| Exemple | app=web, env=production | owner=equipe-web@exemple.fr, une URL de runbook |
Une information longue, changeante ou destinée aux humains (adresse de contact, lien, motif d'un changement) est donc une annotation. Un critère de tri (application, environnement, rôle) est un label.
Poser, modifier et retirer un label
Section intitulée « Poser, modifier et retirer un label »kubectl label <type> <nom> <clé>=<valeur> écrit un label sur n'importe quel objet : Pod, Deployment, nœud. Les exemples de cette leçon tournent sur deux Deployments, web (3 réplicas) et api (2 réplicas), créés avec kubectl create deployment. Leurs Pods portent déjà le label app, que kubectl create deployment écrit dans le modèle de Pod, et un label pod-template-hash, posé par le ReplicaSet.
Ajouter un label
Section intitulée « Ajouter un label »Sans option, la commande ajoute la clé si elle est absente de l'objet et répond par une ligne qui nomme la ressource touchée. Remplacez le nom du Pod par l'un des vôtres, lu avec kubectl get pods.
kubectl label pod web-5c4449bd5f-cg6vq env=productionpod/web-5c4449bd5f-cg6vq labeledModifier un label existant : --overwrite
Section intitulée « Modifier un label existant : --overwrite »Relancer la commande avec une autre valeur échoue : kubectl refuse d'écraser un label par accident, et le message dit quelle valeur est en place.
kubectl label pod web-5c4449bd5f-cg6vq env=stagingerror: 'env' already has a value (production), and --overwrite is falseL'option --overwrite lève ce garde-fou. C'est voulu : remplacer une valeur peut faire sortir l'objet d'un sélecteur, donc changer ce que fait le cluster.
kubectl label pod web-5c4449bd5f-cg6vq env=staging --overwriteRetirer un label : le tiret final
Section intitulée « Retirer un label : le tiret final »Un tiret collé derrière la clé retire le label. Ce n'est pas une faute de frappe, c'est la syntaxe de suppression, la même que pour une annotation.
kubectl label pod web-5c4449bd5f-cg6vq env-pod/web-5c4449bd5f-cg6vq unlabeledRetirer une clé absente n'est pas une erreur : kubectl répond label "env" not found. puis not labeled, et sort en succès. Un script qui retire un label n'a donc pas besoin de vérifier sa présence avant.
Labelliser plusieurs ressources d'un coup
Section intitulée « Labelliser plusieurs ressources d'un coup »La commande accepte plusieurs noms à la suite, le drapeau --all pour toutes les ressources du type dans l'espace de noms courant (le namespace, étudié dans la leçon Namespaces), ou un sélecteur -l qui ne retient que les objets déjà porteurs d'un label.
kubectl label pods -l app=web tier=frontendkubectl label pods -l app=api tier=backendpod/web-5c4449bd5f-cg6vq labeledpod/web-5c4449bd5f-mk46g labeledpod/web-5c4449bd5f-sl8vd labeledpod/api-7c4f6c8597-t8qf6 labeledpod/api-7c4f6c8597-tdg7h labeledAvant une modification en masse, ajoutez --dry-run=server : l'API server valide la demande et kubectl liste les objets visés, suffixés de (server dry run), sans rien modifier.
Filtrer avec un sélecteur de labels (-l)
Section intitulée « Filtrer avec un sélecteur de labels (-l) »L'option -l filtre n'importe quelle commande kubectl get, delete ou logs sur les labels des objets. C'est le geste le plus utile de la leçon, parce que c'est exactement ce que fait un Service : il ne connaît pas ses Pods par leur nom, il les retrouve par un sélecteur d'égalité comme app=web. Le ReplicaSet fonctionne de la même façon. Pour cette section, deux des cinq Pods portent un environnement, env=production sur cg6vq et env=staging sur mk46g :
kubectl get pods -l app=web,env=productionNAME READY STATUS RESTARTS AGEweb-5c4449bd5f-cg6vq 1/1 Running 0 23sLa virgule se lit « et » : toutes les conditions doivent être vraies. Le tableau donne les autres formes ; mettez entre apostrophes celles qui contiennent des parenthèses, des espaces ou un !, pour que le shell ne les interprète pas.
| Sélecteur | Retient les objets… | Résultat mesuré sur nos 5 Pods |
|---|---|---|
-l env=production | dont env vaut production | 1 Pod |
-l env!=staging | dont env ne vaut pas staging, y compris sans env | 4 Pods |
-l 'env in (production, staging)' | dont env vaut l'une des valeurs | 2 Pods |
-l 'env notin (staging)' | dont env ne vaut aucune de ces valeurs, y compris sans env | 4 Pods |
-l env | qui portent la clé env, quelle que soit sa valeur | 2 Pods |
-l '!env' | qui ne portent pas la clé env | 3 Pods |
Le piège est dans la deuxième ligne : != retient aussi les objets qui n'ont pas la clé. Les deux Pods api sortent alors qu'ils n'ont aucun label env. Pour ne viser que les objets qui portent la clé, combinez les deux conditions : -l env,env!=staging.
Le sélecteur sert aussi à modifier en masse. Pour poser env=dev sur tous les Pods qui n'ont pas encore d'environnement, une seule commande suffit, sans boucle ni xargs :
kubectl label pods -l '!env' env=devAfficher les labels dans kubectl get
Section intitulée « Afficher les labels dans kubectl get »Par défaut, kubectl get n'affiche aucun label. L'option --show-labels les ajoute tous dans une colonne LABELS ; l'option -L en extrait certains, une colonne par clé, plus lisible dès que les objets en portent beaucoup. Après la commande précédente, chaque Pod a son environnement :
kubectl get pods -L envNAME READY STATUS RESTARTS AGE ENVapi-7c4f6c8597-t8qf6 1/1 Running 0 23s devapi-7c4f6c8597-tdg7h 1/1 Running 0 23s devweb-5c4449bd5f-cg6vq 1/1 Running 0 23s productionweb-5c4449bd5f-mk46g 1/1 Running 0 23s stagingweb-5c4449bd5f-sl8vd 1/1 Running 0 23s devPlusieurs clés se séparent par une virgule : -L app,env,tier affiche trois colonnes. Une cellule vide signale un objet qui ne porte pas la clé.
Pourquoi un label posé à la main ne dure pas
Section intitulée « Pourquoi un label posé à la main ne dure pas »Un label posé avec kubectl label vit sur un objet précis, et disparaît avec lui. Deux expériences sur le cluster le montrent, et elles disent où un label durable doit être écrit.
Première expérience : labelliser le Deployment ne labellise pas ses Pods. Après kubectl label deployment web env=production, kubectl get deploy --show-labels affiche bien app=web,env=production sur le Deployment, mais aucun Pod n'a changé. Les Pods reçoivent les labels du modèle de Pod (spec.template.metadata.labels), pas ceux du Deployment.
Seconde expérience : retirer le label app d'un Pod géré. La sortie ne garde que les Pods web.
kubectl label pod web-5c4449bd5f-mk46g app-kubectl get pods -L app,envNAME READY STATUS RESTARTS AGE APP ENVweb-5c4449bd5f-cg6vq 1/1 Running 0 28s web productionweb-5c4449bd5f-mk46g 1/1 Running 0 28s stagingweb-5c4449bd5f-sl8vd 1/1 Running 0 28s web devweb-5c4449bd5f-zfrb9 1/1 Running 0 5s webLe Pod mk46g ne correspond plus au sélecteur app=web : le ReplicaSet ne le compte plus et crée zfrb9 pour revenir à trois. Le nouveau Pod n'a pas de label env, ni de tier, puisqu'il sort du modèle. Retenez la règle qui en découle : un label qui doit durer s'écrit dans le manifeste, dans le modèle de Pod, et kubectl label sur un Pod sert à trier ou à diagnostiquer, jamais à configurer. Le Pod sorti du groupe, lui, continue de tourner : supprimez-le avec kubectl delete pod.
Les règles de syntaxe d'un label
Section intitulée « Les règles de syntaxe d'un label »Un label mal formé est refusé au moment de l'écriture, avec un message qui cite l'expression régulière attendue. Les règles viennent de la documentation officielle, Labels and Selectors, et s'appliquent à la clé comme à la valeur.
| Partie | Règle |
|---|---|
| Nom de la clé | 63 caractères au plus, lettres, chiffres, -, _, ., commence et finit par une lettre ou un chiffre |
| Préfixe (facultatif) | un nom de domaine DNS de 253 caractères au plus, suivi de / (app.kubernetes.io/name) |
| Valeur | 63 caractères au plus (vide autorisé), mêmes caractères, commence et finit par une lettre ou un chiffre |
Les préfixes kubernetes.io/ et k8s.io/ sont réservés aux composants de Kubernetes. Deux refus réels, une valeur avec des espaces puis une valeur trop longue :
kubectl label pod web-5c4449bd5f-cg6vq "desc=Mon application de production"kubectl label pod web-5c4449bd5f-cg6vq description=une-valeur-beaucoup-trop-longue-pour-tenir-dans-un-label-kubernetes-valideerror: invalid label value: "desc=Mon application de production": a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (...)error: invalid label value: "description=une-valeur-beaucoup-trop-longue-pour-tenir-dans-un-label-kubernetes-valide": must be no more than 63 bytesSi l'information ne tient pas dans ces règles, c'est le signe qu'elle relève d'une annotation.
Les labels recommandés app.kubernetes.io/*
Section intitulée « Les labels recommandés app.kubernetes.io/* »Kubernetes publie une liste de labels recommandés, tous sous le préfixe app.kubernetes.io/. Les adopter donne un vocabulaire commun à vos équipes et aux outils qui savent les lire, comme Helm ou les tableaux de bord : env, environment et stage cessent de coexister pour dire la même chose.
| Label | Rôle | Exemple |
|---|---|---|
app.kubernetes.io/name | Nom de l'application | boutique |
app.kubernetes.io/instance | Instance précise de l'application | boutique-prod |
app.kubernetes.io/version | Version de l'application | 2.4.1 |
app.kubernetes.io/component | Rôle dans l'architecture | frontend, database |
app.kubernetes.io/part-of | Application d'ensemble | site-marchand |
app.kubernetes.io/managed-by | Outil qui gère l'objet | helm, kubectl |
Conformément à la règle établie plus haut, ces labels s'écrivent dans le manifeste, sur le Deployment et dans son modèle de Pod. Notez les guillemets autour de la version : sans eux, YAML lit une valeur comme 1.10 comme un nombre, et kubectl rejette le fichier avec cannot unmarshal number into Go struct field ObjectMeta.metadata.labels of type string.
apiVersion: apps/v1kind: Deploymentmetadata: name: boutique labels: app.kubernetes.io/name: boutique app.kubernetes.io/version: "2.4.1" app.kubernetes.io/component: frontendspec: replicas: 2 selector: matchLabels: app.kubernetes.io/name: boutique template: metadata: labels: app.kubernetes.io/name: boutique app.kubernetes.io/version: "2.4.1" app.kubernetes.io/component: frontend spec: containers: - name: nginx image: nginx:1.30@sha256:9bf97bd7714f5e24c1ccd545ecb9eb5435cb6d109c97cebb15e7e455e0239edbAprès kubectl apply -f boutique.yaml, kubectl get pods -l app.kubernetes.io/name=boutique --show-labels montre les trois labels sur chaque Pod, suivis du pod-template-hash ajouté par le ReplicaSet.
Le sélecteur ne reprend que le nom, pas la version : comme vous l'avez vu dans la leçon ReplicaSets, il est immuable, et une version qui change à chaque livraison ne peut pas en faire partie.
Documenter un objet avec kubectl annotate
Section intitulée « Documenter un objet avec kubectl annotate »kubectl annotate s'utilise exactement comme kubectl label : mêmes arguments, même --overwrite, même tiret final pour retirer. Seul le contenu change : la valeur est du texte libre, que vous placez entre guillemets dès qu'elle contient des espaces ou des caractères que le shell interpréterait.
Ajouter, modifier et retirer une annotation
Section intitulée « Ajouter, modifier et retirer une annotation »Une adresse de contact et un lien vers une procédure d'exploitation (un runbook) sont les cas les plus courants : la personne d'astreinte les trouve directement sur l'objet. Plusieurs paires peuvent suivre sur la même ligne.
kubectl annotate deployment web owner="equipe-web@exemple.fr"kubectl annotate deployment web runbook="https://wiki.exemple.fr/runbooks/web" ticket="INC-2026-0142"deployment.apps/web annotateddeployment.apps/web annotatedLe refus d'écraser existe aussi, avec un message un peu différent de celui de label. Changer de propriétaire demande donc --overwrite :
kubectl annotate deployment web owner="equipe-sre@exemple.fr"kubectl annotate deployment web owner="equipe-sre@exemple.fr" --overwriteerror: --overwrite is false but found the following declared annotation(s): 'owner' already has a value (equipe-web@exemple.fr)deployment.apps/web annotatedUne fois l'incident clos, kubectl annotate deployment web ticket- retire l'annotation ticket : le tiret final joue le même rôle qu'avec un label.
Lire les annotations d'un objet
Section intitulée « Lire les annotations d'un objet »kubectl get n'affiche pas les annotations, et il n'existe pas d'équivalent de --show-labels. Deux chemins existent : kubectl describe, qui les liste sous Annotations:, et jsonpath, un langage d'extraction intégré à kubectl qui lit un champ précis de l'objet. Voici l'extrait de describe, relevé avant le retrait de ticket :
kubectl describe deployment webName: web(...)Labels: app=web env=productionAnnotations: deployment.kubernetes.io/revision: 1 owner: equipe-sre@exemple.fr runbook: https://wiki.exemple.fr/runbooks/web ticket: INC-2026-0142Selector: app=web(...)kubectl get deployment web -o jsonpath='{.metadata.annotations.owner}'equipe-sre@exemple.frUne annotation n'est pas filtrable : kubectl get pods -l owner ne trouve rien, puisque -l ne lit que les labels. C'est aussi pourquoi un Service ne pourra jamais choisir ses Pods par une annotation.
Les annotations que Kubernetes pose lui-même
Section intitulée « Les annotations que Kubernetes pose lui-même »La sortie de describe montre une annotation que vous n'avez pas écrite : deployment.kubernetes.io/revision, le numéro de révision que le contrôleur de Deployment tient à jour et que kubectl rollout history affiche. Les composants de Kubernetes et de nombreux outils se servent ainsi des annotations pour ranger leurs propres informations.
| Annotation | Qui la pose | À quoi elle sert |
|---|---|---|
deployment.kubernetes.io/revision | le contrôleur de Deployment | numéro de la révision courante |
kubectl.kubernetes.io/last-applied-configuration | kubectl apply | copie du dernier manifeste appliqué, pour calculer le prochain changement |
kubernetes.io/change-cause | vous | motif affiché par rollout history, voir Annoter les changements |
D'autres outils de l'écosystème, comme cert-manager ou Argo CD, lisent des annotations à leur nom pour régler leur comportement sur un objet. Vous les rencontrerez avec ces outils ; le geste pour les poser reste kubectl annotate ou, mieux, le manifeste.
Combien peut-on stocker dans une annotation ?
Section intitulée « Combien peut-on stocker dans une annotation ? »La taille totale des annotations d'un objet, clés et valeurs comprises, ne peut pas dépasser 256 Kio, soit 262 144 octets. La limite vient de la documentation officielle des annotations, et l'API server l'applique : sur notre cluster 1.37, un objet à 262 144 octets d'annotations est accepté, un octet de plus est refusé.
The ConfigMap "taille" is invalid: metadata.annotations: Too long: may not be more than 262144 bytesLa limite porte sur l'ensemble des annotations, pas sur chacune. Elle laisse une large place à de la documentation, mais pas à des fichiers encodés ni à des journaux : ceux-là appartiennent à un ConfigMap, étudié dans la leçon ConfigMaps, ou à un stockage hors du cluster.
Dépannage
Section intitulée « Dépannage »Les erreurs de labels et d'annotations se rangent en deux familles. Dans la première, kubectl refuse d'écrire et le message dit pourquoi. Dans la seconde, l'écriture réussit mais rien ne change dans le cluster, ou le label disparaît : la cause est alors presque toujours un objet recréé depuis un modèle ou un manifeste qui ne le porte pas.
| Symptôme | Cause probable | Solution |
|---|---|---|
invalid label value | Valeur de plus de 63 caractères, ou espaces et caractères interdits | Raccourcir, ou passer en annotation |
'env' already has a value (...), and --overwrite is false | Le label existe déjà | Ajouter --overwrite |
--overwrite is false but found the following declared annotation(s) | L'annotation existe déjà | Ajouter --overwrite |
-l ne retourne rien | Label absent, faute de frappe, ou objets dans un autre namespace | Vérifier avec kubectl get pods --show-labels |
| Le label posé sur un Pod a disparu | Le Pod a été recréé à partir du modèle du Deployment | Écrire le label dans spec.template.metadata.labels |
| Un Pod en trop est apparu | Un label du sélecteur a été retiré ou modifié sur un Pod | Remettre le label, ou supprimer le Pod sorti du groupe |
kubectl label deployment ne change pas les Pods | Les Pods prennent les labels du modèle, pas du Deployment | Modifier le modèle de Pod dans le manifeste |
À retenir
Section intitulée « À retenir »- Un label sert à sélectionner (Service, ReplicaSet,
-l) ; une annotation sert à documenter et n'est jamais filtrable. kubectl labeletkubectl annotatepartagent la syntaxe :--overwritepour remplacer, tiret final (env-) pour retirer.-l app=web,env=productioncombine les conditions en « et » ;env!=xretient aussi les objets sans la cléenv.--show-labelsaffiche tous les labels,-L enven fait une colonne ; les annotations se lisent avecdescribeou jsonpath.- Un label posé à la main sur un Pod disparaît quand le Pod est recréé : un label durable s'écrit dans le modèle de Pod du manifeste.
- Retirer d'un Pod un label du sélecteur le sort du groupe : le ReplicaSet crée un remplaçant.
- Valeur de label : 63 caractères au plus ; annotations d'un objet : 256 Kio au total.
Testez vos connaissances
Section intitulée « Testez vos connaissances »Six questions pour vérifier les gestes de la leçon : poser et retirer un label, lire un sélecteur comme le fera un Service, savoir où un label durable doit s'écrire, et choisir entre label et annotation.
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)Score par domaine
Un domaine regroupe plusieurs guides et reçoit plusieurs questions : son score est plus fiable qu'un score par thème, qui porte souvent sur une seule question.
Bilan
Points forts
Aucun sujet réussi à 80 % sur au moins deux questions pour l’instant.
Points faibles
Aucun sujet sous le seuil de réussite.
À faire ensuite
Des indices pour retenter votre chance ?
Continuer le cours : Les Services
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications