1. Overview
Container orchestration technologies such as Kubernetes have been widely adopted. One of the primary reasons for its popularity is it allows us to deploy and manage containerized applications at scale.
It’s very common to see that applications get overloaded during peak hours. One of the easiest ways to handle such scenarios is to deploy the additional instances of the applications. The good news is that we can do it very quickly and effortlessly in Kubernetes.
In this tutorial, we’ll discuss various techniques for scaling pods in Kubernetes. So, let’s get started.
2. Setting up an Example
It’s good practice to follow a resource isolation strategy while deploying the application. In Kubernetes, we can achieve it using the namespaces.
In this section, we’ll discuss how to create a new namespace and deploy a few pods to it.
2.1. Creating a New Kubernetes Namespace
First, let’s use the create command to create a new namespace:
$ kubectl create ns scaling-demo
namespace/scaling-demo created
Here, we can see that the command creates a new namespace with the name scaling-demo.
In the next sections, we’ll create a declarative YAML configuration to deploy NGINX and Redis pods in this namespace.
2.2. Creating Kubernetes Deployment Objects
To begin, let’s save the following declarative configuration as nginx.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: scaling-demo
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:alpine-slim
name: nginx
ports:
- containerPort: 80
name: nginx
Similarly, we can save the following configuration in a redis.yaml file:
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: scaling-demo
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- image: redis:alpine
name: redis
ports:
- containerPort: 6379
name: redis
2.3. Creating Kubernetes Pods
Next, let’s use the apply command to create the NGINX and Redis pods in the scaling-demo namespace:
$ kubectl apply -f nginx.yaml
deployment.apps/nginx configured
$ kubectl apply -f redis.yaml
deployment.apps/redis configured
Finally, let’s check that all pods are in a healthy state:
$ kubectl get pods --show-labels -n scaling-demo
NAME READY STATUS RESTARTS AGE LABELS
nginx-59c556767c-ncl9k 1/1 Running 0 45s app=nginx,pod-template-hash=59c556767c
redis-78497c75bd-9jxdw 1/1 Running 0 36s app=redis,pod-template-hash=78497c75bd
In this example, we’ve used the –show-labels option with the get command to display the labels of the pod.
Now, the required setup is in place. So let’s use it to understand the scaling in Kubernetes.
3. Scaling Pods Using the Declarative Method
In this section, we’ll discuss the two declarative methods to scale up/down the Kubernetes pods. As the name suggests, this method needs a declarative configuration. In our case, we’ve defined it in the YAML files while setting up the example.
3.1. Using the apply Command
In the YAML file, we’ve set the value of spec.replicas to 1. This property controls the number of pods to be created. One of the easiest and most preferred methods for scaling is to update this value.
So, let’s edit the nginx.yaml file and set the value of the spec.replicas to 2. When we’ve saved it:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: scaling-demo
spec:
replicas: 2 # We've updated this value
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:alpine-slim
name: nginx
ports:
- containerPort: 80
name: nginx
Now, let’s use the apply command to deploy the updated configuration:
$ kubectl apply -f nginx.yaml
deployment.apps/nginx configured
Here, we can observe that the command successfully applies the updated configuration.
Now, let’s confirm that there are two pods of the NGNIX:
$ kubectl get pods --selector=app=nginx -n scaling-demo
NAME READY STATUS RESTARTS AGE
nginx-59c556767c-ncl9k 1/1 Running 0 85s
nginx-59c556767c-nd6rb 1/1 Running 0 7s
In this example, we’ve used the app=nginx label with the get command to filter only NGINX pods.
It’s important to note that, ideally, one should use this method only because we can version control the latest configuration and avoid configuration drifts.
3.2. Using the scale Command
In addition to this, we can also use the scale command to scale pods. The sole purpose of this command is to set a new size for a deployment, replica set, replication controller, or stateful set.
We’ve to use the –replicas option with this command to specify the new size. This option is mandatory as we aren’t updating the value of the spec.replicas property from the YAML file*.*
In the previous example, we scaled up the NGINX pods. Now, let’s scale them down by specifying the –replicas=1 option to the command:
$ kubectl scale --replicas=1 -f nginx.yaml
deployment.apps/nginx scaled
Here, the output shows that the scaling operation was completed successfully.
Now let’s check the status of NGINX pods:
$ kubectl get pods --selector=app=nginx -n scaling-demo
NAME READY STATUS RESTARTS AGE
nginx-59c556767c-ncl9k 1/1 Running 0 108s
In the output, we can see that the scale command has removed the additional Pod.
4. Scaling Pods Using the Imperative Method
In the previous section, we saw how to scale pods using the declarative method. However, sometimes we want to perform scaling operations without declarative configuration. In such cases, we can use the deployment name with the scale command. In our case, the deployment names are nginx and redis.
4.1. Scaling up the Pod
Let’s use the –replicas=2 option to set the replica count of the NGINX deployment to 2:
$ kubectl scale --replicas=2 deployment/nginx -n scaling-demo
deployment.apps/nginx scaled
Now, let’s verify that there are two NGINX pods:
$ kubectl get pods --selector=app=nginx -n scaling-demo
NAME READY STATUS RESTARTS AGE
nginx-59c556767c-5vznb 1/1 Running 0 10s
nginx-59c556767c-ncl9k 1/1 Running 0 2m11s
Here, we can see that scale operation creates the new NGINX pod.
4.2. Scaling Down the Pod
Similarly, we can use the scale command to scale down the pod. To achieve this, we need to use the smaller value with the –replicas option than the current replica count.
So, let’s use the –replicas=1 option to scale down the NGINX pod to one:
$ kubectl scale --replicas=1 deployment/nginx -n scaling-demo
deployment.apps/nginx scaled
Next, let’s verify that the additional NGINX pod is getting removed:
$ kubectl get pods --selector=app=nginx -n scaling-demo
NAME READY STATUS RESTARTS AGE
nginx-59c556767c-5vznb 1/1 Terminating 0 10s
nginx-59c556767c-ncl9k 1/1 Running 0 2m11s
Here, we can see that the status of one of the Pods is Terminating.
4.3. Scaling Pod Based on the Condition
In addition to this, the scale command allows us to perform scaling based on the conditions. This helps us in avoiding the unintentional overwrites of previous scaling changes.
To understand this, let’s specify the scaling condition using the –current-replicas option:
$ kubectl scale --current-replicas=1 --replicas=2 deployment/nginx -n scaling-demo
deployment.apps/nginx scaled
The above condition sets the replica count of NGINX deployment to 2 only if the current replica count is 1.
Now, let’s check the status of the NGINX pods:
$ kubectl get pods --selector=app=nginx -n scaling-demo
NAME READY STATUS RESTARTS AGE
nginx-59c556767c-ncl9k 1/1 Running 0 3m6s
nginx-59c556767c-xx5bb 1/1 Running 0 9s
It’s important to note that the scaling operation succeeds only if the specified condition evaluates to the boolean true.
To understand this, let’s execute the same scale command once again:
$ kubectl scale --current-replicas=1 --replicas=2 deployment/nginx -n scaling-demo
error: Expected replicas to be 1, was 2
Here, we can see that the command fails while performing the scaling operation.
4.4. Scaling Multiple Pods
So far, we scaled only a single pod. However, the scale command allows us to scale multiple pods as well. To achieve this, we just need to specify the multiple deployment object on the command line.
So, let’s scale up the NGINX and Redis pods using the single command:
$ kubectl scale --replicas=3 deployment/nginx deployment/redis -n scaling-demo
deployment.apps/nginx scaled
deployment.apps/redis scaled
In the output, we can see that the two deployments have been scaled. To verify that, let’s list the pods from the scaling-demo namespace:
$ kubectl get pods -n scaling-demo
NAME READY STATUS RESTARTS AGE
nginx-59c556767c-ncl9k 1/1 Running 0 16m
nginx-59c556767c-vn96s 1/1 Running 0 11s
nginx-59c556767c-xx5bb 1/1 Running 0 13m
redis-78497c75bd-6gs96 1/1 Running 0 11s
redis-78497c75bd-9jxdw 1/1 Running 0 16m
redis-78497c75bd-l25mf 1/1 Running 0 11s
4.5. Scaling All Pods
In the previous example, we scaled up two deployments using their names. However, that isn’t the most efficient method if we want to perform the scale operation on a large number of objects.
In such cases, we can use the –all option to perform the scale operation on all objects:
$ kubectl scale --replicas=1 --all deployment -n scaling-demo
deployment.apps/nginx scaled
deployment.apps/redis scaled
It’s important to note that we’ve to specify the resource type after the –all option. The supported resource types are deployment, rs, rc, or statefulset.
Now, let’s verify that both NGINX and Redis pods have been scaled down:
$ kubectl get pods -n scaling-demo
NAME READY STATUS RESTARTS AGE
nginx-59c556767c-ncl9k 1/1 Running 0 17m
redis-78497c75bd-9jxdw 1/1 Running 0 17m
5. Cleaning Up
Kubernetes objects consume various system resources, such as CPU, memory, storage, network, etc. So it’s a good practice to remove them if they aren’t needed anymore. Removing the incorrect Kubernetes object can cause potential issues. Hence, we’ve to be extra careful before deleting them.
So, let’s use the delete command to remove the Deployment and Namespace objects:
$ kubectl delete deployment/nginx deployment/redis -n scaling-demo
deployment.apps "nginx" deleted
deployment.apps "redis" deleted
$ kubectl delete namespace scaling-demo
namespace "scaling-demo" deleted
6. Conclusion
In this article, we saw how to scale up/down the Kubernetes pods.
First, we discussed how to use the apply and scale commands with the declarative configuration.
Next, we saw the usage of the scale command using the imperative method. Then we discussed how to perform the scaling based on the condition.
Finally, we discussed scaling multiple pods at once using a single command.