cd ..
Kubernetes

Updating a Kubernetes Deployment: How to Apply Changes Safely

Updating a Kubernetes Deployment: How to Apply Changes Safely

Many people believe that updating a Deployment means deleting everything and recreating it. In most cases, this is wrong.

One of the biggest advantages of using a Deployment is precisely the ease with which applications can be updated.

You change the manifest.

Apply it again.

And Kubernetes identifies exactly what has changed.

Without needing to manually remove the Deployment.

In this article, we’ll understand how this process works and which commands are part of it.

How is a Deployment Updated?

Kubernetes works declaratively.

You don’t tell it how to update.

You tell it how you want the Deployment to be.

After that, Kubernetes compares the current state with the submitted manifest.

If there’s any difference, it only performs the necessary changes.

The flow is similar to the following:

deployment.yaml


kubectl apply


Kubernetes compares

Current state
      X
Desired state


Applies only the changes

Changing a Deployment

Imagine a Deployment already exists.

Now we want to add a Namespace.

Simply modify the manifest.

Before:

metadata:
  name: nginx-deployment

After:

metadata:
  name: nginx-deployment
  namespace: giropops

We could also change:

Then just apply it again.

Applying the Changes

After modifying the manifest:

kubectl apply -f deployment.yaml

Explanation:

Expected output:

deployment.apps/nginx-deployment configured

Notice that Kubernetes now reports configured.

This means the Deployment already existed and was merely updated.

The Most Common Error with Namespaces

During your studies, it’s very common to add a Namespace to the manifest.

metadata:
  namespace: giropops

Then execute:

kubectl apply -f deployment.yaml

And receive the error:

Error from server (NotFound):

namespaces "giropops" not found

The reason is simple.

The Namespace does not exist yet.

Creating a Namespace

First, we create the Namespace.

kubectl create namespace giropops

Expected output:

namespace/giropops created

Then we can verify.

kubectl get namespaces

Expected output:

NAME
default
kube-system
giropops

Now the Deployment can be created normally.

Generating a Namespace’s YAML

Just as with Deployments, we can also generate the manifest.

kubectl create namespace giropops \
    --dry-run=client \
    -o yaml

Expected output:

apiVersion: v1
kind: Namespace

metadata:
  name: giropops

Or save directly to a file.

kubectl create namespace giropops \
    --dry-run=client \
    -o yaml > namespace.yaml

Then:

kubectl apply -f namespace.yaml

This approach facilitates versioning in Git.

Querying Resources within the Namespace

Once the Deployment exists within the Namespace, we need to specify this in our commands.

For example.

Instead of:

kubectl get deployments

We use:

kubectl get deployments -n giropops

Or:

kubectl get deploy -n giropops

Explanation:

Expected output:

NAME               READY
nginx-deployment   3/3

Updating the Application Image

One of the most common changes is swapping the image.

Before:

containers:
  - name: nginx
    image: nginx:1.30.4

After:

containers:
  - name: nginx
    image: nginx:1.31.0

After saving the file:

kubectl apply -f deployment.yaml

Kubernetes will automatically detect this change.

In upcoming articles, we’ll see exactly how this update happens internally.

How Does Kubernetes Identify Changes?

Every time we execute:

kubectl apply

Kubernetes compares the received manifest with the existing Deployment.

We can imagine this process in the following way.

Old Manifest


New Manifest


Comparison


Apply only differences

This avoids unnecessary recreations.

It also reduces downtime.

Summary

The complete update flow is as follows.

Edit deployment.yaml


kubectl apply -f deployment.yaml


Kubernetes compares


Updates only what's necessary

It is precisely this characteristic that makes Deployment such a powerful resource.

Conclusion

Updating a Deployment typically means simply altering the manifest and reapplying it.

Kubernetes automatically identifies the differences and performs the necessary modifications.

We also saw how to work with Namespaces and how to query resources within them.

In the next article in this series, we will study the default strategy used by Deployments to update applications: RollingUpdate, understanding how the maxSurge and maxUnavailable parameters work and why they allow applications to be updated with virtually no downtime.

References

What did you think?