Label Selector Tester · Kubernetes
Voyez quels pods votre selector sélectionne — et pourquoi.
Collez les pods et le selector — une chaîne kubectl -l ou un bloc matchLabels / matchExpressions — et obtenez un verdict par ressource avec la clause exacte qui l’a décidé. Y compris la règle que presque tout le monde inverse : NotIn et != correspondent à une ressource qui n’a aucun label de ce nom.
S’exécute dans votre navigateur — rien de ce que vous collez ne quitte cette page. Comment nous le prouvons
Playground du Kubernetes Label Selector Tester
Equality-based clauses (=, !=) and set-based ones (in, notin, a bare key, !key) can be mixed freely in one -l string — commas mean AND. A Deployment's spec.selector accepts both forms but is immutable after creation; a Service's spec.selector is a plain label map and supports equality only.
Results update as you type — press Enter to run now.
Paste one manifest, a --- stream, a kind: List or a YAML list. Press Esc to release keyboard focus from the editor; ⌘/Ctrl + Enter runs and leaves it. Nothing you paste is uploaded.
Paste the resources above — or tap an example — to see, per resource, whether the selector matches it and which clause decided.
Le manque
Un selector qui ne sélectionne rien n’est une erreur nulle part dans Kubernetes.
kubectl apply l’accepte. L’API server l’accepte. Aucun contrôleur ne journalise d’avertissement, aucun événement n’est émis, aucun champ n’est marqué invalide. Le seul symptôme d’un Service dont le selector rate ses pods d’un caractère est un objet Endpoints sans adresses — et quand vous le regardez, vous déboguez déjà au mauvais endroit. Le même silence couvre une NetworkPolicy dont le podSelector ne sélectionne rien, qui échoue en mode ouvert exactement comme un contrôle de sécurité ne devrait pas.
Les règles elles-mêmes forment la seconde moitié du problème, car deux d’entre elles se lisent à l’envers. env!=prod correspond à un pod qui n’a aucun label env — NotIn est satisfait par une clé absente, par conception, dans une branche de Requirement.Matches. Et un selector vide correspond à tout, tandis qu’un selector nil ne correspond à rien. Chacun de ces faits tient en une ligne de Go, et tous deux sont régulièrement mémorisés à l’envers.
C’est pourquoi ceci est un outil et non un article. Demandez à un assistant « est-ce que env!=prod correspond à un pod sans label env ? » et vous obtiendrez une réponse fluide avec une chance sur deux d’être fausse — et les manifestes générés placent régulièrement matchExpressions dans le spec.selector d’un Service, un champ qui n’accepte qu’une map de labels. Collez l’affirmation ici et la réponse sort de la sémantique même qu’implémente apimachinery, motif à l’appui, dans un onglet qui n’envoie rien nulle part.
Vous dimensionnez le workload plutôt que de le sélectionner ? Kubernetes Resource Calculator additionne requests et limits sur les répliques, et Env Example Checker repère les variables qu’un conteneur attend et ne reçoit jamais.
Le pipeline
Comment ça marche.
Quatre étapes, toutes dans votre onglet, réexécutées à chaque frappe.
-
Parser le selector comme apimachinery.
La grammaire `-l` passe par un port de son propre lexer et de son parseur — sensible au contexte, si bien que `op in (in,notin)` est légal, et tolérant aux espaces, si bien que `env in ( prod , dev )` est le même selector. Les selectors structurés suivent plutôt les règles de `LabelSelectorAsSelector`.
-
Lire ce qui se trouve dans le presse-papiers.
Un manifeste, un flux `---`, un `kind: List` ou une liste YAML. Le `spec.template.metadata.labels` d’un workload devient sa propre ligne, car un Service sélectionne les labels des pods et non ceux du Deployment.
-
Évaluer clause par clause.
`Requirement.Matches`, une fois par ressource et par clause : `In` exige la clé présente, `NotIn` est satisfait par une clé absente, `Exists` accepte la valeur vide et `DoesNotExist` non.
-
Montrer la raison, pas seulement le verdict.
Chaque clause porte la phrase qui l’a décidée, en nommant la valeur réelle du label. Les correspondances dues à une clé absente reçoivent une annotation ambre, car ce sont celles que les humains et les modèles de langage inversent.
Référence
Chaque opérateur, et l’effet d’une clé absente.
Sept façons d’écrire une clause, quatre opérateurs derrière, et la colonne qui n’est presque jamais imprimée à côté de la syntaxe : ce qui se passe quand la ressource ne porte pas la clé. Trois des sept correspondent dans ce cas.
| Écrit | Opérateur | Forme structurée | Clé absente |
|---|---|---|---|
| key=value | In | matchLabels: {key: value} Une valeur. `=` et `==` sont le même opérateur. | aucune corresp. |
| key==value | In | matchLabels: {key: value} Identique à `=` ; seule l’écriture est conservée. | aucune corresp. |
| key!=value | NotIn | operator: NotIn, values: [value] Celui que l’on inverse. Une clé absente le satisfait. | CORRESPOND |
| key in (a,b) | In | operator: In, values: [a, b] Au moins une valeur est exigée ; l’ensemble est dédupliqué et trié. | aucune corresp. |
| key notin (a,b) | NotIn | operator: NotIn, values: [a, b] Même règle de clé absente que `!=`, puisque c’est le même opérateur. | CORRESPOND |
| key | Exists | operator: Exists N’importe quelle valeur, y compris la chaîne vide. Les values sont interdites. | aucune corresp. |
| !key | DoesNotExist | operator: DoesNotExist Échoue si la clé est présente avec une valeur vide — présente reste présente. | CORRESPOND |
« A le label, et il n’est pas prod »
Une seule clause ne peut pas dire cela. env!=prod ramasse aussi toutes les ressources sans label env. Ajoutez Exists à côté — les virgules signifient ET.
# ramasse aussi les pods sans le label
kubectl get pods -l 'env!=prod'
# a un label env, et il n'est pas prod
kubectl get pods -l 'env,env!=prod' Le selector vide, en trois versions
Vide signifie tout ; nil signifie rien ; et un Service omet le champ quand il est vide, ce qui le laisse sans endpoints gérés.
# tous les pods du namespace
podSelector: {}
# encore toutes les ressources
selector:
matchLabels: {}
# un Service SANS selector : les endpoints
# sont à vous de gérer
spec:
ports: [{ port: 80 }] La clôture
Ce qu’il ne fait pas, délibérément.
Chacun de ces points a été étudié puis refusé, parce que l’alternative était une réponse plausible qui pouvait être fausse. Un testeur que vous ne pouvez pas auditer est un testeur qu’il faut croire.
Les field selectors
Un autre mécanisme, avec une liste de champs indexés par kind et par version, presque toujours sans opérateurs ensemblistes. Le simuler hors ligne signifierait deviner quels champs votre cluster indexe.
Gt et Lt de la node affinity
Ils appartiennent à NodeSelectorRequirement, pas à LabelSelectorRequirement. Taper replicas>2 renvoie un message qui l’explique, et non une comparaison qu’un label selector ne peut pas exprimer.
La sémantique de namespaceSelector
Un peer de NetworkPolicy combine un namespaceSelector et un podSelector entre namespaces. Sans les objets Namespace, la réponse honnête est le podSelector seul.
Tout ce qui exige le cluster
Aucun API server n’est contacté : ni liste de pods en direct, ni résultat d’admission, ni objet Endpoints. Tout ici découle du texte que vous avez collé.
Limites annoncées plutôt que cachées : jusqu’à 500 documents de ressources dans un collage d’au plus 500 000 caractères, et au plus 100 clauses dans un selector. Un nom de clé de label est validé à 63 caractères, son préfixe de sous-domaine DNS optionnel à 253, et une valeur de label à 63 — les limites mêmes qu’applique l’API server.
Étape suivante
Collez la trace dans le canal d’incident.
« Copy report » vous donne toute l’exécution en texte brut : le selector canonique, puis un bloc par ressource avec son verdict et chaque clause qui l’a décidé. Ensuite, continuez — totalisez ce que le workload réserve vraiment, ou vérifiez les variables que ses conteneurs attendent.
Kubernetes Label Selector Tester — 3 of 5 resources match
selector: app=web,tier=frontend
NO MATCH — Pod/web-d
metadata.labels: app=web, tier=frontnd
[ok] app=web — label app="web" = "web"
[no] tier=frontend — label tier="frontnd" ≠ "frontend" FAQ
Vos questions, nos réponses.
Appuyez sur une question pour afficher la réponse.
Pourquoi env!=prod correspond-il à un pod qui n’a aucun label env ?
Parce que c’est ce que dit la règle, et parce que c’est la ligne la plus surprenante de toute l’API des label selectors. Dans k8s.io/apimachinery, Requirement.Matches traite NotIn et != dans une seule branche : si l’ensemble de labels n’a pas la clé, le résultat est true. In et == prennent la branche inverse : si la clé manque, le résultat est false. env!=prod signifie donc « aucun label env valant prod », ce qu’un pod sans label env satisfait parfaitement. Si vous vouliez dire « a un label env, et il n’est pas prod », il faut deux clauses : env,env!=prod — Exists ET NotIn. Ce testeur annote chaque clause qui se vérifie parce que la clé est absente, pour que vous n’ayez jamais à retenir dans quel sens cela va.
Quelle est la différence entre matchLabels et matchExpressions ?
matchLabels est une simple map, et chaque paire y devient une exigence d’égalité : {app: web, tier: frontend} vaut exactement app=web,tier=frontend. matchExpressions est une liste d’entrées {key, operator, values} et le seul moyen d’écrire les opérateurs ensemblistes In, NotIn, Exists et DoesNotExist. Quand un selector contient les deux, apimachinery relie tout par ET — LabelSelectorAsSelector ajoute chaque paire de matchLabels et chaque expression à la même liste d’exigences. Il n’y a de OU nulle part dans un label selector, à aucun niveau.
Un selector de Service peut-il utiliser matchExpressions ?
Non, et c’est l’erreur que commettent le plus souvent les manifestes générés. Le spec.selector d’un Service est typé map[string]string, pas LabelSelector : il prend une map de labels et ne gère que l’égalité. Écrivez-y matchLabels ou matchExpressions et l’API server rejette le champ purement et simplement. Les Deployments, StatefulSets, DaemonSets, Jobs et le podSelector d’une NetworkPolicy prennent en revanche un véritable LabelSelector et acceptent les deux formes. Collez un manifeste de Service avec matchExpressions dans ce testeur : il vous avertit, puis montre ce qu’un Deployment AURAIT sélectionné — vous voyez l’erreur et l’intention en même temps.
Un selector vide correspond-il à tout ou à rien ?
Cela dépend si le champ est vide ou absent, et ce n’est pas la même chose. Un LabelSelector vide — {}, ou matchLabels: {} — vaut labels.Everything() : il correspond à tous les objets, et c’est précisément pour cela qu’une NetworkPolicy avec podSelector: {} s’applique à tous les pods du namespace. Un selector nil, à l’inverse, ne correspond à rien : LabelSelectorAsSelector(nil) renvoie labels.Nothing(). Et un Service constitue un troisième cas : son champ selector est omis quand il est vide, donc un Service avec selector: {} est un Service sans selector, et le contrôleur d’endpoints ne gère pas du tout ses endpoints.
Est-ce que ce que je colle quitte mon navigateur ?
Non. Les deux parseurs, la validation et le matcher sont du JavaScript exécuté dans votre onglet — pas de serveur, pas d’appel d’API, pas de journalisation, donc 0 octet envoyé. Cela compte ici parce qu’un dump de pods n’est pas un texte neutre : il contient des références d’images internes, des noms de nœuds, des annotations et parfois un jeton monté en variable d’environnement. C’est l’outil que vous pouvez utiliser sur de la sortie de production sans ouvrir une discussion sur le traitement des données.
Mon Service a zéro endpoint. Que vérifier d’abord ?
Les labels des pods, pas le Service. Collez le manifeste du Service comme selector et les vrais pods comme ressources : le testeur lit spec.selector pour vous et affiche une trace par clause sur chaque pod, si bien qu’une coquille d’un caractère apparaît sous la forme label tier="frontnd" ≠ "frontend" au lieu d’une liste d’endpoints vide. Écartez aussi deux pièges structurels. D’abord, un Service sélectionne les labels des PODS, pas les metadata.labels du Deployment lui-même — c’est exactement pourquoi ce testeur liste le spec.template.metadata.labels d’un workload comme sa propre ligne « Pod template ». Ensuite, un selector qui ne correspond à rien n’est une erreur nulle part dans Kubernetes : kubectl l’accepte, l’API server l’accepte, et le seul symptôme est un objet Endpoints vide.
Gère-t-il les field selectors comme --field-selector status.phase=Running ?
Non, et c’est une limite délibérée, pas une fonctionnalité manquante. Les field selectors sont un autre mécanisme : ils filtrent sur les champs propres de l’objet, ils sont évalués par l’API server contre une courte liste de champs autorisés qui varie selon le type de ressource, et presque aucun ne gère les opérateurs ensemblistes. Les simuler hors ligne obligerait à encoder quels champs chaque version de Kubernetes indexe pour chaque kind, et à se tromper subtilement. Cet outil couvre les label selectors, uniformes sur tous les types de ressources et entièrement définis par l’objet que vous avez déjà dans le presse-papiers.
Et les opérateurs Gt et Lt que j’ai vus en node affinity ?
Ils existent, mais pas sur un label selector. La node affinity utilise NodeSelectorRequirement, un type distinct dont l’ensemble d’opérateurs comprend In, NotIn, Exists, DoesNotExist, Gt et Lt. Un LabelSelectorRequirement — celui de matchExpressions, spec.selector et podSelector — n’a que les quatre premiers. Gt et Lt sont donc valides dans nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution et invalides partout où ce testeur regarde. Tapez replicas>2 dans le champ du selector : il le dit, au lieu d’inventer une comparaison qu’un label selector ne possède pas.
Quelle taille supporte-t-il, et quelles sont les limites ?
Il évalue les 500 premiers documents de ressources d’un collage d’au plus 500 000 caractères, et un selector de 100 clauses au maximum — chaque limite s’annonce à l’écran avec le vrai chiffre, si bien qu’une exécution tronquée n’a jamais l’air complète. Les clés et les valeurs sont validées contre les vraies limites : un nom de clé de label fait au plus 63 caractères, le préfixe de sous-domaine DNS optionnel avant le / au plus 253, et une valeur de label au plus 63 (la valeur vide est légale). Une clé ou une valeur invalide dans le SELECTOR est une erreur bloquante, parce que l’API server la rejetterait ; un label invalide sur une RESSOURCE n’est qu’une note, parce que la question posée était de savoir si le selector y correspond.
More free, private DevOps tools.
Le Label Selector Tester est un outil de OpsCanopy — une canopée grandissante de validateurs, convertisseurs et testeurs qui tournent dans le navigateur et ne touchent jamais un serveur.
39 free tools, every one offline-capable — opscanopy.com works with no signup and nothing uploaded.
À voir aussi : Kubernetes Resource Calculator pour ce qu’un workload réserve, Env Example Checker pour les variables qu’un conteneur attend, l’Alertmanager Route Tester pour l’autre arbre de correspondance par labels qui écarte des choses en silence, et le convertisseur JSON ↔ YAML quand un manifeste doit être remodelé pour kubectl patch — ou parcourez le répertoire d’outils complet.
Fourni en l’état, par commodité ; vérifiez toujours une configuration critique face au cluster qui la consommera. OpsCanopy est gratuit et ouvert.