🎤Speaking at KubeCon EU 2026Lessons Learned Orchestrating Multi-Tenant GPUs on OpenShift AIView Session
Configuration beginner ⏱ 15 minutes K8s 1.28+

How to Use Labels and Annotations Effectively

Organize and manage Kubernetes resources with labels and annotations. Implement labeling strategies for selection, filtering, and metadata.

By Luca Berton

How to Use Labels and Annotations Effectively

Labels identify and select resources, while annotations store non-identifying metadata. A consistent labeling strategy is essential for managing Kubernetes at scale.

Labels vs Annotations

# Labels: For identification and selection
# - Used by selectors (Services, Deployments, etc.)
# - Queryable via kubectl
# - Keep values short (< 63 chars)

# Annotations: For metadata and tooling
# - Not used for selection
# - Can store larger values
# - Used by tools, controllers, and humans
# Kubernetes recommended labels
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  labels:
    app.kubernetes.io/name: myapp
    app.kubernetes.io/instance: myapp-prod
    app.kubernetes.io/version: "1.2.3"
    app.kubernetes.io/component: frontend
    app.kubernetes.io/part-of: ecommerce
    app.kubernetes.io/managed-by: helm
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: myapp
      app.kubernetes.io/instance: myapp-prod
  template:
    metadata:
      labels:
        app.kubernetes.io/name: myapp
        app.kubernetes.io/instance: myapp-prod
        app.kubernetes.io/version: "1.2.3"
        app.kubernetes.io/component: frontend

Custom Label Strategy

# Organization labels
metadata:
  labels:
    # Application identification
    app: myapp
    component: api
    version: v1
    
    # Environment
    environment: production
    tier: backend
    
    # Ownership
    team: platform
    owner: alice@company.com
    cost-center: engineering
    
    # Lifecycle
    release: stable
    canary: "false"

Label Selectors

# Equality-based selectors
kubectl get pods -l app=myapp
kubectl get pods -l environment=production
kubectl get pods -l 'app=myapp,environment=production'

# Set-based selectors
kubectl get pods -l 'environment in (production, staging)'
kubectl get pods -l 'environment notin (development)'
kubectl get pods -l 'team'           # Has label
kubectl get pods -l '!canary'        # Doesn't have label

# Combined selectors
kubectl get pods -l 'app=myapp,environment in (production, staging),!canary'

Service Selector

# Service selects pods by labels
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  selector:
    app: myapp
    component: api
  ports:
    - port: 80
      targetPort: 8080

Network Policy Selectors

# Network policy using labels
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-policy
spec:
  podSelector:
    matchLabels:
      app: myapp
      component: api
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: myapp
              component: frontend

Manage Labels

# Add label
kubectl label pod myapp-pod environment=production

# Update label (overwrite)
kubectl label pod myapp-pod environment=staging --overwrite

# Remove label
kubectl label pod myapp-pod environment-

# Label multiple resources
kubectl label pods -l app=myapp release=v2

# Label all pods in namespace
kubectl label pods --all reviewed=true

Common Annotations

# Useful annotations
metadata:
  annotations:
    # Documentation
    description: "Main API server for user management"
    docs: "https://wiki.company.com/myapp"
    
    # Ownership and contact
    owner: "platform-team@company.com"
    slack-channel: "#platform-support"
    pagerduty: "platform-oncall"
    
    # Deployment info
    kubernetes.io/change-cause: "Update to v1.2.3 for security fix"
    deployment.kubernetes.io/revision: "5"
    
    # Build info
    build.git/commit: "abc123def"
    build.git/branch: "main"
    build.ci/pipeline: "12345"
    build.ci/url: "https://ci.company.com/build/12345"
    
    # Prometheus scraping
    prometheus.io/scrape: "true"
    prometheus.io/port: "8080"
    prometheus.io/path: "/metrics"

Ingress Annotations

# Ingress controller annotations
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
  annotations:
    # nginx ingress
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: "10m"
    
    # cert-manager
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
    
    # external-dns
    external-dns.alpha.kubernetes.io/hostname: "myapp.example.com"

Manage Annotations

# Add annotation
kubectl annotate pod myapp-pod description="Main API pod"

# Update annotation
kubectl annotate pod myapp-pod description="Updated API pod" --overwrite

# Remove annotation
kubectl annotate pod myapp-pod description-

# View annotations
kubectl get pod myapp-pod -o jsonpath='{.metadata.annotations}'

Label Nodes

# Add node labels for scheduling
kubectl label node node1 disktype=ssd
kubectl label node node1 gpu=nvidia
kubectl label node node1 topology.kubernetes.io/zone=us-east-1a

# Use in nodeSelector
spec:
  nodeSelector:
    disktype: ssd
    gpu: nvidia

Namespace Labels

# Namespace with labels
apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    environment: production
    team: platform
    # Pod Security Standards
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/warn: restricted

Query Resources by Labels

# List pods with specific labels
kubectl get pods -l app=myapp --show-labels

# Get all labels for resources
kubectl get pods --show-labels

# Count resources by label
kubectl get pods -l environment=production --no-headers | wc -l

# Get unique label values
kubectl get pods -o jsonpath='{.items[*].metadata.labels.environment}' | tr ' ' '\n' | sort -u

# Find resources without required label
kubectl get pods -l '!team'

Labeling Best Practices

1. Use consistent naming conventions
   - Prefix custom labels: company.com/label
   - Use lowercase, alphanumeric, -, _, .

2. Required labels for all resources:
   - app: Application name
   - environment: dev/staging/prod
   - team/owner: Ownership

3. Don't put sensitive data in labels/annotations
   - They're not encrypted
   - Visible in kubectl output

4. Keep label values short
   - Max 63 characters
   - Alphanumeric, -, _, .

5. Use annotations for:
   - Build/deployment metadata
   - Tool configuration
   - Documentation links

Validate Labels with Admission

# Kyverno policy requiring labels
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-labels
spec:
  validationFailureAction: Enforce
  rules:
    - name: require-team-label
      match:
        resources:
          kinds:
            - Pod
      validate:
        message: "All pods must have a 'team' label"
        pattern:
          metadata:
            labels:
              team: "?*"

Summary

Labels identify and select resources - use them consistently for Services, NetworkPolicies, and kubectl queries. Recommended labels include app.kubernetes.io/name, version, component, and environment. Annotations store metadata for tools and documentation like build info, prometheus scraping, and ingress configuration. Use kubectl label and kubectl annotate to manage them. Establish a labeling strategy early and enforce it with admission controllers for consistent resource organization at scale.


📘 Go Further with Kubernetes Recipes

Love this recipe? There’s so much more! This is just one of 100+ hands-on recipes in our comprehensive Kubernetes Recipes book.

Inside the book, you’ll master:

  • ✅ Production-ready deployment strategies
  • ✅ Advanced networking and security patterns
  • ✅ Observability, monitoring, and troubleshooting
  • ✅ Real-world best practices from industry experts

“The practical, recipe-based approach made complex Kubernetes concepts finally click for me.”

👉 Get Your Copy Now — Start building production-grade Kubernetes skills today!

#labels #annotations #organization #selectors #metadata

Want More Kubernetes Recipes?

This recipe is from Kubernetes Recipes, our 750-page practical guide with hundreds of production-ready patterns.