7. Deployment in kubernetes
In the creating-first-pod section we learnt how we can setup our pod. If you check the pod.yml again, you will see that there is an identifier kind and it is set to kind: pod.
So, what is kind?
- kind: This attribute specifies the exact resource or object we are creating. It can be many different values like Pod, Deployment, Service, ConfigMap, Secret etc.
In this section we will focus on
kind: Deployment.
Introduction
Note: For this exercise we won't be using postgres image anymore as postgres is stateful. Also we will be doing scaling as well and postgres is usually not scaled via deployments
Why do we need deployments?
There are few problems with pods:
- If pod dies, we need to recreate it (for a java application for example if jvm crashes, or OOM, container exits etc.)
- If I need 3 copies of it , I need to create 3 pods
- If I need a new version, I need to delete old pod and create a new one This doesn't scale well in production, that' why we need deployments.
Problems solved by deployment
- Let's say the postgres-service pod that we created earlier, crashes due to some reason.
- Without deployment, nobody recreates it, application will be down and it will require manual intervention.
What happens when you create a deployment
- ReplicaSet Creation: The deployment immediately creates a ReplicaSet. This object is responsible for ensuring the exact number of Pod replicas we provided in pod.yml configs are running at all times.
- Pod Initialization: The replicaSet generates the exact number of pod objects specified in the pod.yml.
- Deployment is responsible for:
- Version Management
- Scaling
- Rollouts
- Rollbacks
- ReplicaSet is responsible for:
- Maintaining desired pod count
Steps to create deployment
1. Delete existing pod:
- We can first delete the pod we created in the creating-first-pod section.
kubectl delete pod postgres-service
- Verify with
kubectl get podsthat no pod exists.
2. Create deployment YAML
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
app: nginx-service
template:
metadata:
labels:
app: nginx-service
spec:
containers:
- name: nginx-service
image: nginx:alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
3. Understanding the yaml:
apiVersion: app/v1
- Pods use v1
- Deployments belong to apps API group
- hence it is apps/v1
kind: Deployment
- Tells k8s to create deployment object
metadata.name
- It is the deployment object identity.
- Later on we can use it for querying.
kubectl get deployment nginx-deployment
spec
- This section specifies the desired state of deployment object.
spec.replicas
- It tells k8s to always keep specified number of pods alive.
spec.selector.matchLabels
- Using the information provided here the deployment knows which pods belong to it.
- When we set
app: nginx-serviceunder matchLabels. We are telling deployment manage all pods with label asapp: nginx-service.
spec.template
- This is like pod blueprint.
- These are the instructions for deployment on how to create pods.
- Deployment does not contain pods, it contains instructions on how to create pods.
spec.template.metadata.labels
This will apply the label app: nginx-service to each pod.
spec.template.spec
- Everything below this is pod definition, which we have already discussed in creating-first-pod.
4. Apply the deployment
- Now in a separate terminal window run the command
kubectl get deployments -w. This will help us to watch the pod life cycle when we create a pod in the next step. - Next apply the above pod.yml using kubectl
kubectl apply -f kubernetes/deployment.yml
- You should see:
![[screen-2026-06-04_22-52-34.png]](/assets/images/screen-2026-06-04_22-52-34-85af70057d52e3074299ee58eb881738.png)
- Now try changing the replicas to 3 and again use apply command.
- You will see that kubernetes immediately reacts and spins up more pods to match desired state of 3.
![[screen-2026-06-04_22-53-57.png]](/assets/images/screen-2026-06-04_22-53-57-5427b39a0dddf0123f18ee343a14d07e.png)
- Run
kubectl get rs. We will see the replicaSet information.
![[screen-2026-06-05_00-04-25.png]](/assets/images/screen-2026-06-05_00-04-25-8875fced9845e36af3571389efecd353.png)
- Naming convention for pods:
deployment-name-{replica-set-hash}-{uniqe-pod-id}
5. Self healing experiment
- Currently we have 3 pods. Now let's delete one pod
kubectl delete pods nginx-deployment-7445c8fb45-5w4p4
- If we watch the pods on another terminal we will see:
![[screen-2026-06-05_00-09-44.png]](/assets/images/screen-2026-06-05_00-09-44-9cce95071e8f05cdb86bb51c78c107ee.png)
- We can see that when we terminated a pod, a new one was immediately created by k8s.
- Sequence of events:
- Pod deleted
- ReplicaSet notices. It's job was to keep 3 pods running at all times. Desired = 3, Actual = 2
- Creates replacement pod.
- Similar to this when we earlier set replicaSet to 3 and applied with kubectl, ReplicaSet sees the difference in desired and actual and scales up.
- Instead of scaling by updating yaml file we can also do:
kubectl scale deployment fraud-service-deployment --replicas=5
5. Rolling Update
- Currently we have ngnix:alpine image deployed in our pods.
- Let's say we want to deploy a different image. In a real world use case it will be like currently v1 of my backend service is running and I have made changes to it, now I want to deploy v2.
- To replicate this scenario, we will use another image nginx:mainline-alpine in our deployment.yml.
- When we apply this updated yml file, we will notice that k8s doesn't delete and create all pods. That would mean downtime.
- Instead it will create a new v2 pod, wait for it to be healthy and then delete one v1 pod. This process will repeat till all the new pods are created with new image.
- This is called rolling update.
![[screen-2026-06-08_23-00-48.png]](/assets/images/screen-2026-06-08_23-00-48-c9819bd6a32be7dab0f2f26922dd8934.png)
- In the above screenshot we had three pods running in the beginning. When we apply the updated deployment.yml notice how k8s first spins up a new pod with id -mgqks and then it terminates one of the existing instances. This process is repeated till the desired state is reached.
6. Deployment revision history
- Each rollout creates a new version. The update we did in the last update will create a version 2.
- We can get the versions using
kubectl rollout history deployment/nginx-deployment
7. Rollback
- Suppose our new version v2 is broken, we can rollback to the previous version.
kubectl rollout undo deployment/nginx-deployment
- If run the command :
kubectl get pods -wwe can see the existing pods terminating and new pods appearing in there place. - You can describe any of the pods in the replica set and see that the image which the new pods have is the old one.