Learning Kubernetes - Episode 6 - Introduction and Explanation of Label Object

Learning Kubernetes - Episode 6 - Introduction and Explanation of Label Object

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.

Arman Dwi Pangestu
Arman Dwi PangestuFebruary 28, 2026
0 views
10 min read

Introduction

Note

If you want to read the previous episode, you can click the Episode 5 thumbnail below

Episode 5Episode 5

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.

What Are Labels?

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:

  • Identify objects - Know which Pod belongs to which application
  • Organize objects - Group Pods by environment (production, staging, development)
  • Select objects - Use label selectors to query and manage specific objects
  • Manage objects - Apply operations to multiple objects that share the same labels

Label Format

A Label consists of two parts:

  • Key - The identifier for the label (e.g., app, environment, version)
  • Value - The value assigned to that key (e.g., nginx, production, v1.0)

For example:

Kubernetesyml
app: nginx
environment: production
version: v1.0

Label Naming Rules

When creating Labels, you need to follow these naming conventions:

  • Keys can be up to 63 characters long
  • Keys must start and end with alphanumeric characters
  • Keys can contain hyphens (-), underscores (_), and dots (.)
  • Values can be up to 63 characters long
  • Values must start and end with alphanumeric characters
  • Values can contain hyphens (-), underscores (_), and dots (.)

Valid examples:

KubernetesExample Correct Label
app: nginx
tier: backend
version: v1.0
environment: prod-us-east

Invalid examples:

KubernetesExample Incorrect Label
-app: nginx          # Key starts with hyphen
app-: nginx          # Key ends with hyphen
app: -nginx          # Value starts with hyphen
app: nginx-          # Value ends with hyphen

Why Do We Need Labels?

You 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:

  • Service discovery - Services use label selectors to find Pods to route traffic to
  • Deployment management - Deployments use label selectors to manage their Pods
  • Resource management - You can apply operations to multiple objects matching a label selector

Common Label Patterns

In production Kubernetes environments, there are common labeling patterns that teams use:

Application Labels

These labels identify what application a resource belongs to:

Kubernetesyml
app: nginx
app.kubernetes.io/name: nginx
app.kubernetes.io/instance: nginx-prod

Environment Labels

These labels identify the environment:

Kubernetesyml
environment: production
environment: staging
environment: development

Version Labels

These labels track the version of an application:

Kubernetesyml
version: v1.0
version: v2.0
app.kubernetes.io/version: 1.0.0

Component Labels

These labels identify the component or tier:

Kubernetesyml
tier: frontend
tier: backend
tier: database
component: api
component: worker

Owner Labels

These labels identify who owns or manages the resource:

Kubernetesyml
owner: platform-team
team: backend
managed-by: terraform

Adding Labels to Objects

Now let's learn how to add Labels to Kubernetes objects. There are two main ways to add Labels:

Method 1: Adding Labels in YAML Configuration

The most common way is to add Labels directly in the YAML configuration file under the metadata section:

Kubernetespod-with-labels.yml
apiVersion: v1
kind: Pod
metadata:
    name: nginx-pod
    labels:
        app: nginx
        environment: production
        tier: frontend
spec:
    containers:
        - name: nginx
          image: nginx
          ports:
              - containerPort: 80

In this example, we've added three labels to the Pod:

  • app: nginx - Identifies this as an Nginx application
  • environment: production - Indicates this is running in production
  • tier: frontend - Indicates this is a frontend component

Method 2: Adding Labels with kubectl Command

You can also add Labels to existing objects using the kubectl label command:

Kubernetesbash
sudo kubectl label pod <pod_name> <key>=<value>

For example, to add a label to an existing Pod:

Kubernetesbash
sudo kubectl label pod nginx-pod app=nginx

To add multiple labels at once:

Kubernetesbash
sudo kubectl label pod nginx-pod app=nginx environment=production tier=frontend

To overwrite an existing label, use the --overwrite flag:

Kubernetesbash
sudo kubectl label pod nginx-pod environment=staging --overwrite

Viewing Labels

After adding Labels to objects, you can view them using various kubectl commands:

View Labels with kubectl get

To view the labels of objects, use the kubectl get command with the -L or --label-columns flag:

Kubernetesbash
sudo kubectl get pod -L app,environment,tier

The output will look like this:

Kubernetesbash
NAME        READY   STATUS    RESTARTS   AGE     APP     ENVIRONMENT   TIER
nginx-pod   1/1     Running   0          5m      nginx   production    frontend

View All Labels

To see all labels on an object, use the kubectl describe command:

Kubernetesbash
sudo kubectl describe pod nginx-pod

The output will include the labels section:

Kubernetesbash
Name:             nginx-pod
Namespace:        default
Priority:         0
Service Account:  default
Node:             devnull/10.10.10.4
Start Time:       Sat, 28 Feb 2026 13:08:25 +0700
Labels:           app=nginx
                  environment=staging
                  tier=frontend
Annotations:      <none>
Status:           Running
IP:               10.42.0.25
IPs:
  IP:  10.42.0.25
Containers:
  nginx:
    Container ID:   containerd://aa4f41008b45cfa4831de099b63dab0191b61f7daa5928ff7729cffd32fbeb6a
    Image:          nginx
    Image ID:       docker.io/library/nginx@sha256:0236ee02dcbce00b9bd83e0f5fbc51069e7e1161bd59d99885b3ae1734f3392e
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Sat, 28 Feb 2026 13:08:53 +0700
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-rd8mn (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True 
  Initialized                 True 
  Ready                       True 
  ContainersReady             True 
  PodScheduled                True 
Volumes:
  kube-api-access-rd8mn:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    Optional:                false
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  3m17s  default-scheduler  Successfully assigned default/nginx-pod to devnull
  Normal  Pulling    3m11s  kubelet            Pulling image "nginx"
  Normal  Pulled     2m49s  kubelet            Successfully pulled image "nginx" in 21.235s (21.235s including waiting). Image size: 62944796 bytes.
  Normal  Created    2m49s  kubelet            Created container: nginx
  Normal  Started    2m49s  kubelet            Started container nginx

Label Selectors

Label Selectors are queries that allow you to select objects based on their labels. There are two types of label selectors:

Equality-Based Selectors

Equality-based selectors use =, ==, or != operators:

Kubernetesbash
# 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!=production

Set-Based Selectors

Set-based selectors use in, notin, and exists operators:

Kubernetesbash
# 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"

Combining Multiple Selectors

You can combine multiple selectors with commas (AND logic):

Kubernetesbash
# 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=frontend

Practical Example: Creating and Managing Labeled Pods

Let's create a practical example where we create multiple Pods with different labels and then query them:

Step 1: Create Multiple Pods with Labels

Create a file named labeled-pods.yml:

Kuberneteslabeled-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: 5432

Step 2: Apply the Configuration

Kubernetesbash
sudo kubectl apply -f labeled-pods.yml

Step 3: Query Pods by Labels

Now let's query the Pods using different label selectors:

Kubernetesbash
# Get all Pods with app=nginx
sudo kubectl get pod -l app=nginx

Output:

Kubernetesbash
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
Kubernetesbash
# Get all Pods in production environment
sudo kubectl get pod -l environment=production

Output:

Note

If the postgres-prod pod has an error, we can ignore it for now, since this episode focuses on discussing the Label object.

Kubernetesbash
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
Kubernetesbash
# Get all frontend Pods
sudo kubectl get pod -l tier=frontend

Output:

Kubernetesbash
NAME                    READY   STATUS    RESTARTS   AGE
nginx-prod-frontend     1/1     Running   0          2m
nginx-dev-frontend      1/1     Running   0          2m
Kubernetesbash
# Get all Pods with app=nginx AND environment=production
sudo kubectl get pod -l app=nginx,environment=production

Output:

Kubernetesbash
NAME                    READY   STATUS    RESTARTS   AGE
nginx-prod-frontend     1/1     Running   0          2m
nginx-prod-backend      1/1     Running   0          2m

Tip

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

Kubernetesbash
sudo kubectl delete -f labeled-pods.yml

Labels in Kubernetes Objects

Labels are not just used for Pods. You can add Labels to any Kubernetes object. Here are some common use cases:

Labels on Deployments

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.

Kubernetesdeployment-with-labels.yml
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: 80

After successfully creating it, we can check the Pods running using the Deployment with the following command

Kubernetesbash
sudo kubectl get pod -l version=v1

The output will look like this

Kubernetesbash
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          2m12s

Labels on Services

Services use label selectors to find Pods to route traffic to:

Kubernetesservice-with-labels.yml
apiVersion: v1
kind: Service
metadata:
    name: nginx-service
    labels:
        app: nginx
spec:
    selector:
        app: nginx
    ports:
        - protocol: TCP
          port: 80
          targetPort: 80
    type: ClusterIP

Common Mistakes and Pitfalls

Mistake 1: Not Using Consistent Label Names

One 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.

Mistake 2: Using Too Many Labels

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.

Mistake 3: Putting Too Much Information in Label Values

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).

Mistake 4: Forgetting to Update Labels

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.

Best Practices for Using Labels

Kubernetes recommends using a set of standard labels. These are prefixed with app.kubernetes.io/:

Kubernetesrecommended-labels.yml
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: nginx

Use Labels for Resource Management

Use labels to organize resources by team, project, or cost center:

Kuberneteslabels-for-management.yml
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: nginx

Document Your Labeling Strategy

Create documentation for your team about what labels to use and when. This ensures consistency across your cluster.

Use Labels with Node Selectors

You can use labels to schedule Pods on specific nodes:

Kubernetespod-with-node-selector.yml
apiVersion: v1
kind: Pod
metadata:
    name: nginx-pod
    labels:
        app: nginx
spec:
    nodeSelector:
        disk: ssd
        zone: us-east-1a
    containers:
        - name: nginx
          image: nginx

When NOT to Use Labels

While labels are powerful, there are cases where you shouldn't use them:

  • Sensitive information - Never put passwords, API keys, or other sensitive data in labels
  • Large amounts of data - Labels are not designed to store large amounts of data. Use ConfigMaps or Secrets instead
  • Frequently changing data - If data changes frequently, labels might not be the best choice. Consider using annotations instead

Conclusion

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!


Related Posts