Load Test a Web App on Kubernetes with K6 + Grafana

What You'll Learn
  • Deploy a demo web app on OVHcloud Kubernetes
  • Write and run a K6 load test as a Kubernetes Job
  • Use Prometheus and Grafana to monitor performance
Prerequisites
  • Kubernetes cluster on OVHcloud (or local)
  • kubectl configured
  • Basic knowledge of Docker and Kubernetes
  • Helm installed
What is K6?

K6 is an open-source load testing tool created by Grafana Labs. It is built for developers, SREs, and DevOps engineers who need a modern, scriptable, and highly scalable performance testing solution.

Key features of K6:

  • JavaScript-based scripting — write tests easily using a familiar language
  • High load generation — implemented in Go for performance
  • Cloud-native — lightweight, easy to containerize, perfect for Kubernetes
  • Metrics-friendly — integrates naturally with Grafana & Prometheus
  • Scenario-based load patterns (ramp-up, spike, soak testing)

K6 makes it simple to validate the reliability, scalability, and responsiveness of your Kubernetes applications under real traffic conditions.

Deploy a Simple Web App

Let’s use a basic Flask app as the target:

# flask-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
    name: flask-app
spec:
    replicas: 1
    selector:
      matchLabels:
        app: flask
    template:
      metadata:
        labels:
          app: flask
      spec:
        containers:
        - name: flask
          image: yourusername/ovhcloud-k8s-demo:latest
          ports:
          - containerPort: 5000
---
apiVersion: v1
kind: Service
metadata:
    name: flask-service
spec:
    selector:
      app: flask
    ports:
    - protocol: TCP
      port: 80
      targetPort: 5000
    type: LoadBalancer
kubectl apply -f flask-deployment.yaml
kubectl get svc flask-service

Copy the external IP once it’s available.

Write the K6 Load Test Script

Create a file named test.js:

import http from 'k6/http';
import { sleep, check } from 'k6';

export const options = {
    stages: [
        { duration: '30s', target: 10 },
        { duration: '1m', target: 50 },
        { duration: '30s', target: 0 },
    ],
};

export default function () {
    const res = http.get('http://flask-service.default.svc.cluster.local');
    check(res, { 'status was 200': (r) => r.status === 200 });
    sleep(1);
}
Run K6 in Kubernetes as a Job

Create a Dockerfile to include the test:

FROM grafana/k6:latest
COPY test.js .
ENTRYPOINT ["k6", "run", "test.js"]

Build and push:

docker build -t yourusername/k6-loadtest .
docker push yourusername/k6-loadtest

Create a Kubernetes Job:

# k6-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
    name: k6-loadtest
spec:
    template:
      spec:
        containers:
        - name: k6
          image: yourusername/k6-loadtest
        restartPolicy: Never
    backoffLimit: 4
kubectl apply -f k6-job.yaml
kubectl logs job/k6-loadtest
Optional: Monitor with Grafana + Prometheus + K6 Operator

Install monitoring stack:

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update

helm install prom prometheus-community/kube-prometheus-stack

Access Grafana:

kubectl port-forward svc/prom-grafana 3000:80
# open http://localhost:3000 (default: admin/prom-operator)