Skip to content

JMeter Docker and Kubernetes

Run JMeter in Docker and Kubernetes: non-GUI CLI, heap limits, volume mounts for reports, qainsights/jmeter image, Jobs, and distributed worker patterns.

Difficulty
advanced
Guide type
how-to
Estimated read time
12 min read
Last verified version
Verified JMeter 5.6

Teams run JMeter in containers for CI, ephemeral injectors, and scaled workers. Apache JMeter itself is a Java application started with documented CLI flags (jmeter -n -t ...); containers wrap that binary, JVM heap, plugins, and filesystem mounts. This guide stays grounded in official CLI, properties, distributed testing, and best practices, plus practical container patterns (including the community image qainsights/jmeter used on this site’s CI examples).

  • Reproducible JMeter + Java + plugin set
  • Easy CI (CI/CD guide)
  • Scale injectors as Jobs/Deployments
  • Isolate heap and CPU with cgroup limits

Containers do not remove the need for correct thread sizing, lean listeners, or honest test data (best practices).

Inside containers there is typically no display. Always:

Terminal window
jmeter -n -t /plans/test.jmx -l /out/results.jtl -e -o /out/report -j /out/jmeter.log
FlagContainer note
-nRequired headless
-tPath inside the container
-l / -e / -oWrite to a mounted volume so the host/CI keeps artifacts
-J / -qInject environment-specific properties
-r / -RDistributed workers (remote testing)

Official lean form also appears in best practices: jmeter -n -t test.jmx -l test.jtl.

Terminal window
docker run --rm \
-v "\${PWD}/tests:/plans" \
-v "\${PWD}/jmeter-out:/out" \
qainsights/jmeter:5.6 \
-n -t /plans/api.jmx \
-Jthreads=20 -Jrampup=40 -Jhost=staging.example.com \
-l /out/results.jtl \
-e -o /out/report \
-j /out/jmeter.log

Ensure /out/report does not already contain a previous dashboard (generator expects a suitable empty/new output dir).

JMeter scripts honor heap-related environment variables (HEAP, JVM_ARGS depending on packaging). Size for threads, response size, and listeners (Heap Estimator). Align container memory limits above -Xmx or the JVM will be OOM-killed by cgroups.

Bake Plugins Manager installs into a derived Dockerfile, or copy lib/ext JARs. Distributed workers need the same plugins (distributed testing).

Run as non-root when your image supports it; ensure mounted volumes are writable for JTL/report/log.

From the CI/CD topic pattern:

- name: Run JMeter
run: |
mkdir -p jmeter-out
docker run --rm \
-v "\${{ github.workspace }}:/work" \
-w /work \
qainsights/jmeter:5.6 \
-n -t tests/load/api.jmx \
-Jthreads=15 -Jhost=\${{ vars.STAGING_HOST }} \
-l jmeter-out/results.jtl \
-e -o jmeter-out/report \
-j jmeter-out/jmeter.log

Archive jmeter-out/ always; gate on dashboard statistics when ready.

apiVersion: batch/v1
kind: Job
metadata:
name: jmeter-smoke
spec:
backoffLimit: 0
template:
spec:
restartPolicy: Never
containers:
- name: jmeter
image: qainsights/jmeter:5.6
args:
- -n
- -t
- /plans/api.jmx
- -Jthreads=10
- -l
- /out/results.jtl
- -e
- -o
- /out/report
resources:
requests:
cpu: "1"
memory: 2Gi
limits:
cpu: "2"
memory: 2Gi
volumeMounts:
- name: plans
mountPath: /plans
- name: out
mountPath: /out
volumes:
- name: plans
configMap:
name: jmeter-plans
- name: out
emptyDir: {}

Copy results out with a sidecar, kubectl cp, or ship to object storage in an exit script. For durable artifacts, use PVC or upload steps.

  • Plans without secrets: ConfigMap or git-synced volume
  • Hosts and client secrets: Kubernetes Secrets → env → -J or templated properties file
  • Prefer \${__P} in the plan (functions)

JMeter is CPU- and memory-sensitive under many threads. Set requests/limits deliberately. Noisy-neighbor shared nodes distort load generation; use dedicated node pools for serious tests.

Pods must reach the system under test. NetworkPolicies, private DNS, and egress rules often break first-time K8s load tests. Smoke with curl from an ephemeral pod before blaming JMeter.

Official remote mode: workers run jmeter-server, controller uses -R (remote testing).

Container caveats:

  1. Same JMeter + Java + plugins on all pods.
  2. RMI/SSL since JMeter 4.0 defaults to SSL; distribute keystores or lab-only disable carefully.
  3. Ports: registry (often 1099), server.rmi.localport, reverse client.rmi.localport range must be allowed between pods.
  4. CSV data files are not auto-copied to workers; mount shared volume or identical images with data.
  5. Headless controller: jmeter -n -t plan.jmx -R worker1,worker2 -l ....

Alternative: N independent Jobs each running full CLI load with split CSV slices, then merge JTLs offline (also mentioned as a multi-instance approach in best practices). Simpler networking than RMI.

If you stream to Influx (Grafana topic), ensure pods can reach Influx/Grafana URLs and that cardinality stays low. Do not point production Influx at unbounded unique sampler labels.

  1. Pin tag and digest for release gates.
  2. Record JMeter version in the report title or CI log.
  3. Include only needed plugins.
  4. Scan for CVEs.
  5. Fail CI if jmeter -v mismatches expected version.
SymptomCauseFix
Report missing on hostForgot volume mountMount /out
Permission deniedNon-writable mountFix ownership/fsGroup
OOMKilledLimit < heap or too many threadsRaise limit or lower threads
Connection refused to SUTK8s networkDNS/NetworkPolicy
Plugin class missingImage without pluginBake JARs
RMI failuresPorts/SSLAlign with remote testing guide

Is there an official Apache JMeter Docker image?

Section titled “Is there an official Apache JMeter Docker image?”

Treat public images as community/vendor unless you verify Apache provenance. Prefer pinned, scanned images your team controls.

What is the essential CLI inside a container?

Section titled “What is the essential CLI inside a container?”

jmeter -n -t plan.jmx -l results.jtl plus -e -o report/ when you need the HTML dashboard artifact.

How do I pass threads and host into a containerized plan?

Section titled “How do I pass threads and host into a containerized plan?”

Use \${__P(threads,10)} in the plan and docker/K8s args -Jthreads=50 -Jhost=....

Possible with X11/VNC images, but load tests should be non-GUI. Use GUI locally for authoring.

Mount a PVC, upload to object storage at job end, or kubectl cp from the pod before it is deleted.

Do distributed workers work on Kubernetes?

Section titled “Do distributed workers work on Kubernetes?”

Yes if RMI ports, SSL keystores, identical software, and data mounts are correct. Many teams prefer multiple independent CLI jobs to avoid RMI complexity.

On this page