DevOpsToolBox
K8s-HPA-Testing
Info

Kubernetes HPA Testing with Minikube and K6

This documentation outlines the process of testing Kubernetes Horizontal Pod Autoscalers (HPA) in a Minikube environment. We'll use stress simulations and the K6 load testing tool to evaluate the scaling behavior of a PHP application.


Prerequisites

  1. Minikube installed and running.
  2. kubectl CLI tool configured for Minikube.
  3. K6 installed for load testing.
  4. Basic knowledge of Kubernetes deployments, services, and HPA.

Setup Steps

1. Deployment Configuration

Create a Kubernetes deployment for the stress-testing PHP application:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: stress-php-deployment
  labels:
    app: stress-php
spec:
  replicas: 2
  selector:
    matchLabels:
      app: stress-php
  template:
    metadata:
      labels:
        app: stress-php
    spec:
      containers:
      - name: stress-php-container
        image: noscopev6/web-stress-php:v0.2
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: "100m"
            memory: "200Mi"
          limits:
            cpu: "200m"
            memory: "400Mi"
        livenessProbe:
          httpGet:
            path: /index.php
            port: 80
          initialDelaySeconds: 10
          periodSeconds: 20
          timeoutSeconds: 5
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /index.php
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 3
        startupProbe:
          httpGet:
            path: /index.php
            port: 80
          initialDelaySeconds: 20
          periodSeconds: 30
          timeoutSeconds: 5
          failureThreshold: 5

Apply the deployment:

kubectl apply -f deployment.yaml

2. Service Configuration

Expose the application using a NodePort service:

apiVersion: v1
kind: Service
metadata:
  name: stress-php-service
spec:
  selector:
    app: stress-php
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30000  # Minikube NodePort range is 30000-32767
  type: NodePort
  # - protocol: TCP
  #   port: 80
  #   targetPort: 80
  # type: ClusterIP

Apply the service:

kubectl apply -f service.yaml

3. Horizontal Pod Autoscaler

Configure an HPA to scale pods based on CPU and memory utilization:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: stress-php-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: stress-php-deployment
  minReplicas: 2
  maxReplicas: 50
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50  # Target 50% CPU usage
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 50  # Target 70% Memory usage

Apply the HPA:

kubectl apply -f hpa.yaml

Stress Testing the Application

0. Health Check URL

Use the following PHP script to simulate HealthCheck tasks:

<?php
echo "PHP + NGINX is working!";
 

1. CPU Stress Test

Use the following PHP script to simulate CPU-intensive tasks:

<?php
// cpu_stress.php
ini_set('max_execution_time', 0); // Disable time limit for stress test
 
echo "Starting CPU stress test...\n";
 
// Simulate CPU-intensive task by running a loop that performs complex calculations
for ($i = 0; $i < 10000000; $i++) {
    $x = sqrt($i * rand(1, 100));
}
 
echo "CPU stress test completed.";
?>
 

Place this script in your application directory and access it via the service NodePort.

2. Memory Stress Test

Use the following PHP script to simulate memory-intensive tasks:

<?php
session_start();
 
ini_set('max_execution_time', 0);  // Disable time limit for stress test
ini_set('memory_limit', '-1');     // Set memory limit to unlimited
 
// Check if session variable 'memory' exists, if not, initialize it
if (!isset($_SESSION['memory'])) {
    $_SESSION['memory'] = 0;
}
 
echo "Starting memory stress test...\n";
 
// Simulate memory-intensive task by creating large arrays
$memoryHog = [];
 
// Increase memory usage each time the page is hit
$memoryIncrement = 1024 * 1024;  // 1MB per hit
$memoryTarget = $_SESSION['memory'] + $memoryIncrement;
 
while ($_SESSION['memory'] < $memoryTarget) {
    // Add large arrays to memory
    $memoryHog[] = str_repeat('A', 1024 * 1024); // Add 1MB strings
    $_SESSION['memory'] += $memoryIncrement;  // Track total memory used
    echo "Allocated " . $_SESSION['memory'] / (1024 * 1024) . "MB of memory...\n";
    flush();  // Flush the output to the browser immediately
    sleep(1);  // Sleep to prevent a complete hang
}
 
echo "Memory stress test completed.";
$_SESSION['memory'] = 0;  // Reset memory after completion
?>

3. Load Testing with K6

Use K6 to simulate traffic and trigger the HPA:

Example K6 Script for CPU scaling and memory:

CPU scaling

import http from 'k6/http';
import { sleep } from 'k6';
 
export default function () {
  // Replace with a simple endpoint in your Laravel app
  http.get('http://192.168.49.2:30000/cpu_stress.php');
  sleep(1); // Pause for 1 second before the next request
}
 

Memory scaling

import http from 'k6/http';
import { sleep } from 'k6';
 
export default function () {
  // Replace with a simple endpoint in your Laravel app
  http.get('http://192.168.49.2:30000/memory_stress.php');
  sleep(1); // Pause for 1 second before the next request
}

Replace <NodeIP> with the Minikube IP address:

minikube ip

Run the K6 test:

k6 run --vus 100 --duration 300s cpu-k6.js # vus is total no of virtual users
k6 run --vus 100 --duration 300s memory-k6.js # vus is total no of virtual users

Observing HPA Behavior

  1. Monitor the pods:

    kubectl get pods -w
  2. Check the HPA status:

    kubectl get hpa
  3. Check the metrics status:

     kubectl top pod
     kubectl get deploy 
     kubectl top node

You should see the HPA scaling pods up and down based on the simulated traffic and resource utilization.


This testing demonstrates how Kubernetes HPA can dynamically scale your application to handle fluctuating workloads efficiently. Using Minikube and K6 provides a lightweight and effective environment for experimenting with these features.


🧙 AI Wizard - Instant Page Insights

Click the button below to analyze this page.
Get an AI-generated summary and key insights in seconds.
Powered by Perplexity AI!