This repository includes resources in order to benchmark keda core using K6 load tool.
Grafana k6 is an open-source load testing tool that makes performance testing easy and productive for engineering teams. k6 is free, developer-centric, and extensible.
k6 is developed by Grafana Labs and the community.
Keda organization chose k6 as it is a golang based tool even though the scripting is done in javascript. Being built in golang allows our community to contribute to different extensions in order to extend k6 capabilities.
Keda organization chose k6 as well to simulate traffic as part of chaos experiments, trigger them from your k6 tests or inject different types of faults in Kubernetes with xk6-disruptor.
Another reason to choose K6 is the integration with grafana that allows us to have observability during the tests.
- k6
- docker installed
- xk6 extension builder for the following extensions.
- xk6-input-prometheus for acceptance criteria.
- xk6-disruptor to inject delays in the metrics api.
- xk6-kubernetes to interact with kubectl.
kubectl
logged into a Kubernetes cluster.- prometheus as metrics source
- Each load test need additional requirements. For example,
test-scaledobjects.js
requires env variablesPROMETHEUS_URL
,PROMETHEUS_USER
andPROMETHEUS_PASSWORD
- Each scenario might have different configs to simulate the needed workloads.
configs/ contains the configurations to execute K6
shared/ contains functions needed within the loadtest
deps/ dependencies outside the test such as prometheus configuration
ENV.PROMETHEUS_URL
ENV.PROMETHEUS_USER
ENV.PROMETHEUS_PASSWORD
=======
In order to execute the tests we need to build the binary. To do so, check DockerFile where the extensions needed are specified.
e.g.
docker run --rm -it -u "$(id -u):$(id -g)" -v "${PWD}:/xk6" grafana/xk6 build v0.43.1 \
--output k6 \
--with github.com/JorTurFer/xk6-input-prometheus \
--with github.com/grafana/xk6-kubernetes \
--with github.com/grafana/xk6-disruptor
If you want to execute a test you will need to modify the config file to match the test that suits your case.
The parameters to change are inside the config json file in the following section:
"keda": { "scaledobjects": 1, "metricsPerScaledobject": 10 }
./k6 run tests/test-scaledobject.js --env INJECT_FAULTS=1 --config configs/scaledobjects/1so10m.json
You can run tests from the workflows enable in github in the following url.
Adding different scenarios as needed is enabled via PR.
Add a new scenario following k6 documentation in json format
"keda": {
"scaledobjects": int,
"metricsPerScaledobject": int
}
Where scaledobjects is the number of objects to scale and metricsPerScaledobject is the number of metrics that will be considered in order to scale.
Scenario without Fault Injects:
{
"scenarios": {
"load": {
"tags": { "scenario": "default" },
"executor": "constant-vus",
"vus": 1,
"exec": "default",
"duration": "5m"
}
},
"ext": {
"loadimpact": {
"projectID": xxxxxxx,
"name": "x-ScaleObjects-y-Metrics"
},
"keda": {
"scaledobjects": x,
"metricsPerScaledobject": y
}
},
"thresholds": {
"keda_internal_latency": ["p(95) < 7", "p(99) < 15", "max < 20"]
}
}
Scenario with Fault Injects:
{
"scenarios": {
"load": {
"tags": { "scenario": "default" },
"executor": "constant-vus",
"vus": 1,
"exec": "default",
"duration": "9m"
},
"disrupt": {
"tags": { "scenario": "chaos" },
"executor": "shared-iterations",
"iterations": 1,
"vus": 1,
"exec": "disrupt",
"startTime": "1m"
}
},
"ext": {
"loadimpact": {
"projectID": xxxxxxx,
"name": "x-ScaleObjects-y-Metrics"
},
"keda": {
"scaledobjects": x,
"metricsPerScaledobject": y
}
},
"thresholds": {
"keda_internal_latency": ["p(90)<1", "p(95) < 7", "p(99) < 15", "max < 20"]
}
}
For Tests including disrupt we have to notice that the threshold should consider the disrupt phase as a percentage of the total execution time of the test. E.g.
total execution time: 10m
total disruption time: 1m
then the percentile that should be considered without any disruption would be p90 ( 1 min out of 10 min)
TODO