Skip to content

Commit

Permalink
Put stress on a zeebe node (#242)
Browse files Browse the repository at this point in the history
Allow to put different kind of stress on a zeebe node (broker or
gateway).

Stress types are CPU, IO and memory. The broker can be identified via
nodeId or partitionId and role. For the gateway we choose the first one
in the list as on all other commands.

Should replace
https://github.com/zeebe-io/zeebe-chaos/blob/main/chaos-workers/chaos-experiments/scripts/stress-cpu.sh

close #238 

-------

Example:

**Stress Broker:**
```sh
$ ./zbchaos stress broker --cpu --memory --verbose
Connecting to zell-chaos
Running experiment in self-managed environment.
Successfully created port forwarding tunnel
Found Broker zell-chaos-zeebe-0 as LEADER for partition 1.
Put stress on zell-chaos-zeebe-0
Execute ["apt" "-qq" "update"] on pod zell-chaos-zeebe-0
7 packages can be upgraded. Run 'apt list --upgradable' to see them.
Execute ["apt" "-qq" "install" "-y" "stress" "procps"] on pod zell-chaos-zeebe-0
procps is already the newest version (2:3.3.16-1ubuntu2.3).
The following NEW packages will be installed:
  stress
0 upgraded, 1 newly installed, 0 to remove and 7 not upgraded.
Need to get 18.4 kB of archives.
After this operation, 55.3 kB of additional disk space will be used.
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package stress.
(Reading database ... 7621 files and directories currently installed.)
Preparing to unpack .../stress_1.0.4-6_amd64.deb ...
Unpacking stress (1.0.4-6) ...
Setting up stress (1.0.4-6) ...
Execute ["stress" "--timeout" "30" "--cpu" "256" "--vm" "4"] on pod zell-chaos-zeebe-0
stress: info: [405] dispatching hogs: 256 cpu, 0 io, 4 vm, 0 hdd
stress: info: [405] successful run completed in 30s

```


**Stress Gateway:**

```sh
$ ./zbchaos stress gateway --cpu --verbose
Connecting to zell-chaos
Running experiment in self-managed environment.
Successfully created port forwarding tunnel
Put stress on zell-chaos-zeebe-gateway-58dc88cb5b-jz4lg
Execute ["apt" "-qq" "update"] on pod zell-chaos-zeebe-gateway-58dc88cb5b-jz4lg
7 packages can be upgraded. Run 'apt list --upgradable' to see them.
Execute ["apt" "-qq" "install" "-y" "stress" "procps"] on pod zell-chaos-zeebe-gateway-58dc88cb5b-jz4lg
procps is already the newest version (2:3.3.16-1ubuntu2.3).
The following NEW packages will be installed:
  stress
0 upgraded, 1 newly installed, 0 to remove and 7 not upgraded.
Need to get 18.4 kB of archives.
After this operation, 55.3 kB of additional disk space will be used.
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package stress.
(Reading database ... 7621 files and directories currently installed.)
Preparing to unpack .../stress_1.0.4-6_amd64.deb ...
Unpacking stress (1.0.4-6) ...
Setting up stress (1.0.4-6) ...
Execute ["stress" "--timeout" "30" "--cpu" "256"] on pod zell-chaos-zeebe-gateway-58dc88cb5b-jz4lg
stress: info: [307] dispatching hogs: 256 cpu, 0 io, 0 vm, 0 hdd
stress: info: [307] successful run completed in 30s
```


**Without verbose flag:**
```
$ ./zbchaos stress gateway --cpu
Put stress on zell-chaos-zeebe-gateway-58dc88cb5b-jz4lg
```
  • Loading branch information
ChrisKujawa authored Nov 22, 2022
2 parents 8a138ee + 9375ff0 commit bd506ed
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 0 deletions.
98 changes: 98 additions & 0 deletions go-chaos/cmd/stress.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright 2022 Camunda Services GmbH
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
"fmt"

"github.com/spf13/cobra"
"github.com/zeebe-io/zeebe-chaos/go-chaos/internal"
)

var (
cpuStress bool
memoryStress bool
ioStress bool
timeoutSec string
)

func init() {
rootCmd.AddCommand(stress)

stress.PersistentFlags().BoolVar(&cpuStress, "cpu", true, "Specify whether CPU stress should put on the node")
stress.PersistentFlags().BoolVar(&memoryStress, "memory", false, "Specify whether memory stress should put on the node")
stress.PersistentFlags().BoolVar(&ioStress, "io", false, "Specify whether io stress should put on the node")
stressBroker.PersistentFlags().StringVar(&timeoutSec, "timeout", "30", "Specify how long the stress should be executed in seconds. Default: 30")

// stress brokers
stress.AddCommand(stressBroker)

stressBroker.Flags().IntVar(&nodeId, "nodeId", -1, "Specify the nodeId of the Broker")
stressBroker.Flags().StringVar(&role, "role", "LEADER", "Specify the partition role [LEADER, FOLLOWER] of the Broker")
stressBroker.Flags().IntVar(&partitionId, "partitionId", 1, "Specify the partition id of the Broker")

stress.AddCommand(stressGateway)

}

var stress = &cobra.Command{
Use: "stress",
Short: "Put stress on a Zeebe node",
Long: `Put stress on a Zeebe node. Node can be choose from gateway or brokers. Stress can be of different kind: memory, io or CPU. The different stress types can be combined.`,
}

var stressBroker = &cobra.Command{
Use: "broker",
Short: "Put stress on a Zeebe Broker",
Long: `Put stress on a Zeebe Broker. Broker can be identified via ID or partition and role. Stress can be of different kinds: memory, io or CPU.`,
Run: func(cmd *cobra.Command, args []string) {
internal.Verbosity = Verbose
k8Client, err := internal.CreateK8Client()
ensureNoError(err)

port := 26500
closeFn := k8Client.MustGatewayPortForward(port, port)
defer closeFn()

zbClient, err := internal.CreateZeebeClient(port)
ensureNoError(err)
defer zbClient.Close()

pod := getBrokerPod(k8Client, zbClient, nodeId, partitionId, role)
fmt.Printf("Put stress on %s\n", pod.Name)

stressType := internal.StressType{CpuStress: cpuStress, IoStress: ioStress, MemStress: memoryStress}
err = internal.PutStressOnPod(k8Client, timeoutSec, pod.Name, stressType)
ensureNoError(err)
},
}

var stressGateway = &cobra.Command{
Use: "gateway",
Short: "Put stress on a Zeebe Gateway",
Long: `Put stress on a Zeebe Gateway. Stress can be of different kinds: memory, io or CPU.`,
Run: func(cmd *cobra.Command, args []string) {
internal.Verbosity = Verbose
k8Client, err := internal.CreateK8Client()
ensureNoError(err)

pod := getGatewayPod(k8Client)
fmt.Printf("Put stress on %s\n", pod.Name)

stressType := internal.StressType{CpuStress: cpuStress, IoStress: ioStress, MemStress: memoryStress}
err = internal.PutStressOnPod(k8Client, timeoutSec, pod.Name, stressType)
ensureNoError(err)
},
}
67 changes: 67 additions & 0 deletions go-chaos/internal/stress.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright 2022 Camunda Services GmbH
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package internal

type StressType struct {
IoStress bool
CpuStress bool
MemStress bool
}

func PutStressOnPod(k8Client K8Client, timeoutSec string, podName string, stressType StressType) error {
err := installStressOnPod(k8Client, podName)
if err != nil {
return err
}

stressCmd := []string{"stress", "--timeout", timeoutSec}

if stressType.CpuStress {
// Spawn N workers spinning on sqrt().
stressCmd = append(stressCmd, "--cpu", "256")
}

if stressType.MemStress {
// Spawn N workers spinning on malloc()/free(). Per default alloc 256MB per worker.
stressCmd = append(stressCmd, "--vm", "4")
}

if stressType.IoStress {
// Spawn N workers spinning on sync().
stressCmd = append(stressCmd, "--io", "256")
}

err = k8Client.ExecuteCmdOnPod(stressCmd, podName)
if err != nil {
return err
}

return nil
}

func installStressOnPod(k8Client K8Client, podName string) error {
// the -qq flag makes the tool less noisy, remove it to get more output
err := k8Client.ExecuteCmdOnPod([]string{"apt", "-qq", "update"}, podName)
if err != nil {
return err
}

// the -qq flag makes the tool less noisy, remove it to get more output
err = k8Client.ExecuteCmdOnPod([]string{"apt", "-qq", "install", "-y", "stress", "procps"}, podName)
if err != nil {
return err
}
return nil
}

0 comments on commit bd506ed

Please sign in to comment.