Aller au contenu
Conteneurs & Orchestration medium

kubectl label et annotate : organiser et documenter vos ressources Kubernetes

14 min de lecture

logo kubernetes

Labels et annotations sont les deux systèmes de métadonnées de Kubernetes — mais ils ne servent pas du tout à la même chose. Les labels sont des paires clé-valeur que Kubernetes utilise pour sélectionner et router : un Service trouve ses pods via un label selector, un Deployment gère ses réplicas par labels. Les annotations sont du texte libre pour documenter et outiller : référence d’incident, config Ingress, scrape Prometheus. Ce guide vous montre comment les gérer efficacement avec kubectl label et kubectl annotate.

  • La différence entre labels et annotations — et quand utiliser l’un ou l’autre
  • Ajouter, modifier et supprimer des labels et annotations sur n’importe quelle ressource
  • Filtrer des ressources avec les label selectors (-l)
  • Adopter les labels recommandés par Kubernetes (app.kubernetes.io/*)
  • Exploiter les annotations pour le tooling (Ingress, Prometheus, Cert-Manager…)
  • Appliquer en masse des métadonnées sur plusieurs ressources

Avant de taguer quoi que ce soit, posez-vous cette question : Kubernetes ou un autre outil devra-t-il sélectionner des ressources avec cette information ?

CritèreLabelAnnotation
ButIdentifier, sélectionner, grouperDocumenter, configurer des outils
Utilisé par les selectors (-l)✅ Oui❌ Non
Utilisé par les Services/Deployments✅ Oui (routing, réplicas)❌ Non
Longueur valeur63 caractères maxPas de limite pratique
Caractères autorisésAlphanumériques, -, _, .Texte libre
Exemple typiqueenv=prod, app=api, tier=backendowner=equipe-platform, prometheus.io/scrape=true

Les labels sont le mécanisme fondamental de Kubernetes pour lier les ressources entre elles. Un Service trouve ses pods par label selector. Un Deployment identifie ses réplicas par labels. Sans labels, Kubernetes ne peut pas fonctionner.

Fenêtre de terminal
kubectl label <type> <nom> <clé>=<valeur> [options]
Fenêtre de terminal
kubectl label pod api-server-7d4b8c env=production
pod/api-server-7d4b8c labeled

Par défaut, kubectl refuse d’écraser un label existant. Ajoutez --overwrite :

Fenêtre de terminal
kubectl label pod api-server-7d4b8c env=staging --overwrite

Ajoutez un - (tiret) après le nom de la clé :

Fenêtre de terminal
kubectl label pod api-server-7d4b8c env-
pod/api-server-7d4b8c unlabeled
Fenêtre de terminal
# Par nom
kubectl label pods api-server-7d4b8c worker-9f2a1e tier=backend
# Tous les pods d'un namespace
kubectl label pods --all env=staging -n dev
# Par sélecteur (tous les pods de l'app api)
kubectl label pods -l app=api version=v2.1 -n prod

Les label selectors sont l’un des outils les plus puissants de kubectl. Ils fonctionnent partout : get, delete, logs, exec

Fenêtre de terminal
# Égalité
kubectl get pods -l env=production
# Inégalité
kubectl get pods -l env!=staging
# Appartenance (in)
kubectl get pods -l 'env in (production, staging)'
# Exclusion (notin)
kubectl get pods -l 'env notin (dev, test)'
# Existence (le label existe, quelle que soit la valeur)
kubectl get pods -l env
# Non-existence
kubectl get pods -l '!env'
# Combinaison (ET logique — toutes les conditions doivent être vraies)
kubectl get pods -l app=api,env=production,tier=backend

Kubernetes définit un ensemble de labels standardisés sous le préfixe app.kubernetes.io/. Les adopter garantit la compatibilité avec les outils de l’écosystème (Helm, ArgoCD, Lens, Prometheus…).

LabelRôleExemple
app.kubernetes.io/nameNom de l’applicationapi-gateway
app.kubernetes.io/versionVersion de l’application2.4.1
app.kubernetes.io/componentComposant dans l’architecturefrontend, backend, database
app.kubernetes.io/part-ofApplication parenteboutique-en-ligne
app.kubernetes.io/managed-byOutil de déploiementhelm, argocd, kubectl
app.kubernetes.io/instanceInstance uniqueapi-gateway-prod

Exemple concret — un Deployment avec labels recommandés :

apiVersion: apps/v1
kind: Deployment
metadata:
name: api-gateway
labels:
app.kubernetes.io/name: api-gateway
app.kubernetes.io/version: "2.4.1"
app.kubernetes.io/component: backend
app.kubernetes.io/part-of: boutique-en-ligne
app.kubernetes.io/managed-by: helm

Les labels ont des règles strictes — les dépasser provoque une erreur :

ContrainteRègle
Clé (sans préfixe)1-63 caractères, alphanumérique, -, _, .
Préfixe (optionnel)Sous-domaine DNS, max 253 caractères, séparé par /
Valeur0-63 caractères, alphanumérique, -, _, . — doit commencer et finir par un alphanumérique
Fenêtre de terminal
# ✅ Valide
kubectl label pod mon-pod app.kubernetes.io/name=api-gateway
# ❌ Invalide — valeur trop longue ou caractères spéciaux
kubectl label pod mon-pod desc="Mon application de production avec beaucoup de détails"
# → error: invalid label value

Les annotations stockent des informations textuelles libres sur une ressource. Kubernetes ne les utilise pas pour la sélection, mais de nombreux outils s’en servent pour leur configuration.

Fenêtre de terminal
kubectl annotate <type> <nom> <clé>=<valeur> [options]
Fenêtre de terminal
kubectl annotate pod api-server-7d4b8c owner="equipe-platform@example.com"
pod/api-server-7d4b8c annotated
Fenêtre de terminal
kubectl annotate pod api-server-7d4b8c owner="equipe-sre@example.com" --overwrite
Fenêtre de terminal
kubectl annotate pod api-server-7d4b8c owner-
Fenêtre de terminal
# Par nom
kubectl annotate pods api-server-7d4b8c worker-9f2a1e support-team="ops@example.com"
# Tous les deployments d'un namespace
kubectl annotate deploy --all -n prod change-cause="Mise à jour sécurité 2026-02-27"
Fenêtre de terminal
# Toutes les annotations
kubectl get pod api-server-7d4b8c -o jsonpath='{.metadata.annotations}' | python3 -m json.tool
# Une annotation spécifique
kubectl get pod api-server-7d4b8c -o jsonpath='{.metadata.annotations.owner}'

Annotations utilisées par l’écosystème Kubernetes

Section intitulée « Annotations utilisées par l’écosystème Kubernetes »

Contrairement aux labels que vous définissez librement, certaines annotations ont un sens particulier pour des composants Kubernetes ou des outils tiers :

AnnotationOutilRôle
kubernetes.io/change-causekubectl rolloutMotif du changement affiché dans rollout history
nginx.ingress.kubernetes.io/rewrite-targetIngress NGINXRéécriture d’URL
cert-manager.io/cluster-issuerCert-ManagerÉmetteur de certificat TLS
prometheus.io/scrapePrometheusActive le scraping de métriques
prometheus.io/portPrometheusPort à scraper
argocd.argoproj.io/sync-waveArgoCDOrdre de synchronisation

L’annotation kubernetes.io/change-cause permet de documenter pourquoi un Deployment a été modifié. Elle apparaît dans kubectl rollout history :

  1. Annotez le Deployment avec la raison du changement

    Fenêtre de terminal
    kubectl annotate deploy api-gateway -n prod \
    kubernetes.io/change-cause="Mise à jour nginx 1.27 — correctif CVE-2026-1234"
  2. Vérifiez dans l’historique

    Fenêtre de terminal
    kubectl rollout history deploy/api-gateway -n prod
    REVISION CHANGE-CAUSE
    1 Déploiement initial
    2 Mise à jour nginx 1.27 — correctif CVE-2026-1234
Fenêtre de terminal
# Trouver les pods sans label env
kubectl get pods -n prod -l '!env' --no-headers -o custom-columns=":metadata.name" | \
xargs -I{} kubectl label pod {} env=production -n prod
Fenêtre de terminal
kubectl label pods --all -n dev legacy-

Kubernetes ne supporte pas le renommage direct. Il faut copier puis supprimer :

Fenêtre de terminal
# Copier la valeur de l'ancien label vers le nouveau
for pod in $(kubectl get pods -n prod -l app=api -o name); do
val=$(kubectl get "$pod" -n prod -o jsonpath='{.metadata.labels.app}')
kubectl label "$pod" -n prod "app.kubernetes.io/name=$val"
done
# Supprimer l'ancien label
kubectl label pods -l app=api -n prod app-

En cas d’incident, annotez les ressources modifiées pour la post-mortem :

Fenêtre de terminal
kubectl annotate deploy api-gateway -n prod \
incident-ref="INC-2026-0142" \
incident-action="Rollback image vers nginx:1.26" \
incident-by="alice@example.com" \
incident-date="2026-02-27T14:30:00Z"

Adoptez une convention dès le départ et documentez-la. Voici un exemple :

LabelValeurs possiblesQui le pose
envdev, staging, prodCI/CD
tierfrontend, backend, database, cacheManifest
app.kubernetes.io/nameNom de l’applicationHelm / manifest
app.kubernetes.io/versionSemverCI/CD
teamplatform, sre, produitManifest
  • Label = ce qui sert à sélectionner (Services, Deployments, NetworkPolicies, monitoring)
  • Annotation = ce qui sert à documenter ou configurer un outil (Ingress, Cert-Manager, Prometheus)
  • Ne mettez jamais d’information longue ou changeante dans un label (URL, description, timestamp)

Plus il y a de labels, plus les selectors deviennent complexes. 5 à 8 labels par ressource est un maximum raisonnable. Au-delà, regroupez via des annotations ou des ConfigMaps de documentation.

SymptômeCause probableSolution
error: invalid label valueValeur > 63 caractères ou caractères spéciauxRaccourcissez ou utilisez une annotation à la place
error: 'X' already has a valueLe label existe déjà sur la ressourceAjoutez --overwrite
error: 'X' already has a value (annotate)L’annotation existe déjàAjoutez --overwrite
-l ne retourne rienMauvais namespace ou label inexistantVérifiez avec kubectl get <type> --show-labels -n <ns>
Service ne route pas vers les podsLabels du Service selector ≠ labels des podsComparez kubectl get svc <nom> -o jsonpath='{.spec.selector}' avec les labels des pods
invalid label keyPréfixe DNS invalide ou clé trop longueVérifiez : clé max 63 chars, préfixe max 253 chars, format DNS
Annotations perdues après replacekubectl replace remplace l’objet entierUtilisez kubectl annotate ou kubectl apply -f à la place
Labels supprimés par ArgoCD/FluxL’outil GitOps resynchronise depuis GitAjoutez les labels dans le manifest Git, pas via kubectl label
  • Labels = sélection et routage (Services, Deployments, NetworkPolicies les utilisent pour trouver les bons pods).
  • Annotations = documentation et configuration d’outils (Ingress, Prometheus, Cert-Manager, traçabilité).
  • La syntaxe est identique : kubectl label et kubectl annotate avec --overwrite pour modifier, - pour supprimer.
  • Adoptez les labels app.kubernetes.io/* — ils sont le standard de l’écosystème (Helm, ArgoCD, Lens).
  • Les labels ont des contraintes strictes (63 chars, alphanumériques) — si ça ne rentre pas, c’est probablement une annotation.
  • Les label selectors (-l) supportent l’égalité, l’inégalité, in, notin et le test d’existence.
  • En prod, documentez vos conventions de labels dans un document partagé par toutes les équipes.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn