cd ..
Kubernetes

Anatomy of a Deployment: understanding selector, template, and ReplicaSet

Anatomy of a Deployment: understanding selector, template, and ReplicaSet

Many people copy a Deployment manifest from the internet, and it just works. But do you really know why each field exists?

In the previous article, we understood what a Deployment is and how it maintains the application in the desired state.

Now is the time to open that manifest and understand how it works internally.

In this article, we will detail the most important fields of the Deployment and understand why they need to be correctly configured.

How Does a Deployment Find Its Pods?

When a Deployment is created, it needs to know exactly which Pods belong to that application.

For this, there is the selector field.

The selector acts as a filter.

It looks for Pods that have a specific Label.

Without this mechanism, the Deployment would not know which Pods it should control.

The Role of Labels

Labels are key-value pairs added to Kubernetes resources.

Example:

labels:
  app: nginx-deployment

In this example, any resource that has the Label:

app=nginx-deployment

can be located by the Deployment.

This is precisely what makes management possible.

Understanding the Selector

Inside the manifest, we find:

selector:
  matchLabels:
    app: nginx-deployment

The meaning is simple.

"Kubernetes,
I want to control all Pods
that have:

app=nginx-deployment"

Whenever a Pod has this Label, it will be considered part of the Deployment.

The Pod Template

Another extremely important field is the template.

It contains the “mold” used to create new Pods.

template:
  metadata:
    labels:
      app: nginx-deployment

  spec:
    containers:
      - name: nginx
        image: nginx:1.30.4

Think of the template as a factory.

Every time a new Pod needs to be created, the ReplicaSet will use this model.

The Relationship Between Selector and Template

These two fields work together.

Deployment

     │ creates

ReplicaSet

     │ uses the template

New Pod

     │ receives Labels

app=nginx-deployment


selector finds the Pod

This is precisely why the template’s Labels must be compatible with the selector.

Otherwise, the Deployment will not be able to locate the Pods it created itself.

Complete Deployment Structure

Now that we know each part, the manifest starts to make much more sense.

apiVersion: apps/v1
kind: Deployment

metadata:
  name: nginx-deployment

spec:
  replicas: 3

  selector:
    matchLabels:
      app: nginx-deployment

  template:
    metadata:
      labels:
        app: nginx-deployment

    spec:
      containers:
        - name: nginx
          image: nginx:1.30.4

Note that the value used in matchLabels is exactly the same as that used within the template.

This match is mandatory.

Adding Resource Limits

The template also defines how containers will be executed.

We can, for example, define Requests and Limits.

containers:
  - name: nginx
    image: nginx:1.30.4

    resources:
      limits:
        cpu: "800m"
        memory: "256Mi"

      requests:
        cpu: "300m"
        memory: "64Mi"

Thus, all Pods created by this Deployment will be born with these configurations.

Applying the Deployment

After creating or modifying the manifest, simply apply it again.

kubectl apply -f deployment.yaml

Expected result:

deployment.apps/nginx-deployment configured

The apply command creates the resource if it does not exist.

If it already exists, it merely applies the necessary changes.

Viewing the Generated Manifest

A very useful way to study Deployments is to visualize how Kubernetes stored that resource.

kubectl get deployment nginx-deployment -o yaml

Explaining the parameters:

Expected result:

apiVersion: apps/v1
kind: Deployment
metadata:
...
spec:
...
status:
...

This output contains various information automatically added by Kubernetes.

It’s an excellent tool for studying.

Listing Only Pods for That Deployment

Since all Pods have the same Label, we can filter them.

kubectl get pods -l app=nginx-deployment

Explaining:

Expected result:

NAME                                  READY
nginx-deployment-xxxx-yyyy1           1/1
nginx-deployment-xxxx-yyyy2           1/1
nginx-deployment-xxxx-yyyy3           1/1

This is a command frequently used in daily operations.

Does Every Deployment Create a ReplicaSet?

Yes.

Whenever we create a Deployment, a ReplicaSet is also automatically created.

We can verify this with:

kubectl get replicasets

Expected result:

NAME                           DESIRED   READY
nginx-deployment-7b7df8dcb7    3         3

Most of the time, you don’t create ReplicaSets manually.

The Deployment itself does this job.

Summary

We can summarize the entire Deployment structure as follows.

Deployment

├── selector
│      │
│      └── finds Pods

├── template
│      │
│      └── defines how they will be created

└── ReplicaSet

           └── maintains the correct number of Pods

Each of these pieces has a different responsibility.

Together, they allow Kubernetes to keep your application running continuously.

Conclusion

Now that we understand the structure of a Deployment, it becomes much easier to comprehend the next features.

We know who creates the Pods.

We know who finds them.

And we know who ensures they continue to exist.

In the next article in the series, we will learn the different ways to create a Deployment using both YAML manifests and the kubectl create deployment command, as well as understand when each approach makes more sense.

References

What did you think?