k8s.io/perf-tests/clusterloader2@v0.0.0-20240304094227-64bdb12da87e/docs/GETTING_STARTED.md (about) 1 # ClusterLoader2 2 3 In this tutorial, we will: 4 - Set-up perf-tests repository for local development 5 - Create single node cluster using [Kind] 6 - Implement a simple CL2 test and run it 7 - Run load test on 100 nodes cluster 8 9 ## Clone perf-tests repository 10 11 Start with cloning perf-tests repository: 12 ```bash 13 git clone git@github.com:kubernetes/perf-tests.git 14 cd perf-tests 15 ``` 16 17 ## Install GVM 18 Follow instructions on [GVM install]. 19 Install golang with specific version (1.15.12 was tested in this tutorial): 20 ```bash 21 gvm install go1.15.12 22 gvm use go1.15.12 23 ``` 24 Next, add perf-tests repository to GOPATH: 25 26 ```bash 27 gvm linkthis k8s.io/perf-tests 28 ``` 29 30 ## Create cluster using kind 31 Follow the [kind installation][Kind install] guide. 32 33 Create cluster v1.21.1 with one master and one node: 34 ```bash 35 kind create cluster --image=kindest/node:v1.21.1 --name=test-cluster --wait=5m 36 ``` 37 38 This command additionally generates cluster access credentials which are 39 stored in `${HOME}/.kube/config` within a context named test-cluster. 40 41 Check that you can connect to cluster: 42 ```bash 43 kubectl get nodes 44 ``` 45 46 ## Prepare simple test to run 47 Let's prepare our first test config (config.yaml). 48 This test will: 49 - Create one namespace 50 - Create a single deployment with 10 pods inside that namespace 51 - Measure startup latency of these pod 52 53 We will create file `config.yaml` that describes this test. 54 First we need to start with defining test name: 55 ```yaml 56 name: test 57 ``` 58 CL2 will create namespaces automatically, but we need to specify 59 how many namespaces we want: 60 ```yaml 61 namespace: 62 number: 1 63 ``` 64 Next, we need to specify TuningSets. 65 TuningSet describes how actions are executed. 66 In our case, we will have only 1 deployment 67 so there will be only 1 action to execute. 68 In this case tuningSet doesn't really affect transition between states. 69 ```yaml 70 tuningSets: 71 - name: Uniform1qps 72 qpsLoad: 73 qps: 1 74 ``` 75 Test definition consists of a list of steps. 76 A step can be either collection of Phases or Measurements. 77 A Phase defines a state the cluster should reach. 78 A Measurement allows to measure something or wait for something. 79 You can find list of available measurements here [Measurements]. 80 81 Our first step will be starting two measurements. 82 We want to start measuring pod startup latency 83 and also make measurement that will wait for all pods to be in running state. 84 Setting the action field to `start` begins execution of measurement. 85 For both measurements we need to specify labelSelectors 86 so they know which pods they should take into account. 87 PodStartupLatency also takes threshold. If 99th percentile of latency 88 will go over this threshold, test will fail. 89 ```yaml 90 steps: 91 - name: Start measurements 92 measurements: 93 - Identifier: PodStartupLatency 94 Method: PodStartupLatency 95 Params: 96 action: start 97 labelSelector: group = test-pod 98 threshold: 20s 99 - Identifier: WaitForControlledPodsRunning 100 Method: WaitForControlledPodsRunning 101 Params: 102 action: start 103 apiVersion: apps/v1 104 kind: Deployment 105 labelSelector: group = test-deployment 106 operationTimeout: 120s 107 ``` 108 Once we created these two measurements, 109 we can have next step that creates deployment. 110 We need to specify in which namespaces we want this deployment to be created, 111 how many of these deployments per namespace. 112 Also, we will need to specify template for our deployment, 113 which we will do later. 114 For now, let's assume that this template allows us 115 to specify number of replicas in deployment. 116 ```yaml 117 - name: Create deployment 118 phases: 119 - namespaceRange: 120 min: 1 121 max: 1 122 replicasPerNamespace: 1 123 tuningSet: Uniform1qps 124 objectBundle: 125 - basename: test-deployment 126 objectTemplatePath: "deployment.yaml" 127 templateFillMap: 128 Replicas: 10 129 ``` 130 Now, we need to wait for pods in this deployment to be in Running state: 131 ```yaml 132 - name: Wait for pods to be running 133 measurements: 134 - Identifier: WaitForControlledPodsRunning 135 Method: WaitForControlledPodsRunning 136 Params: 137 action: gather 138 ``` 139 Now we can gather results of PodStartupLatency in next step: 140 ```yaml 141 - name: Measure pod startup latency 142 measurements: 143 - Identifier: PodStartupLatency 144 Method: PodStartupLatency 145 Params: 146 action: gather 147 ``` 148 Whole `config.yaml` will look like this: 149 ```yaml 150 name: test 151 152 namespace: 153 number: 1 154 155 tuningSets: 156 - name: Uniform1qps 157 qpsLoad: 158 qps: 1 159 160 steps: 161 - name: Start measurements 162 measurements: 163 - Identifier: PodStartupLatency 164 Method: PodStartupLatency 165 Params: 166 action: start 167 labelSelector: group = test-pod 168 threshold: 20s 169 - Identifier: WaitForControlledPodsRunning 170 Method: WaitForControlledPodsRunning 171 Params: 172 action: start 173 apiVersion: apps/v1 174 kind: Deployment 175 labelSelector: group = test-deployment 176 operationTimeout: 120s 177 - name: Create deployment 178 phases: 179 - namespaceRange: 180 min: 1 181 max: 1 182 replicasPerNamespace: 1 183 tuningSet: Uniform1qps 184 objectBundle: 185 - basename: test-deployment 186 objectTemplatePath: "deployment.yaml" 187 templateFillMap: 188 Replicas: 10 189 - name: Wait for pods to be running 190 measurements: 191 - Identifier: WaitForControlledPodsRunning 192 Method: WaitForControlledPodsRunning 193 Params: 194 action: gather 195 - name: Measure pod startup latency 196 measurements: 197 - Identifier: PodStartupLatency 198 Method: PodStartupLatency 199 Params: 200 action: gather 201 ``` 202 203 By default, clusterloader will delete auto-created namespaces 204 so we don't need to worry with cleaning up cluster. 205 206 Now, in order to finish our first test, we need to specify deployment template. 207 You can think of it as regular kubernetes object, but with templating. 208 CL2 by default adds parameter `Name` that you can use in your template. 209 In our config, we also passed `Replicas` parameter. 210 We need to remember to set correct labels so PodStartupLatency 211 and WaitForControlledPodsRunning will watch correct pods. 212 So our template for deployment will look like this (`deployment.yaml` file): 213 ```yaml 214 apiVersion: apps/v1 215 kind: Deployment 216 metadata: 217 name: {{.Name}} 218 labels: 219 group: test-deployment 220 spec: 221 replicas: {{.Replicas}} 222 selector: 223 matchLabels: 224 group: test-pod 225 template: 226 metadata: 227 labels: 228 group: test-pod 229 spec: 230 containers: 231 - image: registry.k8s.io/pause:3.9 232 name: {{.Name}} 233 ``` 234 ## Execute test 235 Before running test, make sure that kubeconfig 236 current context points to kind cluster: 237 ```bash 238 $ kubectl config current-context 239 > kind-test-cluster 240 ``` 241 To execute test, run: 242 ```bash 243 cd clusterloader2/ 244 go run cmd/clusterloader.go --testconfig=config.yaml --provider=kind --kubeconfig=${HOME}/.kube/config --v=2 245 ``` 246 247 At the end of clusterloader output you should see pod startup latency: 248 ```json 249 { 250 "data": { 251 "Perc50": 7100.534796, 252 "Perc90": 8702.523037, 253 "Perc99": 9122.894555 254 }, 255 "unit": "ms", 256 "labels": { 257 "Metric": "pod_startup" 258 } 259 }, 260 ``` 261 `pod_startup` measures time since pod was created 262 until it was observed via watch as running. 263 264 You should also see that test succeeded: 265 ``` 266 -------------------------------------------------------------------------------- 267 Test Finished 268 Test: ./config.yaml 269 Status: Success 270 -------------------------------------------------------------------------------- 271 ``` 272 As an exercise you can modify threshold for PodStartupLatency 273 below values you've observed in your run and check if test fails. 274 275 ## Delete kind cluster 276 To delete kind cluster, run: 277 ```bash 278 kind delete cluster --name test-cluster 279 ``` 280 281 ## Running 100-node scale test 282 283 Here you can find general purpose [Load test]. 284 This test is release-blocking test we use to evaluate scalability of kubernetes. 285 It consists of 3 main phases: 286 - Creating objects 287 - Scaling objects to size between (50%, 150%) of their original size 288 - Deleting objects 289 290 It can be used to test clusters starting from 100 nodes up to 5k nodes. 291 Load test will create, roughly 30 * nodes pod objects. It will create: 292 - deployments 293 - jobs 294 - statefulsets 295 - services 296 - secrets 297 - configmaps 298 299 There are small (5 pods), medium (30 pods) and big (250 pods) versions of 300 deployments, jobs and statefulsets. 301 302 First, you need to create 100-nodes cluster 303 then you can run cluster scale test with this command: 304 ```bash 305 ./run-e2e-with-prometheus-fw-rule.sh cluster-loader2 --testconfig=./testing/load/config.yaml --nodes=100 --provider=gke --enable-prometheus-server=true --kubeconfig=${HOME}/.kube/config --v=2 306 ``` 307 308 `--enable-prometheus-server=true` deploys prometheus server 309 using prometheus-operator. 310 311 There are various measurements that depend on prometheus metrics, for example: 312 - API responsiveness - measures the latency of requests to kube-apiserver 313 - Scheduling throughput 314 - NodeLocalDNS latency 315 316 [Kind]: https://kind.sigs.k8s.io/ 317 [GVM install]: https://github.com/moovweb/gvm#installing 318 [Kind config]: https://kind.sigs.k8s.io/docs/user/quick-start/#advanced 319 [Kind install]: https://kind.sigs.k8s.io/docs/user/quick-start#installation 320 [Load test]: https://github.com/kubernetes/perf-tests/tree/master/clusterloader2/testing/load 321 [Measurements]: https://github.com/kubernetes/perf-tests/tree/master/clusterloader2#measurement