Learn how to scale an HTTP stub for high-performance load testing using WireMock in Kubernetes. This post covers strategies for horizontal scaling, handling dynamic mappings with StatefulSets, and configuring a load generator for effective non-functional testing.


---
apiVersion: v1
kind: ConfigMap
metadata:
name: wiremock-mappings
data:
static.json: |-
{
"request": {
"method": "GET",
"url": "/static"
},
"response": {
"status": 200,
"jsonBody": {
"data": "static"
},
"headers": {
"Content-Type": "application/json"
}
}
}
volumeMounts:
- name: wiremock-mappings-volume
mountPath: /home/wiremock/mappings
http://wiremock
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wiremock
labels:
app.kubernetes.io/name: wiremock
spec:
replicas: 3
selector:
matchLabels:
app.kubernetes.io/name: wiremock
template:
metadata:
labels:
app.kubernetes.io/name: wiremock
spec:
containers:
- name: wiremock
image: wiremock/wiremock:3.4.2
args:
- "--no-request-journal"
- "--disable-request-logging"
- "--async-response-enabled"
- "true"
volumeMounts:
- name: wiremock-mappings
mountPath: /home/wiremock/mappings
livenessProbe:
httpGet:
port: 8080
path: /static
readinessProbe:
httpGet:
port: 8080
path: /static
ports:
- containerPort: 8080
volumes:
- name: wiremock-mappings
configMap:
name: wiremock-mappings
---
apiVersion: v1
kind: Service
metadata:
name: wiremock
spec:
selector:
app.kubernetes.io/name: wiremock
ports:
- protocol: TCP
port: 80
targetPort: 8080
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: wiremock
labels:
app.kubernetes.io/name: wiremock
spec:
serviceName: wiremocks
replicas: 3
selector:
matchLabels:
app.kubernetes.io/name: wiremock
---
apiVersion: v1
kind: Service
metadata:
name: wiremocks
spec:
clusterIP: None # headless
selector:
app.kubernetes.io/name: wiremock
ports:
- protocol: TCP
port: 8080
targetPort: 8080
+ kubectl get pods -l app.kubernetes.io/name=wiremock
NAME READY STATUS RESTARTS AGE
wiremock-0 1/1 Running 0 2h
wiremock-1 1/1 Running 0 2h
wiremock-2 1/1 Running 0 2h
http://wiremock-{index}.wiremocks:8080
import { check } from "k6";
import http from "k6/http";
export function registerStubMapping(replicas, stubMappingDefinition) {
for (let i = 0; i < replicas; i++) {
const replicaEndpoint = `http://wiremock-${i}.wiremocks:8080`;
callWiremock(replicaEndpoint, stubMappingDefinition);
}
}
function callWiremock(endpoint, stubMappingDefinition) {
const url = `${endpoint}/__admin/mappings`;
const params = {
headers: {
"Content-Type": "application/json",
},
};
const res = http.post(url, JSON.stringify(stubMappingDefinition), params);
check(res, {
"stub mapping created": (r) => r.status === 201,
});
}
import { check } from "k6";
import http from "k6/http";
import { registerStubMapping } from "./wiremock.js";
const wiremockReplicas = 3;
const testData = "testing-data-string";
export const options = {
scenarios: {
loadTest: {
executor: "constant-arrival-rate",
rate: 1000,
timeUnit: "1s",
duration: "3m",
preAllocatedVUs: 200,
},
},
thresholds: {
checks: ["rate>0.99"],
http_reqs: ["rate>999"],
http_req_failed: ["rate<0.01"],
http_req_duration: ["p(99)<500"],
},
};
export function setup() {
registerStubMapping(wiremockReplicas, {
request: {
method: "GET",
url: "/api/test",
},
response: {
status: 200,
jsonBody: {
data: testData,
},
headers: {
"Content-Type": "application/json",
},
},
});
}
export default function () {
const res = http.get("http://reference-service/downstream/api/test");
check(res, {
"status is 200": (r) => r.status === 200,
"response body contains stubbed data": (r) => r.body.includes(testData),
});
}
This article is provided as a general guide for general information purposes only. It does not constitute advice. CECG disclaims liability for actions taken based on the materials.
Discover more insights from our blog collection

The journey from Backstage to Next.js in building CECG's Core Platform dashboard, exploring technology choices, performance optimization, and the challenges of creating a complex platform interface.

Learn about Crossplane's deletion policies and how improper handling can lead to orphaned cloud assets. This guide covers Kubernetes Admission Protection, Crossplane Delete Policies, Usages for Dependency Ordering, and more to help you manage your infrastructure safely.

CECG has been appointed as a Google Cloud Partner, reaffirming our team's expertise in enterprise cloud transformations and GCP products after achieving required certifications and completing Google's onboarding process.