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:
- number of replicas;
- container image;
- resources;
- labels;
- strategy.
Then just apply it again.
Applying the Changes
After modifying the manifest:
kubectl apply -f deployment.yaml
Explanation:
apply→ creates or updates resources.-f→ uses a YAML file.
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:
-n→ abbreviation for--namespace.giropops→ Queried Namespace.
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.