Pular para o conteúdo

Label Selector Tester · Kubernetes

Veja quais pods o seu selector casa — e por quê.

Cole os pods e o selector — uma string kubectl -l ou um bloco matchLabels / matchExpressions — e receba um veredito por recurso com a cláusula exata que decidiu. Incluindo a regra que quase todo mundo responde ao contrário: NotIn e != casam com um recurso que não tem essa label de jeito nenhum.

Roda no seu navegador — nada do que você cola sai desta página. Como comprovamos isso

Roda no seu navegador Sem cluster Sem cadastro Atualizado em 31 de jul. de 2026

Playground do Kubernetes Label Selector Tester

Examples
Selector grammar

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.

resources.yaml input

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.

Verdicts

Paste the resources above — or tap an example — to see, per resource, whether the selector matches it and which clause decided.

A lacuna

Um selector que não casa com nada não é erro em nenhum lugar do Kubernetes.

kubectl apply aceita. O API server aceita. Nenhum controlador registra aviso, nenhum evento é emitido, nenhum campo é marcado como inválido. O único sintoma de um Service cujo selector erra os pods por um caractere é um objeto Endpoints sem endereços — e quando você está olhando para isso, já está depurando no lugar errado. O mesmo silêncio cobre uma NetworkPolicy cujo podSelector não seleciona nada, que falha aberta exatamente como um controle de segurança não deveria.

As regras em si são a outra metade do problema, porque duas delas se leem ao contrário. env!=prod casa com um pod que não tem nenhuma label envNotIn é satisfeito por uma chave ausente, por design, em um ramo do Requirement.Matches. E um selector vazio casa com tudo, enquanto um selector nil casa com nada. Cada fato é uma linha de Go, e os dois são lembrados invertidos com frequência.

É por isso que isto é uma ferramenta e não um artigo. Pergunte a um assistente « env!=prod casa com um pod sem label env?» e você recebe uma resposta fluente com cinquenta por cento de chance de estar errada — e manifestos gerados colocam matchExpressions dentro do spec.selector de um Service com naturalidade, um campo que só aceita um mapa simples de labels. Cole a afirmação aqui e a resposta sai da mesma semântica que o apimachinery implementa, com o motivo anexado, em uma aba que não manda nada para lugar nenhum.

Quer dimensionar o workload em vez de selecioná-lo? Kubernetes Resource Calculator soma requests e limits entre réplicas, e Env Example Checker encontra as variáveis que um contêiner espera e nunca recebe.

O pipeline

Como funciona.

Quatro passos, todos dentro da sua aba, reexecutados enquanto você digita.

  1. Parsear o selector como o apimachinery faz.

    A gramática `-l` passa por um port do lexer e do parser dele — sensível ao contexto, então `op in (in,notin)` é legal, e tolerante a espaços, então `env in ( prod , dev )` é o mesmo selector. Selectors estruturados seguem as regras do `LabelSelectorAsSelector`.

  2. Ler o que estiver na área de transferência.

    Um manifesto, um fluxo `---`, um `kind: List` ou uma lista YAML. O `spec.template.metadata.labels` de um workload vira a própria linha, porque um Service seleciona labels de pod e não as do Deployment.

  3. Avaliar cláusula por cláusula.

    `Requirement.Matches`, uma vez por recurso e por cláusula: `In` exige a chave presente, `NotIn` é satisfeito por uma chave ausente, `Exists` aceita o valor vazio e `DoesNotExist` não.

  4. Mostrar a razão, não só o veredito.

    Cada cláusula carrega a frase que a decidiu, nomeando o valor real da label. As correspondências por chave ausente ganham uma anotação âmbar, porque são as que pessoas e modelos de linguagem respondem ao contrário.

Referência

Cada operador, e o que uma chave ausente faz.

Sete formas de escrever uma cláusula, quatro operadores atrás delas e a coluna que quase nunca aparece ao lado da sintaxe: o que acontece quando o recurso não carrega a chave. Três das sete casam nesse caso.

Escrito como Operador Forma estruturada Chave ausente
key=value In matchLabels: {key: value} Um valor. `=` e `==` são o mesmo operador. não casa
key==value In matchLabels: {key: value} Idêntico a `=`; só a forma escrita é preservada. não casa
key!=value NotIn operator: NotIn, values: [value] O que as pessoas invertem. Uma chave ausente o satisfaz. CASA
key in (a,b) In operator: In, values: [a, b] Exige pelo menos um valor; o conjunto é deduplicado e ordenado. não casa
key notin (a,b) NotIn operator: NotIn, values: [a, b] A mesma regra de chave ausente do `!=`, porque é o mesmo operador. CASA
key Exists operator: Exists Qualquer valor, inclusive a string vazia. Values são proibidos. não casa
!key DoesNotExist operator: DoesNotExist Falha se a chave existir com valor vazio — presente continua presente. CASA

«Tem a label, e ela não é prod»

Uma cláusula sozinha não diz isso. env!=prod também leva todo recurso sem label env. Coloque Exists ao lado — vírgulas significam AND.

BASH
# também leva pods sem a label
kubectl get pods -l 'env!=prod'

# tem uma label env, e ela não é prod
kubectl get pods -l 'env,env!=prod'

O selector vazio, de três formas

Vazio significa tudo; nil significa nada; e um Service omite o campo quando está vazio, o que o deixa sem endpoints gerenciados.

YAML
# todos os pods do namespace
podSelector: {}

# de novo, todos os recursos
selector:
  matchLabels: {}

# um Service SEM selector: os endpoints
# são você quem gerencia
spec:
  ports: [{ port: 80 }]

A cerca

O que ele deliberadamente não faz.

Cada item foi estudado e recusado, porque a alternativa era uma resposta plausível que podia estar errada. Um tester que você não consegue auditar é um tester em que você tem que acreditar.

Field selectors

Outro mecanismo, com uma lista de campos indexados por kind e por versão, quase sempre sem operadores baseados em conjunto. Simular offline significaria adivinhar quais campos o seu cluster indexa.

Gt e Lt do node affinity

Pertencem ao NodeSelectorRequirement, não ao LabelSelectorRequirement. Digitar replicas>2 devolve uma mensagem que explica isso, não uma comparação que um label selector não expressa.

A semântica de namespaceSelector

Um peer de NetworkPolicy combina um namespaceSelector com um podSelector entre namespaces. Sem os objetos Namespace, a resposta honesta é o podSelector sozinho.

Qualquer coisa que precise do cluster

Nenhum API server é contatado, então não há lista de pods ao vivo, nem resultado de admission, nem objeto Endpoints. Tudo aqui vem do texto que você colou.

Limites ditos em vez de escondidos: até 500 documentos de recursos de uma colagem de no máximo 500.000 caracteres, e no máximo 100 cláusulas em um selector. O nome de uma chave de label é validado em 63 caracteres, o prefixo de subdomínio DNS opcional em 253 e um valor de label em 63 — os mesmos limites que o API server aplica.

Próximo passo

Cole o rastro no canal do incidente.

«Copy report» entrega a execução inteira em texto puro: o selector canônico e depois um bloco por recurso com o veredito e cada cláusula que decidiu. E então siga — some o que o workload realmente reserva, ou verifique as variáveis que os contêineres esperam.

selector-report.txt
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

Suas perguntas, respondidas.

Toque em uma pergunta para expandir a resposta.

Porque é o que a regra diz, e é a linha mais surpreendente de toda a API de label selectors. No k8s.io/apimachinery, o Requirement.Matches resolve NotIn e != em um único ramo: se o conjunto de labels não tem a chave, o resultado é true. In e == tomam o ramo oposto: se a chave falta, o resultado é false. Então env!=prod significa «nenhuma label env valendo prod», e um pod sem label env cumpre isso perfeitamente. Se você queria dizer «tem uma label env, e ela não é prod», precisa de duas cláusulas: env,env!=prod — Exists E NotIn. Este tester anota toda cláusula que se cumpre porque a chave está ausente, então você nunca precisa lembrar em que sentido isso vai.

matchLabels é um mapa simples, e cada par vira um requisito de igualdade: {app: web, tier: frontend} é exatamente app=web,tier=frontend. matchExpressions é uma lista de entradas {key, operator, values} e é o único jeito de escrever os operadores baseados em conjunto In, NotIn, Exists e DoesNotExist. Quando um selector tem os dois, o apimachinery junta tudo com AND — o LabelSelectorAsSelector adiciona cada par de matchLabels e cada expressão à mesma lista de requisitos. Não existe OR em nenhum nível de um label selector.

Não, e esse é o erro que os manifestos gerados cometem com mais frequência. O spec.selector de um Service é tipado como map[string]string, não como LabelSelector: ele aceita um mapa simples de labels e só suporta igualdade. Se você escrever matchLabels ou matchExpressions ali, o API server rejeita o campo na hora. Deployments, StatefulSets, DaemonSets, Jobs e o podSelector de uma NetworkPolicy aceitam um LabelSelector de verdade e admitem as duas formas. Cole um manifesto de Service com matchExpressions neste tester e ele avisa, e depois mostra o que um Deployment TERIA casado — assim você vê o erro e a intenção ao mesmo tempo.

Depende de o campo estar vazio ou ausente, e não é a mesma coisa. Um LabelSelector vazio — {}, ou matchLabels: {} — é labels.Everything(): casa com todos os objetos, e é justamente por isso que uma NetworkPolicy com podSelector: {} vale para todos os pods do namespace. Um selector nil, ao contrário, não casa com nada: LabelSelectorAsSelector(nil) devolve labels.Nothing(). E um Service é um terceiro caso: o campo selector é omitido quando está vazio, então um Service com selector: {} é um Service sem selector, e o controlador de endpoints não gerencia os endpoints dele de forma alguma.

Não. Os dois parsers, a validação e o matcher são JavaScript rodando na sua aba — não há servidor, nem chamada de API, nem log, então 0 bytes são enviados. Aqui isso conta porque um dump de pods não é texto neutro: ele carrega referências de imagens internas, nomes de nós, annotations e às vezes um token montado como variável de ambiente. Esta é a ferramenta que você pode usar em saída de produção sem abrir uma conversa sobre tratamento de dados.

As labels dos pods, não o Service. Cole o manifesto do Service como selector e os pods reais como recursos: o tester lê o spec.selector para você e mostra um rastro por cláusula em cada pod, então um erro de digitação de um caractere aparece como label tier="frontnd" ≠ "frontend" em vez de uma lista de endpoints vazia. Descarte também duas armadilhas estruturais. Primeiro, um Service seleciona labels de POD, não os metadata.labels do próprio Deployment — é exatamente por isso que este tester lista o spec.template.metadata.labels de um workload como a própria linha «Pod template». Segundo, um selector que não casa com nada não é erro em nenhum lugar do Kubernetes: o kubectl aceita, o API server aceita, e o único sintoma é um objeto Endpoints vazio.

Não, e isso é uma fronteira deliberada, não uma lacuna. Field selectors são outro mecanismo: filtram pelos campos do próprio objeto, são avaliados pelo API server contra uma lista curta de campos permitidos que varia por tipo de recurso, e quase nenhum suporta operadores baseados em conjunto. Simulá-los offline significaria codificar quais campos cada versão do Kubernetes indexa para cada kind, e errar de forma sutil. Esta ferramenta cobre label selectors, que funcionam igual em todos os tipos de recurso e ficam totalmente definidos pelo objeto que você já tem na área de transferência.

Eles existem, mas não em um label selector. Node affinity usa NodeSelectorRequirement, um tipo separado cujo conjunto de operadores é In, NotIn, Exists, DoesNotExist, Gt e Lt. Um LabelSelectorRequirement — o de matchExpressions, spec.selector e podSelector — tem só os quatro primeiros. Então Gt e Lt são válidos em nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution e inválidos em tudo o que este tester olha. Digite replicas>2 no campo do selector e ele diz isso, em vez de inventar uma comparação que um label selector não tem.

Ele avalia os primeiros 500 documentos de recursos de uma colagem de até 500.000 caracteres, e um selector de no máximo 100 cláusulas — cada limite se anuncia na tela com o número real, então uma execução truncada nunca parece completa. Chaves e valores são validados contra os limites reais: o nome de uma chave de label vai até 63 caracteres, o prefixo de subdomínio DNS opcional antes da / vai até 253, e um valor de label vai até 63 (valor vazio é legal). Uma chave ou valor inválido no SELECTOR é erro que bloqueia, porque o API server rejeitaria; uma label inválida em um RECURSO é só uma nota, porque a pergunta que você fez foi se o selector casa com ele.

More free, private DevOps tools.

O Label Selector Tester é uma ferramenta do OpsCanopy — uma copa crescente de validadores, conversores e testers que rodam no navegador e nunca encostam em um servidor.

39 free tools, every one offline-capable — opscanopy.com works with no signup and nothing uploaded.

Relacionado: Kubernetes Resource Calculator para o que um workload reserva, Env Example Checker para as variáveis que um contêiner espera, o Alertmanager Route Tester para a outra árvore de correspondência por labels que descarta coisas em silêncio, e o Conversor JSON ↔ YAML quando um manifesto precisa ser remodelado para kubectl patch — ou navegue pelo diretório de ferramentas completo.

Fornecido como está, por conveniência; confirme sempre configuração crítica contra o cluster que vai consumi-la. O OpsCanopy é gratuito e aberto.