Sitemap

Deployment & ReplicaSet

7 min readAug 7, 2025

--

Hello everyone! In this document, we’ll cover deployment in our existing Kubernetes environment. We’ll also explore the differences between deployment and replica sets, deployment strategies, and, using rollut commands, how to perform version upgrades, version control checks, and rollbacks.

While the concept of pods may seem sufficient for many Kubernetes newcomers, real-world scenarios require much more. Let’s briefly explain why pods alone aren’t enough.

Pods are:

  • Does not respawn when deleted/closed (unless there is a controller)
  • Can shut down under load, there is no backup
  • Cannot manage the update process (there is no versioning/rollback support)

That’s why ReplicaSet and Deployment come into play.

Differences Between ReplicaSet and Deployment

These two concepts are often confused with each other. While they aren’t entirely independent, they also aren’t the same thing. Let’s highlight the key differences

ReplicaSet ensures that a specified number of identical Pods are running at any given time. For example, if we define 3 replicas, the ReplicaSet will always maintain that count.

Deployment sits one level above ReplicaSet and manages one or more ReplicaSets.

With a Deployment, you can perform critical operations such as:

  • Updating (rolling updates)
  • Rolling back
  • Version control
  • Zero-downtime transitions

In summary: ReplicaSet simply answers “How many?”, whereas Deployment answers “Which version? How to switch? When to roll back?”

After completing the necessary definitions and explanations, we can now create our first Deployment with this command

kubectl create deployment nginx-deployment --image=nginx:1.21 --replicas=3 --dry-run=client -o yaml > nginx-deploy.yaml

Let’s break down the command:

kubectl create deployment → Used to create a new Deployment object.

--image=nginx:1.21 → Specifies the version of the nginx image to use (in this case, 1.21). Using static versions like this gives us full control over operational behavior. Dynamic tags like latest may cause unexpected updates each time we apply a manifest.

--dry-run=client → This flag simulates the command without actually applying it to the cluster. It only outputs the generated manifest without creating real resources.

The resulting YAML file from this command will look like this

apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: nginx-deployment
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx-deployment
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: nginx-deployment
spec:
containers:
- image: nginx:1.21
name: nginx
resources: {}
status: {}

To explain a little bit about our yaml file here

metadata.labels → The label of the Deployment (independent of the Pods). You can assign any value you like here.

metadata.name → The name of the Deployment to be created.

replicas → Specifies how many Pods will be created.

spec.selector.matchLabels → Defines which Pods will be managed by this Deployment. This must match template.metadata.labels.

template → The Pod template specification.

template.metadata.labels → Labels for the Pods that will be created. Must match spec.selector.matchLabels.

containers.image → Specifies the container image to be used.

After editing the deployment’s yaml, we need to use the kubectl apply command to create the deployment.

kubectl apply -f filename.yaml

To view the deployments we created, we need to use the kubectl get deploy command.

kubectl get deploy

NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 5s

With this command, we can see information such as the currently running deployments, how many pods have been created, and how many of these pods are running.

Deployment Strategies

When transitioning an application to a new version in Kubernetes, the strategy you choose is critical. The ideal deployment strategy can depend on many factors, such as:

  • Tolerance for downtime
  • Available system resources
  • How quickly you can recover from failure

There are five main deployment strategies commonly used in Kubernetes. Let’s take a closer look at each:

1️⃣ Rolling Update (Default)

  • This is the default strategy in Kubernetes and is ideal for most use cases.
  • New version Pods are gradually rolled out.
  • Old Pods are terminated progressively.
  • No downtime from the user’s perspective.
  • Everything happens automatically; no extra management required.
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 2
maxUnavailable: 1

maxSurge → How many extra pods can be temporarily opened from the new version?
maxUnavailable → How many old pods can be disabled during the update.

2️⃣ Recreate

  • The simplest but riskiest strategy.
  • All existing Pods are terminated at once.
  • Then, new Pods are created.
  • Downtime is inevitable.
  • It may be used when running two versions of an application simultaneously is not feasible.
strategy:
type: Recreate

3️⃣ Blue/Green Deployment

  • Allows two versions to coexist in the system simultaneously.
  • V1 (blue) and V2 (green) run in parallel.
  • Routing is handled through a service or ingress.
  • Rollback is as simple as redirecting traffic back to the previous version.
  • Ensures zero downtime, but doubles resource usage.
  • It is a resource-intensive strategy and should be carefully planned in production environments.

4️⃣ Canary Deployment

  • Sends a small portion of user traffic to the new version to mitigate risk.
  • For example, in the first step, only 10% of users see the new version.
  • System behavior and errors are observed.
  • If everything is stable, traffic is increased gradually: 10% → 50% → 100%.
  • Rollback is fast, as the previous version is still active.
  • Requires real traffic management, typically implemented at the service or ingress level.

5️⃣ A/B Testing (Parallel Version Comparison)

  • Multiple versions (e.g., A and B) run simultaneously in production.
  • Users are routed to different versions based on factors like IP, cookie, or headers.
  • The goal is to identify which version performs better or is more preferred by users.
  • Routing is usually done using Ingress Controllers like NGINX or Istio.
  • Unlike Canary, traffic isn’t distributed by percentage, but rather by user identity.

Among deployment strategies, A/B and canary strategies can sometimes be confused. The differences can be summarized as follows:

A/B testing attempts to determine which version of an application is most effective by simultaneously releasing it to different user groups. Canary Deployment, on the other hand, aims to test a new version on a small number of users before gradually rolling it out to everyone. So, while Canary tries to answer the question, “Is this version causing problems?”, A/B focuses on the question, “Which one performs best?”

Version update and rollback using rolling update

In this example, we will update the NGINX versions of our pods using the rolling update strategy, which we covered above, and then roll back to the previous version. To perform this operation, we need to add the strategy: block to the YAML file when creating the deployment.

Get Mustafa Bora’s stories in your inbox

Join Medium for free to get updates from this writer.

The strategy: field only defines how the pods will be updated. Therefore, RollingUpdate and Recreate can be directly specified in the YAML. However, in strategies like Blue/Green, Canary, and A/B Testing, the main focus is on how traffic is routed to the updated pods, which is managed not in the YAML but through service or ingress configurations. For this reason, these three strategies are typically applied manually.

This is how it is added to the Rolling update deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: nginx-deployment
name: nginx-deployment
spec:
replicas: 3
# Rolling update
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 2
maxUnavailable: 1
# Rolling update
selector:
matchLabels:
app: nginx-deployment
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: nginx-deployment
spec:
containers:
- image: nginx:1.21
name: nginx
resources: {}
status: {}

We need to run the apply command again to apply the changes we made.

kubectl apply -f filename.yaml

After adding the strategy block, we can start the image version upgrade process.

We update the images of our pods with the set image command.

kubectl set image deployment/nginx-deployment nginx=nginx:1.25 --record

We can check the rollout status with the rollout status command.

kubectl rollout status deployment/nginx-deployment

deployment "nginx-deployment" successfully rolled out

To view past transactions, we use the rollout history command.

kubectl rollout history deployment/nginx-deployment

kubectl set image deployment/nginx-deployment nginx=nginx:1.25 --record=true

In this process, the image information of the pods can also be checked with the kubectl describe podcommand.

kubectl describe pod podadi | grep "Image:"

Image: nginx:1.25

To undo the change, we use the rollout undo command.

kubectl rollout undo deployment/nginx-deployment

In this section, we didn’t just create a Deployment object; we also explored how application updates can be managed in Kubernetes in a controlled, seamless, and reversible manner. We clarified the differences between ReplicaSet and Deployment, brought rollout strategies from theory to practice, and examined various transition scenarios (Rolling Update, Recreate, Blue/Green, Canary, A/B) from both technical and operational perspectives. Finally, by performing version upgrades and rollbacks via kubectl, we reinforced the concept of safe updates.

Thank you for taking the time to read. I hope this document contributes to your journey into Kubernetes. See you in the next module!

Press enter or click to view image in full size

--

--