In this episode, we'll discuss one of the most important concepts in Kubernetes called Labels. We'll learn how to use Labels to organize, identify, and manage Kubernetes objects effectively.

Note
If you want to read the previous episode, you can click the Episode 5 thumbnail below
In the previous episode, we learned deeply about the Pod object in Kubernetes. In episode 6, we'll discuss one of the most important concepts in Kubernetes: Labels.
Note: Here I'll be using a Kubernetes Cluster installed through K3s.
Labels are a fundamental concept in Kubernetes that you'll use constantly when working with clusters. Understanding Labels is crucial because they're used for organizing, identifying, and managing Kubernetes objects. Without Labels, managing multiple objects in a cluster becomes extremely difficult.
A Label is a key-value pair that you attach to Kubernetes objects to identify and organize them. Think of Labels like tags or stickers you put on objects to categorize them. For example, in a real-world scenario, you might have multiple Pods running different applications. Without Labels, it would be difficult to identify which Pod belongs to which application or environment.
Labels are metadata that help you:
A Label consists of two parts:
app, environment, version)nginx, production, v1.0)For example:
app: nginx
environment: production
version: v1.0When creating Labels, you need to follow these naming conventions:
-), underscores (_), and dots (.)-), underscores (_), and dots (.)Valid examples:
app: nginx
tier: backend
version: v1.0
environment: prod-us-eastInvalid examples:
-app: nginx # Key starts with hyphen
app-: nginx # Key ends with hyphen
app: -nginx # Value starts with hyphen
app: nginx- # Value ends with hyphenYou might wonder why we need Labels when we already have object names. The key difference is that names are unique identifiers for individual objects, while Labels are used to group and organize multiple objects.
Consider this scenario: You have 10 Pods running in your cluster. Some are running Nginx, some are running PostgreSQL, and some are running Redis. Without Labels, you'd have to manually track which Pod is which. With Labels, you can simply query all Pods with app: nginx and get all Nginx Pods instantly.
Another important use case is Label Selectors. Label Selectors allow you to select a group of objects based on their labels. This is used extensively in Kubernetes for:
In production Kubernetes environments, there are common labeling patterns that teams use:
These labels identify what application a resource belongs to:
app: nginx
app.kubernetes.io/name: nginx
app.kubernetes.io/instance: nginx-prodThese labels identify the environment:
environment: production
environment: staging
environment: developmentThese labels track the version of an application:
version: v1.0
version: v2.0
app.kubernetes.io/version: 1.0.0These labels identify the component or tier:
tier: frontend
tier: backend
tier: database
component: api
component: workerThese labels identify who owns or manages the resource:
owner: platform-team
team: backend
managed-by: terraformNow let's learn how to add Labels to Kubernetes objects. There are two main ways to add Labels:
The most common way is to add Labels directly in the YAML configuration file under the metadata section:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
environment: production
tier: frontend
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80In this example, we've added three labels to the Pod:
app: nginx - Identifies this as an Nginx applicationenvironment: production - Indicates this is running in productiontier: frontend - Indicates this is a frontend componentYou can also add Labels to existing objects using the kubectl label command:
sudo kubectl label pod <pod_name> <key>=<value>For example, to add a label to an existing Pod:
sudo kubectl label pod nginx-pod app=nginxTo add multiple labels at once:
sudo kubectl label pod nginx-pod app=nginx environment=production tier=frontendTo overwrite an existing label, use the --overwrite flag:
sudo kubectl label pod nginx-pod environment=staging --overwriteAfter adding Labels to objects, you can view them using various kubectl commands:
To view the labels of objects, use the kubectl get command with the -L or --label-columns flag:
sudo kubectl get pod -L app,environment,tierThe output will look like this:
NAME READY STATUS RESTARTS AGE APP ENVIRONMENT TIER
nginx-pod 1/1 Running 0 5m nginx production frontendTo see all labels on an object, use the kubectl describe command:
sudo kubectl describe pod nginx-podThe output will include the labels section:
Label Selectors are queries that allow you to select objects based on their labels. There are two types of label selectors:
Equality-based selectors use =, ==, or != operators:
# Select all Pods with app=nginx
sudo kubectl get pod -l app=nginx
# Select all Pods with environment=production
sudo kubectl get pod -l environment=production
# Select all Pods that are NOT in production
sudo kubectl get pod -l environment!=productionSet-based selectors use in, notin, and exists operators:
# Select Pods where environment is either production or staging
sudo kubectl get pod -l "environment in (production,staging)"
# Select Pods where environment is NOT development
sudo kubectl get pod -l "environment notin (development)"
# Select Pods that have the tier label (regardless of value) or called exists operator
sudo kubectl get pod -l tier
# Select Pods that don't have the tier label or called not exists operator
sudo kubectl get pod -l "!tier"You can combine multiple selectors with commas (AND logic):
# Select Pods with app=nginx AND environment=production
sudo kubectl get pod -l app=nginx,environment=production
# Select Pods with app=nginx AND tier=frontend
sudo kubectl get pod -l app=nginx,tier=frontendLet's create a practical example where we create multiple Pods with different labels and then query them:
Create a file named labeled-pods.yml:
apiVersion: v1
kind: Pod
metadata:
name: nginx-prod-frontend
labels:
app: nginx
environment: production
tier: frontend
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Pod
metadata:
name: nginx-prod-backend
labels:
app: nginx
environment: production
tier: backend
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Pod
metadata:
name: nginx-dev-frontend
labels:
app: nginx
environment: development
tier: frontend
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Pod
metadata:
name: postgres-prod
labels:
app: postgres
environment: production
tier: database
spec:
containers:
- name: postgres
image: postgres:15
ports:
- containerPort: 5432sudo kubectl apply -f labeled-pods.ymlNow let's query the Pods using different label selectors:
# Get all Pods with app=nginx
sudo kubectl get pod -l app=nginxOutput:
NAME READY STATUS RESTARTS AGE
nginx-prod-frontend 1/1 Running 0 2m
nginx-prod-backend 1/1 Running 0 2m
nginx-dev-frontend 1/1 Running 0 2m# Get all Pods in production environment
sudo kubectl get pod -l environment=productionOutput:
Note
If the postgres-prod pod has an error, we can ignore it for now, since this episode focuses on discussing the Label object.
NAME READY STATUS RESTARTS AGE
nginx-prod-frontend 1/1 Running 0 2m
nginx-prod-backend 1/1 Running 0 2m
postgres-prod 1/1 Running 0 2m# Get all frontend Pods
sudo kubectl get pod -l tier=frontendOutput:
NAME READY STATUS RESTARTS AGE
nginx-prod-frontend 1/1 Running 0 2m
nginx-dev-frontend 1/1 Running 0 2m# Get all Pods with app=nginx AND environment=production
sudo kubectl get pod -l app=nginx,environment=productionOutput:
NAME READY STATUS RESTARTS AGE
nginx-prod-frontend 1/1 Running 0 2m
nginx-prod-backend 1/1 Running 0 2mTip
Don't forget to get used to deleting resources like Pods that are no longer in use so that our computer can run other Pods without obstacles. To delete it, you can run the following command
sudo kubectl delete -f labeled-pods.ymlLabels are not just used for Pods. You can add Labels to any Kubernetes object. Here are some common use cases:
When you create a Deployment, it automatically creates Pods with labels. The Deployment uses label selectors to manage its Pods:
Important
On the Deployment object there are 2 metadata, the metadata at the top is for the Deployment object itself, while the metadata in the template is for the Pod object, so all Pods will have the same metadata based on what is in the template. The metadata in the template is also used as selector identification in its matchLabels.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
version: v1
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
version: v1
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80After successfully creating it, we can check the Pods running using the Deployment with the following command
sudo kubectl get pod -l version=v1The output will look like this
NAME READY STATUS RESTARTS AGE
nginx-deployment-58fc95c95c-ctzzf 1/1 Running 0 2m12s
nginx-deployment-58fc95c95c-sxskq 1/1 Running 0 2m12s
nginx-deployment-58fc95c95c-w8xw8 1/1 Running 0 2m12sServices use label selectors to find Pods to route traffic to:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
app: nginx
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIPOne common mistake is using inconsistent label names across objects. For example, using app in one Pod and application in another. This makes it difficult to query objects consistently.
Solution: Establish a labeling convention for your team and stick to it. Use standardized label names like app, environment, tier, etc.
While labels are useful, adding too many labels to objects can make them difficult to manage and understand.
Solution: Use only the labels you actually need. Typically, 3-5 labels per object is sufficient.
Label values should be concise and meaningful. Avoid putting long descriptions or complex information in label values.
Solution: Keep label values short and simple. Use hyphens to separate words if needed (e.g., prod-us-east instead of production-united-states-east).
When you update an object's configuration, you might forget to update its labels. This can lead to inconsistencies.
Solution: Always review and update labels when making changes to objects.
Kubernetes recommends using a set of standard labels. These are prefixed with app.kubernetes.io/:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app.kubernetes.io/name: nginx
app.kubernetes.io/instance: nginx-prod
app.kubernetes.io/version: "1.0"
app.kubernetes.io/component: web-server
app.kubernetes.io/part-of: web-application
app.kubernetes.io/managed-by: helm
spec:
containers:
- name: nginx
image: nginxUse labels to organize resources by team, project, or cost center:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
team: platform
project: web-app
cost-center: engineering
owner: john-doe
spec:
containers:
- name: nginx
image: nginxCreate documentation for your team about what labels to use and when. This ensures consistency across your cluster.
You can use labels to schedule Pods on specific nodes:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
nodeSelector:
disk: ssd
zone: us-east-1a
containers:
- name: nginx
image: nginxWhile labels are powerful, there are cases where you shouldn't use them:
In episode 6, we've explored the Label concept in Kubernetes in depth. We've learned what labels are, why they're important, how to add them to objects, and how to use label selectors to query and manage objects.
Labels are fundamental to working effectively with Kubernetes. They enable you to organize, identify, and manage your cluster resources at scale. By following best practices and establishing consistent labeling conventions, you can make your Kubernetes cluster much easier to manage and understand.
Understanding labels is crucial before moving on to more advanced Kubernetes concepts like Services, Deployments, and StatefulSets, which all rely heavily on labels for their operation.
Are you getting a clearer understanding of Labels in Kubernetes? In the next episode 7, we'll discuss another important Kubernetes concept that complements labels: Annotation. While labels are used for identification and selection, annotations are used to attach arbitrary metadata to objects. Keep your learning momentum going and look forward to the next episode!