How To Autoscale Your Workloads on DigitalOcean Kubernetes

Kubernetes

YOUR COSMETIC CARE STARTS HERE

Find the Best Cosmetic Hospitals

Trusted • Curated • Easy

Looking for the right place for a cosmetic procedure? Explore top cosmetic hospitals in one place and choose with confidence.

“Small steps lead to big changes — today is a perfect day to begin.”

Explore Cosmetic Hospitals Compare hospitals, services & options quickly.

✓ Shortlist providers • ✓ Review options • ✓ Take the next step with confidence

Originally based on a tutorial from digitalocean.com.

When working with a Kubernetes-based application, you will occasionally need to schedule additional pods to handle peak traffic or bursts of compute load. By default, scaling is a manual operation: a developer changes the replica count in the Deployment object, then reduces it again when load subsides. That manual dependency can become a liability. Traffic can spike at 3 AM, or a sudden viral event can overwhelm a cluster before anyone has a chance to respond.

The solution is the Horizontal Pod Autoscaler (HPA). The HPA reads resource-usage data from the Metrics Server and automatically adjusts the number of running pods to keep per-pod utilization within a target threshold. Combined with DigitalOcean Kubernetes (DOKS), a managed Kubernetes service, HPA lets you build infrastructure that adapts to load without human intervention.

When autoscaling is a good fit: HPA works best for stateless workloads that can run as multiple parallel instances — web servers, API gateways, and microservices are ideal examples. Stateful workloads such as databases are a poor fit: you would need to handle race conditions, data integrity, synchronization, and dynamic cluster-membership changes. This tutorial does not cover database autoscaling.

In this tutorial you will:

  • Deploy a sample Nginx workload on DOKS.
  • Set CPU resource limits and requests on the Deployment.
  • Install Metrics Server with Helm and work around a DOKS-specific DNS issue.
  • Create an HPA and validate that it scales the Deployment automatically under artificial CPU load.

Prerequisites

Before you begin, ensure you have:

  • A running DigitalOcean Kubernetes cluster with kubectl configured to connect to it. Follow the Connect to your Cluster instructions shown after cluster creation, or see the DigitalOcean Kubernetes Quickstart.
  • The Helm package manager installed locally and Tiller initialized on the cluster. Complete Steps 1 and 2 of the How To Install Software on Kubernetes Clusters with the Helm Package Manager tutorial on DigitalOcean.

Step 1 — Creating a Test Deployment

To demonstrate HPA, you need a workload to autoscale. This tutorial uses the official Nginx image because it is stateless, widely deployed in Kubernetes environments (for example, as the Nginx Ingress Controller), and trivially lightweight to spin up. Skip this step if you already have a Deployment you want to scale.

Create the Deployment:

kubectl create deployment web --image=nginx:latest

The --image=nginx:latest flag pulls the latest Nginx image from Docker Hub. After a few seconds, verify that the pod is running:

kubectl get podsCode language: JavaScript (javascript)

Expected output:

NAME                   READY   STATUS    RESTARTS   AGE
web-84d7787df5-btf9h   1/1     Running   0          11s

Notice that only one pod is running. Once autoscaling triggers, additional pods will spin up automatically.

Step 2 — Setting CPU Limits and Requests on Your Deployment

The HPA cannot make meaningful scaling decisions without knowing how much CPU a pod is allowed to use. Kubernetes uses two related concepts:

  • Requests — the amount of CPU (or memory) that Kubernetes reserves on a node for the pod when scheduling. A node is only considered for scheduling if it has at least this much resource available.
  • Limits — the maximum amount of CPU (or memory) the container is allowed to consume. The HPA uses this value as the 100% baseline when computing utilization percentage.

For example, if you set a CPU limit of 100m (millicores) and the pod is currently using 80m, the HPA sees the pod at 80% utilization. Without a limit, the HPA has no frame of reference.

Open the Deployment for editing:

kubectl edit deployment web

This command opens the live API object in your default editor (controlled by the KUBE_EDITOR or EDITOR environment variable, defaulting to vi on Linux or notepad on Windows).

Locate the resources: {} line under the nginx container spec and replace it with the following block:

    spec:
      containers:
      - image: nginx:latest
        imagePullPolicy: Always
        name: nginx
        resources:
          limits:
            cpu: 300m
          requests:
            cpu: 100m
            memory: 250MiCode language: CSS (css)

These values are for demonstration purposes. In production, monitor your workload during both low and peak traffic periods to determine appropriate values, and adjust them over time as your traffic patterns change.

Save and close the file. If there is a YAML syntax error, kubectl will reopen the file and display the error so you can correct it.

Step 3 — Installing Metrics Server

The HPA pulls utilization data from the Kubernetes Metrics Server, a cluster add-on that scrapes resource usage from the kubelet on each node. Without it, the HPA has no data source and cannot function.

Install Metrics Server via Helm:

helm install stable/metrics-server --name metrics-server

Wait for the pod to initialize, then test it:

kubectl top pod

On DOKS, you will likely see this error immediately after installation:

Error: Metrics not available for pod
Error from server (ServiceUnavailable): the server is currently unable to handle the request (get pods.metrics.k8s.io)Code language: JavaScript (javascript)

Why this happens: DOKS nodes do not register DNS records for their own hostnames. By default, Metrics Server contacts kubelets using node hostnames, which fail to resolve in DOKS. The fix is to instruct Metrics Server to use node internal IP addresses instead.

Edit the Metrics Server Deployment:

kubectl edit deployment metrics-server

Find the command section for the metrics-server container and add two flags as shown below:

      containers:
      - command:
        - /metrics-server
        - --cert-dir=/tmp
        - --logtostderr
        - --secure-port=8443
        - --metric-resolution=60s
        - --kubelet-preferred-address-types=InternalIP
  • --kubelet-preferred-address-types=InternalIP — instructs Metrics Server to contact nodes by internal IP, bypassing the unresolvable hostname problem on DOKS.
  • --metric-resolution=60s — sets the scrape interval to 60 seconds. Reduce this to 10s or 20s if you need more granular data for faster scaling decisions.

Save and close the editor. After a minute or two, verify that Metrics Server is collecting data:

kubectl top pod

You should now see resource usage for each pod:

NAME                             CPU(cores)   MEMORY(bytes)
metrics-server-db745fcd5-v8gv6   3m           12Mi
web-555db5bf6b-f7btr             0m           2Mi

Metrics Server is now operational and feeding data into the cluster’s resource API. You are ready to configure the HPA.

Step 4 — Creating and Validating the Horizontal Pod Autoscaler

Create the HPA for the web Deployment:

kubectl autoscale deployment web --max=4 --cpu-percent=80

Flag breakdown:

  • --max=4 — the HPA will never schedule more than 4 replicas of the web Deployment.
  • --cpu-percent=80 — if the average CPU utilization across all pods exceeds 80% of the limit defined in Step 2, the HPA adds more pods. With a limit of 300m, the trigger point is approximately 240m average across all running pods.

You can inspect the HPA object at any time:

kubectl get hpa webCode language: JavaScript (javascript)

Validating Autoscaling Under Artificial Load

Open a second terminal and run the following watch command to refresh pod metrics every two seconds:

watch "kubectl top pods"Code language: JavaScript (javascript)

You should see a single web pod consuming minimal CPU:

Every 2.0s: kubectl top pods

NAME                              CPU(cores)   MEMORY(bytes)
metrics-server-6fd5457684-7kqtz   3m           15Mi
web-7476bb659d-q5bjv              0m           2MiCode language: CSS (css)

Switch to your first terminal and open a shell inside the running web pod (replace the pod name with the one from your cluster):

kubectl exec -it web-f765fd676-s9729 /bin/bash

From inside the pod, install the stress tool and run it to generate CPU load:

# Debian/Ubuntu-based images:
apt update && apt-get install -y stress
stress -c 3Code language: PHP (php)
# CentOS/RHEL-based images:
yum install -y stress
stress -c 3Code language: PHP (php)

Leave stress running and switch back to your second terminal. After approximately two minutes — enough time for Metrics Server to collect data at the configured 60-second interval and for the HPA’s sync loop to react — you will see additional web pods appear:

Every 2.0s: kubectl top pods

NAME                             CPU(cores)   MEMORY(bytes)
metrics-server-db745fcd5-v8gv6   6m           16Mi
web-555db5bf6b-ck98q             0m           2Mi
web-555db5bf6b-f7btr             494m         21Mi
web-555db5bf6b-h5cbx             0m           1Mi
web-555db5bf6b-pvh9f             0m           2MiCode language: CSS (css)

The HPA detected that the single web pod had exceeded the 80% CPU threshold and automatically scheduled additional replicas (up to the maximum of 4). When you stop the stress command with CTRL+C and exit the pod shell, the HPA will scale the Deployment back down after the load subsides and the cool-down period elapses.

Conclusion

In this tutorial you:

  • Created an Nginx Deployment on DigitalOcean Kubernetes.
  • Defined CPU resource requests and limits to give the HPA a utilization baseline.
  • Installed and configured Metrics Server via Helm, including the DOKS-specific --kubelet-preferred-address-types=InternalIP workaround.
  • Created a Horizontal Pod Autoscaler and confirmed that it automatically scales the Deployment in response to CPU load.

From here, consider:

  • Tuning thresholds — monitor actual workload metrics to set realistic CPU targets and replica limits.
  • Memory-based autoscaling — HPA also supports custom and external metrics beyond CPU.
  • Cluster Autoscaler — if all nodes are full, new pods will remain in a Pending state. The DigitalOcean Cluster Autoscaler can add worker nodes automatically to accommodate additional pods.
  • Helm v3 — the tutorial uses Helm v2 syntax (helm install stable/metrics-server --name metrics-server). Helm v3 dropped Tiller and changed the install syntax to helm install metrics-server stable/metrics-server.

Refer to the official Kubernetes HPA documentation for the full list of configuration options and supported metric sources.

0 0 votes
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
0
Would love your thoughts, please comment.x