Deployments in Kubernetes
Series of hands-on Kubernetes tutorials to make your app highly-available and scalable.
Photo by ThisisEngineering RAEng on Unsplash
Table of contents
This is the third post in the series of posts related to Kubernetes. If you have not read the previous posts in this series, I highly encourage you to read them. This post is in continuation of the previous post about deploying custom applications on Kubernetes. This post is a hands-on tutorial in which we will see how we can scale-out or scale-in the containerized application, that we built in the previous post, using Kubernetes.
PermalinkScaling your application on Kubernetes
In the previous post, I showed how we can deploy a containerized app on Kubernetes and I also showed how we can ensure in a rudimentary way that the app is running within the container that is managed by Kubernetes. In this post, we will use the same app to scale-out and scale-in horizontally in a few seconds, using Kubernetes deploy
command.
In a real-world scenario, we want our application to be scalable to better utilize computing resources and handle sudden spikes in traffic as well as ensure fault tolerance. To make our service (any workload in general) scalable, Kubernetes can help us achieve that seamlessly. Kubernetes allows us to quickly spin up additional instances (of workload) within a few seconds in case of spikes in traffic - it takes just one command or can even be taken care of automatically when configured. Similarly, we can also bring down the number of running instances quickly with just one command. Let's see how we can do that using Kubernetes.
In Kubernetes, we can define deployment
- it is a logical grouping of similar pods (running the same workload in containers) that can be horizontally scaled-out or scaled-in on-demand. Let's create our deployment to see it in action.
> kubectl create deployment demo-web-app-deployment --image=gauravdhiman05/k8s-demo-web-app --port=80
deployment.apps/demo-web-app-deployment created
>
When we create a deployment using the above command, a single pod will be created on one of the nodes
, running the containerized custom application in it. It is very similar to the pod
that we earlier created manually. The difference is just that this new pod
will be managed and monitored by deployment
. Try exploring the details of deployment
, using the below commands.
# short summary of deployments
> kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
demo-web-app-deployment 1/1 1 1 5m25s
# little more details of deployments
> kubectl get deploy -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
demo-web-app-deployment 1/1 1 1 5m33s k8s-demo-web-app gauravdhiman05/k8s-demo-web-app app=demo-web-app-deployment
# very detailed information about deployment and pods managed within that
> kubectl describe deploy demo-web-app-deployment
Name: demo-web-app-deployment
Namespace: default
CreationTimestamp: Thu, 03 Feb 2022 23:49:44 -0700
Labels: app=demo-web-app-deployment
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=demo-web-app-deployment
Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=demo-web-app-deployment
Containers:
k8s-demo-web-app:
Image: gauravdhiman05/k8s-demo-web-app
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: demo-web-app-deployment-6d64d6ff4b (1/1 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 6m29s deployment-controller Scaled up replica set demo-web-app-deployment-6d64d6ff4b to 1
>
You can also run the below command to see what all pods are running under the default
namespace. This will show pods managed by any deployments or manually created pods
too. For instance, in the below output, demo-web-app
is the name of the pod that we earlier created manually (it is not part of any deployment), whereas demo-web-app-deployment-6d64d6ff4b-hkb5d
is a pod that has been created and managed by a deployment that we created above with name demo-web-app-deployment
.
> kubectl get pods
NAME READY STATUS RESTARTS AGE
demo-web-app 1/1 Running 0 9h
demo-web-app-deployment-6d64d6ff4b-hkb5d 1/1 Running 0 8s
>
Now once the deployment
is done, we can easily scale-out using the below command.
> kubectl scale deployment demo-web-app-deployment --replicas=5
deployment.apps/demo-web-app-deployment scaled
>
The above command immediately increases the number of pod
instances within deployment
from 1 to 5 instances. These pods
could be running on any of the nodes
within the Kubernetes cluster. Kubernetes manages that internally and we do not need to worry about it. Run the below commands to see the effect of the above command. You will realize that now there are 5 pods
whose name starts with common string demo-web-app-deployment
which is the name of the deployment.
# summary of deployments. Now 5 pods are running under deployment
> kubectl get deploy -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
demo-web-app-deployment 4/5 5 4 18m k8s-demo-web-app gauravdhiman05/k8s-demo-web-app app=demo-web-app-deployment
# summary of pods.
> kubectl get pods
NAME READY STATUS RESTARTS AGE
demo-web-app 1/1 Running 0 9h
demo-web-app-deployment-6d64d6ff4b-5kp79 1/1 Running 0 16s
demo-web-app-deployment-6d64d6ff4b-ftzzt 1/1 Running 0 16s
demo-web-app-deployment-6d64d6ff4b-hkb5d 1/1 Running 0 18m
demo-web-app-deployment-6d64d6ff4b-l787g 1/1 Running 0 16s
demo-web-app-deployment-6d64d6ff4b-lk8qw 1/1 Running 0 16s
>
Now let's scale-in and reduce the number of pod instances that are under deployment demo-web-app-deployment
. To scale-in and run only a single pod, run the below command with --replicas
option as 1
.
> kubectl scale deployment demo-web-app-deployment --replicas=1
deployment.apps/demo-web-app-deployment scaled
>
You can now see that there would be only one pod running under that deployment. To see that, again run the command to get deployment and pod details.
# get deployment details
> kubectl get deploy -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
demo-web-app-deployment 1/1 1 1 7m k8s-demo-web-app gauravdhiman05/k8s-demo-web-app app=demo-web-app-deployment
# get all pods details, including pods under deployment or independent pods that are created without deployments
> kubectl get pods
NAME READY STATUS RESTARTS AGE
demo-web-app 1/1 Running 1 9h
demo-web-app-deployment-6d64d6ff4b-l787g 1/1 Running 1 7m
>
That's it for this post. In this quick tutorial, we learned how to scale-out and scale-in the containerized application on Kubernetes. We used kubectl scale deployment
command to scale and deploy multiple pods, but that is not how normal deployments are done on Kubernetes. Normally we define Kubernetes config file (YAML files) to declare what all entities (deployments
, services
, replica sets
and pods
we need in our infrastructure). Declaring things using YAML files is much simpler and does not require us to run multiple Kubernetes commands manually. It also encourages best practices of code-as-infrastructure. In later posts, we will see how to define YAML files that can spin up the required infrastructure in minutes on Kubernetes. For now, we should stick to running kubectl
commands manually to learn more about how Kubernetes perform operations. I hope you enjoyed reading this post in addition to the earlier two posts. Drop your comment and let me know if you have any feedback or thoughts to share.
In the next post, I will introduce the service
construct of Kubernetes and in what scenarios we want to use that.