Fatskills
Practice. Master. Repeat.
Study Guide: TECH **Docker & Kubernetes: Labels, Selectors, and Annotations – Zero-Fluff Study Guide**
Source: https://www.fatskills.com/kubernetes/chapter/tech-docker-kubernetes-labels-selectors-and-annotations-zero-fluff-study-guide

TECH **Docker & Kubernetes: Labels, Selectors, and Annotations – Zero-Fluff Study Guide**

By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.

⏱️ ~7 min read

Docker & Kubernetes: Labels, Selectors, and Annotations – Zero-Fluff Study Guide


1. What This Is & Why It Matters

Labels, selectors, and annotations are the "metadata glue" that makes Kubernetes (and Docker, to a lesser extent) manageable at scale. Think of them like sticky notes on a filing cabinet—without them, you’d have no way to organize, filter, or automate your workloads.

Why This Matters in Production

  • Without labels/selectors, you can’t:
  • Roll out updates to a specific subset of pods (e.g., "only the canary version").
  • Route traffic to a specific service tier (e.g., tier: frontend vs. tier: backend).
  • Clean up old resources automatically (e.g., "delete all pods with env: staging").
  • Without annotations, you lose:
  • The ability to attach non-identifying metadata (e.g., "who deployed this?" or "what commit hash is this?").
  • Integration with third-party tools (e.g., Prometheus, Istio, or AWS ALB Ingress Controller).

Real-World Scenario

You’re a DevOps engineer at a fintech startup. Your team deploys 100+ microservices across multiple environments (dev, staging, prod). A security audit flags that old staging pods are still running and consuming resources. Without proper labels, you’d have to manually delete each pod—a nightmare at scale. With labels, you run:


kubectl delete pods -l env=staging

Done in one command.


2. Core Concepts & Components


? Labels

  • Definition: Key-value pairs attached to Kubernetes objects (Pods, Services, Deployments, etc.) for identification and grouping.
  • Production Insight:
  • Always label your resources—even in dev. Future-you will thank past-you when debugging.
  • Avoid using name as a label key—it’s redundant (Kubernetes already has a metadata.name field).
  • Label keys must follow DNS subdomain rules (e.g., app.kubernetes.io/name is valid; my app is not).

? Selectors

  • Definition: A query mechanism to filter objects based on labels.
  • Production Insight:
  • Services use selectors to route traffic to the right pods. If your selector doesn’t match any pods, your service won’t work.
  • Deployments use selectors to manage replicas. If you change a pod’s labels, the Deployment loses track of it (orphaned pods!).
  • kubectl get supports selectors (e.g., kubectl get pods -l app=nginx).

? Annotations

  • Definition: Key-value pairs for non-identifying metadata (e.g., build info, tooling data, descriptions).
  • Production Insight:
  • Annotations are for humans and tools, not Kubernetes itself. Kubernetes ignores them for scheduling.
  • Use annotations for:
    • CI/CD metadata (git-commit: abc123).
    • Tooling configs (e.g., prometheus.io/scrape: "true").
    • Descriptions (description: "This pod runs the payment service").
  • Never use annotations for filtering—that’s what labels are for.

? Label vs. Annotation: When to Use Which

Use Case Label Annotation
Grouping objects (e.g., env=prod) ✅ Yes ❌ No
Filtering with selectors ✅ Yes ❌ No
Attaching tooling metadata (e.g., Prometheus) ❌ No ✅ Yes
Describing a resource (e.g., "This pod runs the API") ❌ No ✅ Yes
CI/CD build info (e.g., git-commit) ❌ No ✅ Yes


3. Step-by-Step Hands-On


Prerequisites

  • A running Kubernetes cluster (Minikube, Kind, or cloud-based).
  • kubectl installed and configured.
  • Basic familiarity with kubectl commands (apply, get, delete).

Task: Deploy a Canary Release Using Labels & Selectors

Goal: Deploy two versions of an app (v1 and v2) and use labels to route 10% of traffic to v2 (canary testing).


Step 1: Deploy v1 of the App

# app-v1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-v1
spec:
  replicas: 3
  selector:
matchLabels:
app: myapp
version: v1 template:
metadata:
labels:
app: myapp
version: v1
spec:
containers:
- name: nginx
image: nginx:1.23
ports:
- containerPort: 80

Apply it:


kubectl apply -f app-v1.yaml

Step 2: Deploy v2 (Canary) of the App

# app-v2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-v2
spec:
  replicas: 1  # Only 1 pod for canary (10% of total traffic)
  selector:
matchLabels:
app: myapp
version: v2 template:
metadata:
labels:
app: myapp
version: v2
spec:
containers:
- name: nginx
image: nginx:1.24
ports:
- containerPort: 80

Apply it:


kubectl apply -f app-v2.yaml

Step 3: Create a Service to Route Traffic

# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  selector:
app: myapp # Matches BOTH v1 and v2 pods ports:
- protocol: TCP
port: 80
targetPort: 80

Apply it:


kubectl apply -f service.yaml

Step 4: Verify Traffic Splitting

  1. Check which pods are running:
    bash
    kubectl get pods -l app=myapp --show-labels

    Expected Output:
    NAME READY STATUS LABELS
    myapp-v1-5f7d8c6b7c-abc12 1/1 Running app=myapp,version=v1
    myapp-v1-5f7d8c6b7c-def34 1/1 Running app=myapp,version=v1
    myapp-v1-5f7d8c6b7c-ghi56 1/1 Running app=myapp,version=v1
    myapp-v2-7d8f9g0h1i-jkl78 1/1 Running app=myapp,version=v2
  2. Check the service’s endpoints (which pods it routes to):
    bash
    kubectl get endpoints myapp-service -o yaml

    Expected Output:
    ```yaml
    subsets:
  3. addresses:
    • ip: 10.244.1.2 # v1 pod
    • ip: 10.244.1.3 # v1 pod
    • ip: 10.244.1.4 # v1 pod
    • ip: 10.244.1.5 # v2 pod (canary) ports:
    • port: 80
      ```
  4. Test traffic distribution (run this in a loop):
    bash
    for i in {1..10}; do kubectl exec -it <any-pod> -- curl myapp-service; done
  5. ~90% of requests should go to v1 (nginx 1.23).
  6. ~10% of requests should go to v2 (nginx 1.24).

Step 5: Clean Up

kubectl delete -f app-v1.yaml -f app-v2.yaml -f service.yaml


4. ? Production-Ready Best Practices


? Security

  • Never expose sensitive data in labels/annotations (e.g., password: 12345). Use Secrets instead.
  • Use app.kubernetes.io/ labels for better tooling compatibility (e.g., app.kubernetes.io/name: myapp).
  • Restrict label/annotation keys in RBAC policies if needed (e.g., prevent users from modifying env=prod).

? Cost Optimization

  • Use labels to track cost centers (e.g., cost-center: marketing). Tools like Kubecost use labels for cost allocation.
  • Label old resources for cleanup (e.g., lifecycle: delete-after-30d). Use a tool like kube-janitor to auto-delete them.

?️ Reliability & Maintainability

  • Standardize label keys across teams (e.g., always use env, not environment or stage).
  • Use immutable labels (e.g., version: v1). Changing labels on running pods can break Deployments.
  • Add annotations for troubleshooting (e.g., contact: [email protected]).

? Observability

  • Label pods for Prometheus scraping (e.g., prometheus.io/scrape: "true").
  • Use annotations for logging metadata (e.g., fluentd-tag: app.logs).
  • Track deployment history with annotations (e.g., kubernetes.io/change-cause: "Updated to v2.1.0").


5. ⚠️ Common Mistakes & Traps

Mistake Symptom Fix/Prevention
Mismatched selectors in Deployment vs. Pod Pods are created but never reach Running state. Ensure spec.selector.matchLabels matches spec.template.metadata.labels.
Changing labels on running pods Deployment loses track of pods (orphaned pods). Never modify labels on running pods. Update the Deployment instead.
Using annotations for filtering kubectl get -l doesn’t work as expected. Use labels for filtering, annotations for metadata.
Overloading labels with too much data kubectl get pods --show-labels becomes unreadable. Keep labels short and meaningful (e.g., env=prod, not environment=production).
Forgetting to label resources Can’t clean up old resources efficiently. Always label resources—even in dev. Use app, env, and version as a minimum.


6. ? Exam/Certification Focus


Typical Question Patterns

  1. "Which of the following is a valid label key?"
  2. my app (spaces not allowed)
  3. 123app (must start with alphanumeric)
  4. app.kubernetes.io/name (valid DNS subdomain)
  5. app (valid)

  6. "How do you delete all pods with env=staging?"

  7. kubectl delete pods -l env=staging
  8. kubectl delete pods --selector env=staging (works but less common)
  9. kubectl delete pods --annotation env=staging (annotations ≠ labels)

  10. "What happens if a Service’s selector doesn’t match any pods?"

  11. The Service won’t route traffic (no endpoints).
  12. kubectl get endpoints <service> will show no IPs.

  13. "Can you use annotations for filtering in kubectl get?"

  14. ❌ No. Annotations are for metadata, not filtering.

Key ⚠️ Trap Distinctions

Concept Labels Annotations
Purpose Grouping/filtering Metadata (non-identifying)
Used by Kubernetes? ✅ Yes (selectors, scheduling) ❌ No (ignored by Kubernetes)
Example Use Case kubectl get pods -l app=nginx prometheus.io/scrape: "true"


7. ? Hands-On Challenge


Challenge

You have a Kubernetes cluster with 10 pods running different versions of an app (v1, v2, v3). Delete all v2 pods without affecting v1 or v3.

Solution

kubectl delete pods -l version=v2

Why it works:
- -l version=v2 selects only pods with the label version: v2.
- The other pods (v1, v3) remain untouched.


8. ? Rapid-Reference Crib Sheet

Command/Concept Example Notes
List pods with labels kubectl get pods --show-labels Shows all labels for each pod.
Filter pods by label kubectl get pods -l app=nginx Only shows pods with app=nginx.
Delete resources by label kubectl delete pods -l env=staging Deletes all pods with env=staging.
Label a running pod kubectl label pod mypod env=prod ⚠️ Can break Deployments if not careful.
Add an annotation kubectl annotate pod mypod description="API service" Annotations are for metadata.
View annotations kubectl describe pod mypod Annotations appear under Annotations:.
Service selector spec.selector.app: myapp Must match pod labels.
Deployment selector spec.selector.matchLabels.app: myapp Must match pod template labels.
Valid label key app.kubernetes.io/name Must be a DNS subdomain.
Invalid label key my app Spaces not allowed.


9. ? Where to Go Next

  1. Kubernetes Official Docs – Labels & Selectors
  2. Kubernetes Best Practices – Labeling
  3. Kubectl Cheat Sheet – Labels & Selectors
  4. Prometheus Annotations for Monitoring


ADVERTISEMENT