A Ansible tool to deploy a distributed Locust load test on any Kubernetes cluster.
git clone https://github.com/sinae99/locust-k8s-loadtest
cd locust-k8s-loadtest
# edit vars.yml
ansible-playbook deploy.yml
Your Laptop
│
└─► ansible-playbook deploy.yml
│
▼
Kubernetes Cluster
┌─────────────────────────────────────────┐
│ namespace: locust │
│ │
│ ┌──────────────┐ 5557 ┌──────────┐ │
│ │ locust-master│◄────────│ worker-0 │ │
│ │ (1 pod) │◄────────│ worker-1 │ │
│ │ │ ... │ worker-N │ │
│ └──────┬───────┘ └──────────┘ │
│ │ :30089 (NodePort) │
└─────────┼───────────────────────────────┘
│
▼
Locust Web UI
http://NODE_IP:30089
The master pod runs the test automatically (--autostart). Workers connect to the master and hammer the target in parallel. The web UI shows real-time RPS, latency, and failures.
| Tool | Minimum version |
|---|---|
ansible |
2.12+ |
kubectl |
configured with cluster access |
1. Clone and configure
git clone https://github.com/YOUR_USERNAME/locust-k8s-loadtest
cd locust-k8s-loadtestOpen vars.yml and set your target:
target_host: "https://api.myservice.com"
target_path: "/v1/endpoint"
http_method: "POST"
request_body:
username: "testuser"
token: "abc123"
users: 200
spawn_rate: 20
run_time: "10m"
worker_replicas: 52. Deploy
ansible-playbook deploy.yml
# or: make deployAnsible will:
- Template all Kubernetes manifests into
generated/ - Apply them to your cluster
- Wait for pods to become ready
- Print the Locust UI URL
3. Watch the results
Open the printed URL in your browser:
http://your_ip:30089
4. Tear down when done
ansible-playbook teardown.yml
# or: make teardownAll options live in vars.yml.
| Variable | Default | Description |
|---|---|---|
target_host |
https://api.example.com |
Base URL of the service under test |
target_path |
/api/endpoint |
API path to hit |
http_method |
POST |
GET or POST |
| Variable | Default | Description |
|---|---|---|
request_body |
{key: value} |
YAML dict, serialized to JSON automatically |
body_json_url |
"" |
URL to download the body JSON from at startup. Overrides request_body when set. |
| Variable | Default | Description |
|---|---|---|
users |
100 |
Total number of concurrent virtual users |
spawn_rate |
10 |
New users added per second during ramp-up |
run_time |
5m |
Test duration (30s, 5m, 1h, etc.) |
| Variable | Default | Description |
|---|---|---|
k8s_namespace |
locust |
Kubernetes namespace to deploy into |
nodeport |
30089 |
NodePort for the Locust web UI |
kubeconfig |
"" |
Absolute path to kubeconfig. Leave empty to use KUBECONFIG env var or ~/.kube/config |
worker_replicas |
5 |
Number of worker pods (scale up for higher RPS) |
| Variable | Default |
|---|---|
locust_image |
locustio/locust:latest |
master_cpu_request / master_cpu_limit |
500m / 1 |
master_memory_request / master_memory_limit |
512Mi / 1Gi |
worker_cpu_request / worker_cpu_limit |
250m / 500m |
worker_memory_request / worker_memory_limit |
128Mi / 256Mi |
target_host: "https://api.example.com"
target_path: "/health"
http_method: "GET"
users: 500
spawn_rate: 50
run_time: "2m"
worker_replicas: 3target_host: "https://api.example.com"
target_path: "/v1/login"
http_method: "POST"
request_body:
email: "loadtest@example.com"
password: "test123"
users: 200
spawn_rate: 20
run_time: "10m"
worker_replicas: 5Useful when the body is large or generated externally:
target_host: "https://api.example.com"
target_path: "/v1/process"
http_method: "POST"
body_json_url: "https://my-bucket.s3.amazonaws.com/loadtest-body.json"
users: 300
worker_replicas: 10The Locust UI is available at http://NODE_IP:NODEPORT after deploy.
To find the node IP manually:
kubectl get nodes -o wideThe deploy playbook prints the URL automatically at the end.
Since --autostart is set, the test begins immediately. Open the UI to watch live metrics, download CSV reports, or stop the test early.
locust-k8s-loadtest/
├── vars.yml ← Edit this
├── deploy.yml ← Main playbook
├── teardown.yml ← Cleanup playbook
├── Makefile ← make deploy / make teardown
├── ansible.cfg
├── templates/
│ ├── locustfile.py.j2 ← Locust script template
│ ├── namespace.yaml.j2
│ ├── configmap.yaml.j2
│ ├── master-deployment.yaml.j2
│ ├── master-svc.yaml.j2
│ └── worker-deployment.yaml.j2
├── generated/ ← Rendered manifests (git-ignored)
└── k8s/ ← Original raw manifests (reference)
MIT