Techniques avancées de kubectl get : Filtrer la sortie avec des étiquettes et JSONPath

Filtrez la sortie de kubectl get avec des sélecteurs d'étiquettes, JSONPath et des colonnes personnalisées pour un dépannage Kubernetes plus efficace.

Techniques avancées de kubectl get : Filtrer la sortie avec des étiquettes et JSONPath

kubectl get devient beaucoup plus utile lorsque vous pouvez réduire la sortie aux ressources et champs exacts dont vous avez besoin. Dans un espace de noms chargé, la différence entre un mur de pods et une liste ciblée de noms, nœuds et images peut faire gagner des minutes lors d'un incident.

Ce guide montre comment combiner les sélecteurs d'étiquettes avec la sortie JSONPath. Vous verrez également quand custom-columns ou jq est plus approprié que de tout forcer dans une seule expression JSONPath.

Comprendre les étiquettes Kubernetes : Le fondement de la sélection des ressources

Avant de plonger dans le filtrage avancé, il est crucial de comprendre les étiquettes Kubernetes. Les étiquettes sont des paires clé-valeur attachées aux objets Kubernetes (comme les Pods, Services, Déploiements, etc.) qui sont utilisées pour identifier et organiser les ressources. Ce sont des métadonnées que les clients et les utilisateurs peuvent utiliser pour sélectionner des sous-ensembles d'objets.

Les étiquettes sont distinctes des annotations ; les étiquettes sont destinées à identifier des caractéristiques significatives et pertinentes pour que les utilisateurs puissent interroger et sélectionner des objets, tandis que les annotations sont destinées aux métadonnées non identifiantes. De bonnes pratiques d'étiquetage sont essentielles pour une gestion efficace des ressources et des opérations avancées de kubectl get.

Pour voir les étiquettes actuellement attribuées à vos ressources, vous pouvez utiliser le drapeau --show-labels :

kubectl get pods --show-labels

Cela ajoutera une colonne LABELS à votre sortie, montrant toutes les étiquettes associées à chaque Pod.

Sélecteurs d'étiquettes avancés avec kubectl get -l

Le drapeau -l ou --selector est votre outil principal pour filtrer la sortie de kubectl get en fonction des étiquettes. Il vous permet de spécifier un ensemble d'exigences d'étiquettes que les ressources doivent satisfaire pour être incluses dans la sortie. Les sélecteurs peuvent être de simples paires clé-valeur ou des expressions plus complexes basées sur des ensembles.

Sélection de base des étiquettes

Correspondance exacte

Pour sélectionner des ressources qui ont une étiquette spécifique avec une valeur exacte, utilisez la syntaxe clé=valeur.

# Obtenir tous les pods avec l'étiquette 'app' définie sur 'nginx'
kubectl get pods -l app=nginx

# Obtenir tous les services dans l'espace de noms 'default' avec l'étiquette 'tier' définie sur 'frontend'
kubectl get services -n default -l tier=frontend

Correspondance d'inégalité

Pour sélectionner des ressources qui ont une étiquette spécifique non définie sur une valeur particulière, utilisez la syntaxe clé!=valeur.

# Obtenir tous les pods où l'étiquette 'app' n'est pas 'nginx'
kubectl get pods -l app!=nginx

Existence (clé uniquement)

Pour sélectionner des ressources qui ont simplement une étiquette particulière, quelle que soit sa valeur, spécifiez simplement la clé.

# Obtenir tous les pods qui ont l'étiquette 'environment', indépendamment de sa valeur
kubectl get pods -l environment

Non-existence (clé uniquement)

Pour sélectionner des ressources qui n'ont pas une étiquette particulière, préfixez la clé avec !.

# Obtenir tous les pods qui n'ont PAS l'étiquette 'component'
kubectl get pods -l !component

Combinaison de plusieurs sélecteurs d'étiquettes (logique ET)

Vous pouvez combiner plusieurs sélecteurs d'étiquettes en les séparant par une virgule. Cela implique une relation ET, ce qui signifie qu'une ressource doit satisfaire toutes les conditions d'étiquette spécifiées pour être incluse.

# Obtenir les pods avec 'app=nginx' ET 'env=production'
kubectl get pods -l app=nginx,env=production

# Obtenir les déploiements avec 'tier=backend' ET qui n'ont PAS l'étiquette 'version'
kubectl get deployments -l tier=backend,!version

Sélecteurs d'étiquettes basés sur des ensembles

Kubernetes prend également en charge des sélecteurs d'étiquettes basés sur des ensembles plus puissants, particulièrement utiles lorsqu'il s'agit de plusieurs valeurs possibles pour une seule étiquette.

clé in (valeur1, valeur2, ...)

Pour sélectionner des ressources où la valeur d'une étiquette est l'une d'une liste spécifiée de valeurs.

# Obtenir les pods où l'étiquette 'app' est soit 'nginx' OU 'redis'
kubectl get pods -l 'app in (nginx,redis)'

# Obtenir les services dans l'espace de noms 'kube-system' où l'étiquette 'k8s-app' est 'kube-dns' OU 'kubernetes-dashboard'
kubectl get services -n kube-system -l 'k8s-app in (kube-dns,kubernetes-dashboard)'

clé notin (valeur1, valeur2, ...)

Pour sélectionner des ressources où la valeur d'une étiquette n'est aucune d'une liste spécifiée de valeurs.

# Obtenir les pods où l'étiquette 'env' n'est NI 'dev' NI 'test'
kubectl get pods -l 'env notin (dev,test)'

Astuce : Lorsque vous utilisez des sélecteurs basés sur des ensembles ou des sélecteurs avec des caractères spéciaux, mettez toujours l'expression de sélection entière entre guillemets simples ('...') pour éviter les problèmes d'interprétation du shell.

Meilleures pratiques pour l'étiquetage

  • Cohérence : Établissez un schéma d'étiquetage clair et respectez-le dans tout votre cluster. Cela rend le filtrage prévisible et fiable.
  • Noms significatifs : Utilisez des étiquettes qui décrivent clairement les caractéristiques de la ressource (par exemple, app, tier, environment, version).
  • Granularité : Les étiquettes doivent être suffisamment spécifiques pour permettre une sélection précise mais pas si granulaires qu'elles deviennent ingérables.
  • Immutabilité : Évitez d'utiliser des étiquettes pour des données qui changent fréquemment. Les étiquettes sont mieux adaptées aux propriétés d'identification statiques.
  • Étiquettes courantes : Utilisez des étiquettes largement adoptées comme app.kubernetes.io/name, app.kubernetes.io/instance, app.kubernetes.io/version, etc., pour une meilleure interopérabilité avec les outils.

Extraction de données personnalisées avec JSONPath

Alors que les sélecteurs d'étiquettes vous aident à identifier quelles ressources vous voulez, JSONPath vous aide à définir quelles informations vous voulez extraire de ces ressources et comment elles doivent être formatées. kubectl get vous permet de produire des détails de ressources dans divers formats tels que yaml, json, et wide ; -o jsonpath est utile lorsque vous avez besoin d'une sortie personnalisée compacte.

kubectl a sa propre implémentation JSONPath pour naviguer dans la structure JSON des objets Kubernetes. Elle prend en charge les textes de modèle utiles et les boucles range, mais ce n'est pas la même chose que les modèles Go ou jq.

Pour utiliser JSONPath, vous spécifiez le format de sortie avec -o jsonpath='<modèle>'.

Bases de JSONPath et cas d'utilisation courants

Tout d'abord, il est souvent utile de visualiser la sortie JSON complète d'une ressource pour comprendre sa structure avant d'écrire une expression JSONPath :

# Obtenir la structure JSON complète d'un pod
kubectl get pod <nom-du-pod> -o json

Cela vous donnera une carte claire pour construire vos requêtes JSONPath.

Accès à un seul champ

Utilisez {.sous-champ.champ} pour accéder à des valeurs spécifiques. Par exemple, pour obtenir le nom d'un Pod :

# Obtenir le nom d'un pod spécifique
kubectl get pod mon-nginx-pod-12345 -o jsonpath='{.metadata.name}'

# Obtenir le nom du nœud où un pod est en cours d'exécution
kubectl get pod mon-nginx-pod-12345 -o jsonpath='{.spec.nodeName}'

Accès aux éléments d'un tableau

Pour accéder aux éléments d'un tableau, vous pouvez utiliser [*] pour itérer sur tous les éléments ou [index] pour un élément spécifique.

# Obtenir les noms de tous les conteneurs dans un pod spécifique
kubectl get pod mon-nginx-pod-12345 -o jsonpath='{.spec.containers[*].name}'

# Obtenir l'image du premier conteneur dans un pod spécifique
kubectl get pod mon-nginx-pod-12345 -o jsonpath='{.spec.containers[0].image}'

Itération sur une liste de ressources (en utilisant range)

Lorsque kubectl get renvoie plusieurs ressources (par exemple, tous les pods), la sortie est généralement un objet contenant un tableau items. Vous aurez besoin de la fonction range du modèle Go pour itérer sur elles.

# Lister tous les noms de pods et leurs IP, chacun sur une nouvelle ligne
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.podIP}{"\n"}{end}'

# Lister tous les noms de déploiements et le nombre de réplicas prêts
kubectl get deployments -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.readyReplicas}{"\n"}{end}'
  • {range .items[*]} : Commence une itération sur chaque élément du tableau .items.
  • {.metadata.name} : À l'intérieur de la boucle, . fait référence à l'élément courant (par exemple, un objet Pod unique).
  • {"\t"} : Insère un caractère de tabulation pour le formatage.
  • {"\n"} : Insère un caractère de nouvelle ligne.
  • {end} : Ferme la boucle range.

Sortie conditionnelle : Utilisez plutôt les modèles Go

kubectl -o jsonpath ne prend pas en charge les blocs if, with ou else du modèle Go. Si vous avez besoin d'un rendu conditionnel, passez à -o go-template :

# Lister les noms de pods et afficher N/A lorsque podIP est vide
kubectl get pods -o go-template='{{range .items}}{{.metadata.name}}{{"\t"}}{{if .status.podIP}}{{.status.podIP}}{{else}}N/A{{end}}{{"\n"}}{{end}}'

Pour une sortie non conditionnelle, JSONPath est plus court :

kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.podIP}{"\n"}{end}'

Formatage personnalisé et en-tête

Vous pouvez ajouter votre propre texte statique et créer un en-tête pour votre sortie de type tableau.

# Sortie personnalisée pour les noms de pods, images et nœud, avec un en-tête
kubectl get pods -o=jsonpath='{"NAME\tIMAGE\tNODE\n"}{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].image}{"\t"}{.spec.nodeName}{"\n"}{end}'

Avertissement : kubectl a sa propre implémentation JSONPath. Elle est utile pour l'extraction de champs et les boucles range, mais ce n'est pas la même chose que jq et ne prend pas en charge toutes les fonctionnalités JSONPath que vous pourriez connaître d'autres outils.

Conseils pour JSONPath

  • Commencez simplement : Commencez par un chemin de base, puis ajoutez plus de complexité.
  • Inspectez JSON : Utilisez toujours kubectl get <ressource> <nom> -o json pour comprendre la structure exacte que vous interrogez.
  • Échappez les caractères : N'oubliez pas d'échapper les caractères spéciaux comme les nouvelles lignes (\n) et les tabulations (\t) dans votre chaîne de modèle JSONPath si vous voulez qu'ils soient rendus comme des littéraux dans la sortie.
  • Enregistrez les modèles : Pour les expressions JSONPath complexes ou fréquemment utilisées, enregistrez-les dans un fichier et utilisez -o jsonpath-file=/chemin/vers/modele.jsonpath.

Combinaison d'étiquettes et JSONPath

La véritable puissance vient de la combinaison de ces techniques. Tout d'abord, utilisez les sélecteurs d'étiquettes pour réduire les ressources, puis appliquez JSONPath pour extraire et formater des données spécifiques de cet ensemble filtré.

# Obtenir les noms et les images de conteneurs de tous les pods avec 'app=my-app' et 'env=production'
kubectl get pods -l 'app=my-app,env=production' -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].image}{"\n"}{end}'

# Obtenir les noms et les IP de cluster de tous les services qui ont l'étiquette 'tier' définie sur 'backend'
kubectl get services -l tier=backend -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.clusterIP}{"\n"}{end}'

# Trouver tous les pods en cours d'exécution sur un nœud spécifique 'worker-node-1' et lister leurs noms et statuts
kubectl get pods --field-selector spec.nodeName=worker-node-1 -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.phase}{"\n"}{end}'

Remarque : Alors que les sélecteurs d'étiquettes (-l) sont destinés aux paires clé-valeur arbitraires, kubectl offre également --field-selector pour filtrer en fonction des champs de ressource (par exemple, status.phase=Running, metadata.namespace=default). Cela fournit une autre couche puissante de filtrage qui peut être combinée avec les étiquettes et JSONPath.

Dépannage et pièges courants

  • Erreurs de syntaxe JSONPath : Même une petite faute de frappe peut casser le modèle. Vérifiez deux fois les accolades, les points et l'accès aux tableaux.
  • Champs manquants : Si un champ n'existe pas pour une ressource particulière, JSONPath peut afficher <no value> ou une chaîne vide. Utilisez les constructions de modèle Go if ou with pour les gérer élégamment.
  • Échappement du shell : Les guillemets simples autour de l'expression JSONPath sont cruciaux. Si votre expression contient des guillemets internes ou des caractères spéciaux, vous pourriez avoir besoin d'un échappement supplémentaire du shell.
  • Modèle Go vs. JSONPath pur : N'oubliez pas que kubectl utilise des modèles Go, pas un moteur JSONPath universel. Des fonctionnalités comme le filtrage avancé (?()) font généralement partie de jq ou d'autres processeurs JSON dédiés, et ne sont pas directement prises en charge dans -o jsonpath de kubectl.
  • Tableau items vide : Si votre sélecteur d'étiquettes ne correspond à aucune ressource, items sera vide et votre boucle range ne produira aucune sortie.

À retenir

Maîtriser les techniques avancées de kubectl get avec les sélecteurs d'étiquettes et JSONPath est une compétence inestimable pour tout utilisateur Kubernetes. Ces options puissantes de filtrage et de formatage transforment kubectl get d'un simple outil de listage en un utilitaire sophistiqué d'extraction de données. Vous pouvez rapidement identifier les ressources problématiques, générer des rapports personnalisés ou alimenter des données précises dans des scripts d'automatisation.

Utilisez les étiquettes pour choisir les ressources, puis choisissez le format de sortie le plus simple qui vous donne les champs dont vous avez besoin. JSONPath est idéal pour une extraction compacte, custom-columns est plus facile pour les tableaux rapides, et jq ou les modèles Go sont meilleurs lorsque la sortie nécessite une véritable logique.