Labels and Selectors

Welcome to the Labels and Selectors chapter. This section covers fundamental concepts and best practices necessary to master this topic in depth.

1. The Metadata Engine

Kubernetes objects do not hold hardcoded references to each other (e.g., a Service does not say “Route traffic to Pod ID 12345”). Instead, they rely on a loosely coupled metadata system: Labels and Selectors.

What are Labels?

Labels are simply key-value pairs attached to objects (like Pods). They define the identity or attributes of the object.

  • env: production
  • tier: backend
  • version: v1.2.0

What are Selectors?

Selectors are queries used by other objects (like Services or ReplicaSets) to find objects with matching labels.

  • “Find all Pods where tier=backend AND env=production

2. MatchLabels vs MatchExpressions

Kubernetes supports two types of selectors:

  1. Equality-Based (matchLabels): Exact match required.
    selector:
      matchLabels:
        app: my-web
    
  2. Set-Based (matchExpressions): More complex logic (In, NotIn, Exists, DoesNotExist).
    selector:
      matchExpressions:
        - {key: tier, operator: In, values: [frontend, backend]}
        - {key: env, operator: NotIn, values: [dev]}
    

3. Interactive: Label Query Engine

Test different selector queries against a mock cluster of labeled Pods.

Query Engine

Cluster Pods


4. Selecting in Practice

CLI (kubectl)
YAML Manifest
Go
# Add a label to an existing pod
kubectl label pods my-pod env=production

# Overwrite an existing label
kubectl label pods my-pod env=staging --overwrite

# Get all pods with a specific label
kubectl get pods -l env=production

# Set-based querying from CLI
kubectl get pods -l 'env in (production, staging), tier!=frontend'

# Remove a label (use a minus sign)
kubectl label pods my-pod env-
# A Service selecting Pods
apiVersion: v1
kind: Service
metadata:
  name: backend-service
spec:
  selector:
    app: my-app
    tier: backend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
// Using client-go to list pods by label selector
import (
	"context"
	"fmt"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
)

func listPodsByLabel(clientset *kubernetes.Clientset, namespace, labelSelector string) error {

    listOptions := metav1.ListOptions{
        LabelSelector: labelSelector, // e.g. "env=production,tier=backend"
    }

    pods, err := clientset.CoreV1().Pods(namespace).List(context.TODO(), listOptions)
    if err != nil {
        return err
    }

    fmt.Printf("Found %d pods matching %s\n", len(pods.Items), labelSelector)
    for _, pod := range pods.Items {
        fmt.Printf("- %s\n", pod.Name)
    }

    return nil
}