Real World App — Kubernetes Deployment and ReplicaSet
We have moved from containers to kubernetes because we want entreprise or production level features like load balancing, auto healing and others which by only deploying pod itself is not possible. In real world, we actually deploy our (stateless) apps using Kubernetes Deployment which is an abstraction layer that underneath rolls out ReplicaSet and also manages Pods. ReplicaSet ensures one of the most important features of k8s — Auto Healing.
What is Kubernetes Deployment?
A K8s Deployment manages a set of Pods to run an application workload — usually stateless apps. The nginx app we deployed previously using Pod Deployment fits here. You mention your desired state of application in a Deployment and it rolls out or uses ReplicaSet to provide you the actual state of Pods.
If there is anything in Kubernetes that is responsibe to convert desired state into actual state then it is generally a Controller.
ReplicaSet is also a Kubernetes Controller which ensures ‘N’ number of Pods replicas are running at any given time which you specified in Deployment configuration.
A Glance At Previous Pod Deployment
To understand what Kubernetes Deployment does, we need to understand the problem it solves. Back to our Pod deployment file:
apiVersion: v1
kind: Pod
metadata:
name: webserver
spec:
containers:
- name: web1
image: nginx:latest
ports:
- containerPort: 80In one terminal watch the pods (-w):
kubectl get pods -wNow in another terminal, apply and delete the pod:
kubectl apply -f pod.yaml
kubectl delete pod webserverSee what’s happening on watched terminal:
NAME READY STATUS RESTARTS AGE
webserver 0/1 ContainerCreating 0 4s
webserver 1/1 Running 0 4s
webserver 1/1 Terminating 0 22s
webserver 1/1 Terminating 0 22s
webserver 0/1 Completed 0 22sYou see the STATUS transition:
flowchart LR
ContainerCreating --> Running --> Terminating --> Completed
The problem is No one is ensuring Auto Healing — Users can’t access application if by any chances a Pod is deleted or have some problems. But with K8s Deployment which rolls out RepliaSet, it always ensures ‘N’ number of specified Pods be running no matter what.
Deploy With Kubernetes Deployment
Let’s convert the Pod to actual Kubernetes Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: webserver-deployment
labels:
app: webserver
spec:
replicas: 1
selector:
matchLabels:
app: webserver
template:
metadata:
labels:
app: webserver
spec:
containers:
- name: wwb1
image: nginx:latest
ports:
- containerPort: 80The second line kind: Deployment here is telling K8s — “Please create Deployment for me!”
Make sure your Kubernetes cluster is up & running. When you apply this deployment:
kubectl apply -f deployment.yamldeployment.apps/webserver-deployment createdFollowing things happen:
A Deployment named
webserver-deploymentis created (.metadata.name) which will be the base for the ReplicaSets and Pods created later.The Deployment creates a ReplicaSet with
1desired replicas (.spec.replicas).ReplicaSet uses
.spec.selectorfield to find which Pods to manage. In this case a labelwebserveris selected which is defined in the Pod template (app: webserver).The Container is crated as defined in
.spec.templatenamelyweb1usingnginx:latestimage..spec.templatealso definesapp: webserveras label which was matched by ReplicaSet as explained in the prior point.
Verify Kubernetes Deployment
One thing worth flagging again from earlier:
When you create Kubernetes Deployment, it rolls out ReplicaSet which in turn ensures ‘N’ number of Pods replicas (
1here) is up and running at any given time.
This means when you applied Deployment (kubectl apply -f deployment.yaml) previously, not only the Deployment is created but also ReplicaSet is created which in trun cerates 1 Pod replica. This can be verified:
Verify Deployment
kubectl get deploymentNAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
webserver-deployment 1/1 1 1 70s wwb1 nginx:latest app=webserverVerify ReplicaSet
kubectl get replicasetNAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
webserver-deployment-5f75747fb9 1 1 1 2m2s wwb1 nginx:latest app=webserver,pod-template-hash=5f75747fb9Verify Pods
kubectl get podsNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
webserver-deployment-5f75747fb9-qp6rc 1/1 Running 0 2m45s 10.244.0.16 minikube <none> <none>With all the verifications above, it is proved that: Instead of us manually managing Containers, Pods, ReplicaSets and Deployment differently — Kubernetes does this all in one using Deployment abstraction. Basically, K8s is saying:
Hey! I have created a Deployment abstraction so that you just specify you want a Deployment and I will handle the rest. You go sleep (well No!).
Also if you have noticed, webserver-deployment is the base name defined as .metadata.name: webserver-deployment above for all the resources created as discussed.
Verify App is Running
You get the Ip Address from here which is 10.244.0.16. Go inside the Minikube cluster first:
minikube sshAnd then http request to 10.244.0.16:
curl 10.244.0.16The answer:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
</head>
<body>
<h1>Welcome to nginx!</h1>
...
<p><em>Thank you for using nginx.</em></p>
</body>
</html>The Ultimate Test: Is ReplicaSet Doing It’s Job?
The ReplicaSet is here to ensure one thing that is: One Pod must be running no matter what as specified by .spec.replicas: 1 in the configuration.
Let’s watch before deleting in one terminal:
kubectl get pods -wAnd delete from another terminal:
kubectl delete pod webserver-deployment-5f75747fb9-qp6rcSee the watched states:
NAME READY STATUS RESTARTS AGE
webserver-deployment-5f75747fb9-qp6rc 1/1 Running 0 11m
webserver-deployment-5f75747fb9-qp6rc 1/1 Terminating 0 12m
webserver-deployment-5f75747fb9-9jzdt 0/1 Pending 0 0s
webserver-deployment-5f75747fb9-qp6rc 1/1 Terminating 0 12m
webserver-deployment-5f75747fb9-9jzdt 0/1 Pending 0 0s
webserver-deployment-5f75747fb9-9jzdt 0/1 ContainerCreating 0 0s
webserver-deployment-5f75747fb9-qp6rc 0/1 Completed 0 12m
webserver-deployment-5f75747fb9-qp6rc 0/1 Completed 0 12m
webserver-deployment-5f75747fb9-qp6rc 0/1 Completed 0 12m
webserver-deployment-5f75747fb9-qp6rc 0/1 Completed 0 12m
webserver-deployment-5f75747fb9-9jzdt 1/1 Running 0 3sCompleted is the defination of container deletion. Even before the container is killed, a new container is being spinned up as denoted by ContainerCreating.
What If ReplicaSet Itself Is Deleted?
ReplicaSet ensures Auto Healing but what if it is deleted? Watch ReplicaSets (rs):
kubectl get rs -wDelete the Replicaset:
kubectl delete replicaset webserver-deployment-5f75747fb9replicaset.apps "webserver-deployment-5f75747fb9" deleted from default namespaceSee the watched states:
NAME DESIRED CURRENT READY AGE
webserver-deployment-5f75747fb9 1 1 1 16m
webserver-deployment-5f75747fb9 1 1 1 16m
webserver-deployment-5f75747fb9 1 0 0 0s
webserver-deployment-5f75747fb9 1 0 0 0s
webserver-deployment-5f75747fb9 1 1 0 0s
webserver-deployment-5f75747fb9 1 1 1 3sAs soon as ReplicaSet is deleted, Deployment sees CURRENT state (0) is not matched as DESIRED state (1) so ReplicaSet is rolled out again.
You Can Go Nasty
Yep, you can go nasty by deleting the Deployment itself.
First, wait for deletion of webserver-deployment in the default namespace:
kubectl wait --for=delete deployment/webserver-deployment -n defaultYour terminal will block till webserver-deployment is deleted.
Now, delete the Deployment in another terminal:
kubectl delete deployment webserver-deploymentdeployment.apps "webserver-deployment" deleted from default namespaceThe wait is over and the waiting terminal says:
deployment.apps/webserver-deployment condition metIf you now see your Deployment (deploy short form):
kubectl get deployYou see nothing. So here is the mindmap:
- ReplicaSet was watching Pods — Pods get recreated.
- Deployment was watching ReplicaSet — ReplicaSet gets recreated.
- Nobody was watching the Deployment itself — it’s gone forever.
Do It Yourself
Increase the number of replicas, see deletion happening live, play around — Get comfortable with Kubernetes Deployment and Kubernetes too BECAUSE KUBERNETES IS EASY.
Here is the hint:
spec.replicas: NmeansNnumber of Pods will be deployed notNReplicaSets.- When you delete ReplicaSet, all
NPods will be deleted. - When ReplicaSet is recreted by Deployment, all
Npods will also be recreated. - When Deployment itself is deleted, you know what’s going to happen, don’t you?
Don’t left it undone. Even with the hint provided, see everything by your eyes. Don’t trust anything what you haven’t seen and especially when you have the power to see. SHOW YOUR POWER in the comment section.