Auto-Scale Kubernetes Pods Based on Resource Metrics

In Kubernetes, pod auto-scaling can be achieved using the Horizontal Pod Autoscaler (HPA), which scales pods dynamically based on CPU, memory, or custom metrics. This guide creates a bash script that automates the setup and management of HPA for auto-scaling pods, explains the process in detail, and provides examples and scenarios for implementation.


Overview of the Script

The script will:

  1. Check prerequisites (ensure kubectl and the Kubernetes Metrics Server are installed).
  2. Set up HPA for a deployment.
  3. Monitor scaling events dynamically.
  4. Provide options for customization like setting thresholds for CPU or memory utilization.
  5. Handle alerts or logs when scaling events occur.

Prerequisites

  1. Install Kubernetes CLI (kubectl): Ensure kubectl is installed and configured:
    kubectl version --client
    
  2. Install Metrics Server: The Metrics Server must be installed to collect CPU and memory usage data. Verify it with:
    kubectl top nodes
    
  3. Deployment Ready: A Kubernetes deployment must be available for scaling.

Script: Auto-Scale Pods Based on Resource Metrics

Below is the complete bash script, including detailed steps, explanations, and examples.

#!/bin/bash

# Auto-Scale Kubernetes Pods Based on Resource Metrics
# Author: [Your Name]
# Date: [Date]
# Version: 1.0

# Icons for status
CHECK="\u2714" # ✔
CROSS="\u274C" # ✘
INFO="\u2139"  # ℹ

# Function: Check if kubectl is installed
function check_kubectl() {
    if ! command -v kubectl &> /dev/null; then
        echo -e "${CROSS} Error: kubectl is not installed. Please install kubectl and configure access to the cluster."
        exit 1
    else
        echo -e "${CHECK} kubectl is installed."
    fi
}

# Function: Check Metrics Server installation
function check_metrics_server() {
    if ! kubectl get deployment metrics-server -n kube-system &> /dev/null; then
        echo -e "${CROSS} Error: Metrics Server is not installed. Please install Metrics Server to enable resource metrics."
        exit 1
    else
        echo -e "${CHECK} Metrics Server is installed and running."
    fi
}

# Function: Create HPA
function create_hpa() {
    local deployment=$1
    local cpu_target=$2
    local min_pods=$3
    local max_pods=$4

    echo -e "${INFO} Creating HPA for deployment: $deployment"
    kubectl autoscale deployment "$deployment" \
        --cpu-percent="$cpu_target" \
        --min="$min_pods" \
        --max="$max_pods"

    if [[ $? -eq 0 ]]; then
        echo -e "${CHECK} HPA created successfully for deployment: $deployment"
    else
        echo -e "${CROSS} Failed to create HPA for deployment: $deployment"
        exit 1
    fi
}

# Function: Monitor HPA
function monitor_hpa() {
    local deployment=$1

    echo -e "${INFO} Monitoring HPA for deployment: $deployment"
    watch -n 10 kubectl get hpa "$deployment"
}

# Function: Clean up HPA
function delete_hpa() {
    local deployment=$1

    echo -e "${INFO} Deleting HPA for deployment: $deployment"
    kubectl delete hpa "$deployment"

    if [[ $? -eq 0 ]]; then
        echo -e "${CHECK} HPA deleted successfully for deployment: $deployment"
    else
        echo -e "${CROSS} Failed to delete HPA for deployment: $deployment"
        exit 1
    fi
}

# Main script starts here
echo "=== Kubernetes Pod Auto-Scaler Script ==="

# Step 1: Check prerequisites
check_kubectl
check_metrics_server

# Step 2: Get user input for deployment
read -p "Enter the name of the deployment to scale: " deployment
if [[ -z $deployment ]]; then
    echo -e "${CROSS} Error: Deployment name cannot be empty."
    exit 1
fi

read -p "Enter the target CPU utilization (e.g., 50 for 50%): " cpu_target
cpu_target=${cpu_target:-50} # Default to 50%

read -p "Enter the minimum number of pods: " min_pods
min_pods=${min_pods:-1} # Default to 1

read -p "Enter the maximum number of pods: " max_pods
max_pods=${max_pods:-10} # Default to 10

# Step 3: Create HPA
create_hpa "$deployment" "$cpu_target" "$min_pods" "$max_pods"

# Step 4: Monitor HPA
read -p "Do you want to monitor the HPA? (yes/no): " monitor
if [[ $monitor == "yes" ]]; then
    monitor_hpa "$deployment"
fi

# Step 5: Clean up HPA
read -p "Do you want to delete the HPA? (yes/no): " cleanup
if [[ $cleanup == "yes" ]]; then
    delete_hpa "$deployment"
fi

echo -e "${CHECK} Script execution completed."

Step-by-Step Explanation

1. Check Prerequisites

The script verifies that:

  1. kubectl is installed:
    if ! command -v kubectl &> /dev/null; then
    

    If not found, it exits with an error.

  2. The Metrics Server is installed:
    kubectl get deployment metrics-server -n kube-system
    

    Without the Metrics Server, HPA cannot collect CPU or memory usage data.


2. Create HPA

The create_hpa function uses kubectl autoscale to create an HPA for the specified deployment:

kubectl autoscale deployment "$deployment" \
    --cpu-percent="$cpu_target" \
    --min="$min_pods" \
    --max="$max_pods"
  • --cpu-percent: Specifies the target CPU utilization percentage.
  • --min and --max: Define the minimum and maximum number of pods.

For example:

kubectl autoscale deployment nginx-deployment --cpu-percent=70 --min=2 --max=5

This will scale the nginx-deployment pods between 2 and 5 based on CPU usage.


3. Monitor HPA

The monitor_hpa function displays the HPA status dynamically using:

watch -n 10 kubectl get hpa "$deployment"

The watch command refreshes the HPA status every 10 seconds, allowing you to observe scaling events in real time.


4. Delete HPA

If the user opts to clean up, the script deletes the HPA with:

kubectl delete hpa "$deployment"

This ensures the cluster remains clean after testing.


Examples

Deployment YAML Example

Here’s a sample deployment for testing the script:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        resources:
          requests:
            cpu: "250m"
          limits:
            cpu: "500m"

Apply this deployment with:

kubectl apply -f deployment.yaml

Script Execution Example

  1. Run the Script:
    ./auto_scale_pods.sh
    
  2. Provide Inputs:
    Enter the name of the deployment to scale: nginx-deployment
    Enter the target CPU utilization (e.g., 50 for 50%): 70
    Enter the minimum number of pods: 2
    Enter the maximum number of pods: 5
    
  3. Output Example:
    === Kubernetes Pod Auto-Scaler Script ===
    ✔ kubectl is installed.
    ✔ Metrics Server is installed and running.
    ℹ Creating HPA for deployment: nginx-deployment
    ✔ HPA created successfully for deployment: nginx-deployment
    ℹ Monitoring HPA for deployment: nginx-deployment
    NAME                   REFERENCE                     TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
    nginx-deployment       Deployment/nginx-deployment  60%/70%   2         5         3          2m
    
  4. Clean Up:
    Do you want to delete the HPA? (yes/no): yes
    

Technical Details

  1. HPA Algorithm:
    • Scale Out: Adds pods if CPU/memory usage exceeds the target.
    • Scale In: Reduces pods if usage falls below the target.
  2. Metrics Server: Collects real-time resource metrics.
  3. Custom Metrics: The script can be extended to support custom metrics by integrating Kubernetes API or Prometheus.

Benefits of Auto-Scaling

  1. Cost Efficiency: Pods scale only when necessary.
  2. High Availability: Handles sudden traffic spikes.
  3. Resource Optimization: Ensures balanced resource usage.

This script is a comprehensive solution for implementing auto-scaling in Kubernetes clusters. Let me know if you’d like further enhancements or customization for specific scenarios!

Implementing Auto-Scaling of Pods Based on Resource Metrics in Google Cloud Platform (GCP)

In GCP, Kubernetes clusters are managed via Google Kubernetes Engine (GKE). GKE supports auto-scaling out of the box with the Horizontal Pod Autoscaler (HPA), which adjusts the number of pods in a deployment based on CPU, memory, or custom metrics.

Here’s how to implement pod auto-scaling in GCP, including the setup process and configurations:


Step-by-Step Implementation in GCP

1. Set Up GKE Cluster

  1. Create a GKE Cluster:
    • Go to the Google Cloud Console.
    • Navigate to Kubernetes Engine > Clusters.
    • Click Create Cluster and follow the instructions to create a GKE cluster.
  2. Enable Metrics Server: GKE comes with a built-in Metrics Server for monitoring CPU and memory utilization. Verify it’s installed:
    kubectl top nodes
    

    If this command works, the Metrics Server is operational.


2. Deploy an Application

  1. Deploy a sample NGINX application:
    kubectl create deployment nginx-deployment --image=nginx
    
  2. Expose the deployment as a service:
    kubectl expose deployment nginx-deployment --type=LoadBalancer --port=80
    
  3. Verify the deployment:
    kubectl get deployments
    

3. Configure Resource Limits

To use HPA, define resource requests and limits for your pods in the deployment manifest. Update the deployment using the following YAML:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        resources:
          requests:
            cpu: "250m"
          limits:
            cpu: "500m"

Apply the updated deployment:

kubectl apply -f nginx-deployment.yaml

4. Enable Horizontal Pod Autoscaler (HPA)

  1. Create an HPA to scale pods based on CPU usage:
    kubectl autoscale deployment nginx-deployment \
        --cpu-percent=50 \
        --min=1 \
        --max=5
    
    • --cpu-percent=50: Scale when CPU usage exceeds 50%.
    • --min=1: Minimum 1 pod.
    • --max=5: Maximum 5 pods.
  2. Verify the HPA:
    kubectl get hpa
    

    Example output:

    NAME               REFERENCE                     TARGETS         MINPODS   MAXPODS   REPLICAS   AGE
    nginx-deployment   Deployment/nginx-deployment   <unknown>/50%   1         5         1          10s
    

5. Generate Load to Test Auto-Scaling

To trigger scaling, generate traffic to the NGINX deployment. Use the kubectl run command or a load-testing tool like Apache Bench:

  1. Use a busybox pod to generate CPU load:
    kubectl run -i --tty load-generator --image=busybox --restart=Never -- /bin/sh
    
  2. Inside the busybox pod, run the following loop to send traffic:
    while true; do wget -q -O- http://nginx-deployment; done
    
  3. Observe the HPA:
    kubectl get hpa -w
    

    You should see the number of replicas increase as CPU usage exceeds the target.


6. Monitor Scaling Events

To monitor scaling events, use:

kubectl describe hpa nginx-deployment

This will show details about scaling events, metrics collected, and decisions made by the HPA.


7. Cleanup Resources

To clean up the resources:

  1. Delete the HPA:
    kubectl delete hpa nginx-deployment
    
  2. Delete the deployment and service:
    kubectl delete deployment nginx-deployment
    kubectl delete service nginx-deployment
    

Advanced Scenarios

1. Auto-Scale Based on Memory

If you want to scale based on memory instead of CPU, modify the HPA to target memory usage. Add memory requests and limits to the deployment YAML:

resources:
  requests:
    memory: "128Mi"
  limits:
    memory: "256Mi"

Create an HPA targeting memory usage:

kubectl autoscale deployment nginx-deployment \
    --metric memory.targetAverageUtilization=70 \
    --min=1 \
    --max=5

2. Auto-Scale Based on Custom Metrics

For custom metrics (e.g., HTTP request rate):

  1. Install Prometheus Adapter to expose custom metrics.
  2. Define custom metrics in Prometheus (e.g., requests_per_second).
  3. Create an HPA targeting the custom metric:
    kubectl autoscale deployment nginx-deployment \
        --metric requests_per_second.targetAverageValue=100 \
        --min=1 \
        --max=10
    

3. Combine HPA with Cluster Autoscaler

  • HPA scales pods, but the Cluster Autoscaler ensures there are enough nodes to handle the pods.
  • Enable the Cluster Autoscaler in GKE:
    gcloud container clusters update [CLUSTER_NAME] \
        --enable-autoscaling --min-nodes=1 --max-nodes=10 --zone=[ZONE]
    

Bash Script for Automating HPA Setup

Below is a bash script to automate the process of enabling HPA for a deployment in GCP:

#!/bin/bash

# GCP Kubernetes Pod Auto-Scaler Script
# Author: [Your Name]
# Date: [Date]
# Version: 1.0

# Icons for status
CHECK="\u2714" # ✔
CROSS="\u274C" # ✘
INFO="\u2139"  # ℹ

# Function: Check prerequisites
function check_prerequisites() {
    if ! command -v kubectl &> /dev/null; then
        echo -e "${CROSS} Error: kubectl is not installed. Please install kubectl."
        exit 1
    fi

    echo -e "${CHECK} kubectl is installed."

    if ! kubectl top nodes &> /dev/null; then
        echo -e "${CROSS} Error: Metrics Server is not installed in your cluster."
        exit 1
    fi

    echo -e "${CHECK} Metrics Server is installed."
}

# Function: Create HPA
function create_hpa() {
    local deployment=$1
    local cpu_target=$2
    local min_pods=$3
    local max_pods=$4

    echo -e "${INFO} Creating HPA for deployment: $deployment"
    kubectl autoscale deployment "$deployment" \
        --cpu-percent="$cpu_target" \
        --min="$min_pods" \
        --max="$max_pods"

    if [[ $? -eq 0 ]]; then
        echo -e "${CHECK} HPA created successfully for deployment: $deployment"
    else
        echo -e "${CROSS} Failed to create HPA."
        exit 1
    fi
}

# Function: Monitor HPA
function monitor_hpa() {
    local deployment=$1
    echo -e "${INFO} Monitoring HPA for deployment: $deployment"
    kubectl get hpa "$deployment" -w
}

# Main script
echo "=== GCP Kubernetes Pod Auto-Scaler ==="

check_prerequisites

read -p "Enter deployment name: " deployment
read -p "Target CPU utilization (default: 50): " cpu_target
cpu_target=${cpu_target:-50}
read -p "Minimum pods (default: 1): " min_pods
min_pods=${min_pods:-1}
read -p "Maximum pods (default: 5): " max_pods
max_pods=${max_pods:-5}

create_hpa "$deployment" "$cpu_target" "$min_pods" "$max_pods"
monitor_hpa "$deployment"

Conclusion

By leveraging GCP’s GKE and Kubernetes’ Horizontal Pod Autoscaler (HPA):

  1. Applications can dynamically adapt to changing resource demands.
  2. Resource utilization becomes efficient, reducing costs.
  3. The integration of HPA and Cluster Autoscaler ensures scalability even during high traffic.

This solution is extensible for complex scenarios such as multi-metric scaling or scaling across multiple regions. Let me know if you need further details or customizations!

Related articles

Kubernetes Cluster With Minikube

Kubernetes Cluster With Minikube Creating a Kubernetes cluster on cloud platforms like AWS, Google Cloud, or Azure can be...

Top Amazon Web Services (AWS) Trends Dominating 2026 in the US & UK

Top Amazon Web Services (AWS) Trends Dominating 2026 in the US & UK As we step into 2026, Amazon...

Create New Branch in Git and Push Code​

Create New Branch in Git and Push Code​. Introduction Branching is one of the most powerful features of Git, allowing...

Git Status

Git Status Git is one of the most widely used version control systems for managing source code in software...