Autoscaling a Kubernetes cluster using Horizontal Pod AutoScaler (HPA)

In the blog I shall be describing the step by step process to setup a Kubernetes cluster using minikube to run a node js based application in Azure cloud and autoscaling the application using Horizontal Pod AutoScaler.

  • Spin up a Standard D4s v3 (4 vcpus, 16 GiB memory) Virtual machine in Azure based on Linux (ubuntu 18.04)
  • Putty into the server and sudo su -. Execute all following commands as root.
sudo apt-get update
sudo apt-get install -y apt-transport-https
sudo apt-get install -y virtualbox virtualbox-ext-pack
  • Install kubectl
curl -s | sudo apt-key add –

sudo touch /etc/apt/sources.list.d/kubernetes.list

echo "deb kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list

sudo apt-get update

sudo apt-get install -y kubectl
  • Install minikube
curl -LO

sudo rpm -ivh minikube-latest.x86_64.rpm

chmod +x minikube && sudo mv minikube /usr/local/bin/

minikube start
  • Run the following commands to ensure proper installation.
kubectl api-versions
kubectl get services
  • Create a new node js application
apt-get install npm

npm init  // this create a new package.json file in the directory
  • Create an index.js file with the following code.
const http = require(‘http’);
const port = process.env.PORT || 3000;
const server = http.createServer((req, res) => {
         res.statusCode = 200;
         res.setHeader(‘Content-Type’, ‘text/plain’);
        res.end(‘Hello World\n’);
});server.listen(port, () => {
 console.log(‘Server running on port: ${port}’);
  • Create a Dockerfile in the same directory with the following content
FROM node:alpine

RUN mkdir -p /usr/src/app

WORKDIR /usr/src/app

ADD index.js ./

ADD package.json ./

RUN npm install

CMD ["npm", "start"]

Sudo apt-get install
docker login

docker build -t rtdhaccount/node-application .

docker push rtdhaccount/node-application
  • Deploy to kubernetes
    • Create a folder called k8s
    • Create deployment.yml inside k8s with the following content
apiVersion: extensions/v1
kind: Deployment
  name: node-application-deployment
  replicas: 1
        app: node-application
      - name: node-application
        image: rtdhaccount/node-application
        imagePullPolicy: Always
        - containerPort: 3000
  • Create service.yml inside k8s with the following content
apiVersion: v1
kind: Service
  name: node-application
    app: node-application
    app: node-application
  - port: 3000
    protocol: TCP
    nodePort: 30001
  type: LoadBalancer
  • Verify the service using the following commands
kubectl apply -f k8s
kubectl get services

kubectl get deployments
kubectl get pods
  • Access Minikube dashboard. To access the minikube dashboard. Open a new putty window and run
sudo kubectl proxy --address='' --disable-filter=true

open a new browser window and enter the url below


where xx.yy.zz.ww is the public ipaddress of your VM.

Ensure that port 8001 is open to inbound traffic in the VM

Incase you get the error :

Unable to start VM: Error getting state for host: machine does not exist

minikube delete
minikube start
  • Accessing the node application.Open a new putty window and setup port forwarding like below
sudo ssh -i ~/.minikube/machines/minikube/id_rsa docker@$(minikube ip) -L \*:30001:

And the access your application from the browser window using the url


Ensure that port 30001 is open to inbound traffic in the VM

Incase of any errors in port forwarding

ssh-keygen -f "/root/.ssh/known_hosts" -R ""
  • Scaling the cluster using Horizontal pod autoscaler. Create a new file hpa.yml under the k8s folder with the following content
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
 name: node-application
 namespace: default
 maxReplicas: 5
 minReplicas: 1
  apiVersion: extensions/v1
  kind: Deployment
  name: node-application
 targetCPUUtilizationPercentage: 1

With targetCPUUtilizationPercentage option, we are saying that, Once the cpu load inside observed CPU more than 1%, scale this pod.

kubectl apply -f k8s/hpa.yml
  • Deploy the metrics-server
kubectl apply -f

kubectl get deployment metrics-server -n kube-system

minikube addons list

minikube addons enable metrics-server

kubectl get hpa
  • Testing using apache benchmark : Install apache benchmark using the below command
apt-get install apache2-utils

ab -c 500 -n 100000 -t 100000 http://xx.yy.zz.ww:30001/
  • Observe the pods scaling up using the commands
kubectl get pods

kubectl get hpa

References :

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: