divide idle only benchmark and autopause benchmark of cpu usage

pull/11140/head
Kent Iso 2021-04-25 03:44:16 +09:00
parent a6fdc2f8ea
commit 52ddca0ea4
16 changed files with 730 additions and 164 deletions

View File

@ -924,9 +924,13 @@ endif
stress: ## run the stress tests
go test -test.v -test.timeout=2h ./test/stress -loops=10 | tee "./out/testout_$(COMMIT_SHORT).txt"
.PHONY: cpu-benchmark
cpu-benchmark: ## run the cpu usage benchmark
./hack/benchmark/cpu_usage/benchmark_local_k8s.sh
.PHONY: cpu-benchmark-idle
cpu-benchmark-idle: ## run the cpu usage 5 minutes idle benchmark
./hack/benchmark/cpu_usage/idle_only/benchmark_local_k8s.sh
.PHONY: cpu-benchmark-autopause
cpu-benchmark-autopause: ## run the cpu usage auto-pause benchmark
./hack/benchmark/cpu_usage/auto_pause/benchmark_local_k8s.sh
.PHONY: update-gopogh-version
update-gopogh-version: ## update gopogh version

View File

@ -0,0 +1,284 @@
#!/bin/bash
# Copyright 2021 The Kubernetes Authors All rights reserved.
#
# 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.
# Gather data comparing the overhead of multiple local Kubernetes (macOS and linux)
readonly TESTS=$1
# How many iterations to cycle through
readonly TEST_ITERATIONS=10
# How long to poll CPU usage for (each point is an average over this period)
readonly POLL_DURATION=5s
# How long to measure background usage for. 5 minutes too short, 10 minutes too long
readonly TOTAL_DURATION=5m
# How all tests will be identified
readonly SESSION_ID="$(date +%Y%m%d-%H%M%S)-$$"
# OS Type
readonly OS=$(uname)
measure() {
local name=$1
local iteration=$2
local totalduration=$3
local filename="benchmark-results/${SESSION_ID}/cstat.${name}.$$-${iteration}"
echo ""
echo " >> Current top processes by CPU:"
if [[ "${OS}" == "Darwin" ]]; then
top -n 3 -l 2 -s 2 -o cpu | tail -n4 | awk '{ print $1 " " $2 " " $3 " " $4 }'
elif [[ "${OS}" == "Linux" ]]; then
top -b -n 3 -o %CPU | head -n 9
fi
if [[ "${iteration}" == 0 ]]; then
echo "NOTE: dry-run iteration: will not record measurements"
cstat --poll "${POLL_DURATION}" --for "${POLL_DURATION}" --busy
return
fi
echo ""
echo " >> Measuring ${name} and saving to out/${filename} ..."
if [[ "${totalduration}" != "" ]]; then
cstat --poll "${POLL_DURATION}" --for "${totalduration}" --busy --header=false | tee "$(pwd)/out/${filename}"
else
cstat --poll "${POLL_DURATION}" --for "${TOTAL_DURATION}" --busy --header=false | tee "$(pwd)/out/${filename}"
fi
}
cleanup() {
echo " >> Deleting local clusters and Docker containers ..."
out/minikube delete --all 2>/dev/null >/dev/null
k3d cluster delete 2>/dev/null >/dev/null
kind delete cluster 2>/dev/null >/dev/null
docker stop $(docker ps -q) 2>/dev/null
docker kill $(docker ps -q) 2>/dev/null
docker rm $(docker ps -a -q) 2>/dev/null
sleep 2
}
pause_if_running_apps() {
while true; do
local apps=$(osascript -e 'tell application "System Events" to get name of (processes where background only is false)' | tr ',' '\n' | sed s/"^ "//g)
local quiet=0
for app in $apps; do
quiet=1
if [[ "${app}" != "Terminal" && "${app}" != "Finder" ]]; then
echo "Unexpected application running: \"${app}\" - will sleep"
quiet=0
fi
done
pmset -g batt | grep 'AC Power'
if [[ "$?" != 0 ]]; then
echo "waiting to be plugged in ..."
sleep 5
continue
fi
if [[ "${quiet}" == 1 ]]; then
break
else
echo "waiting for apps to be closed ..."
sleep 5
fi
done
}
fail() {
local name=$1
local iteration=$2
echo '***********************************************************************'
echo "${name} failed on iteration ${iteration} - will not record measurement"
echo '***********************************************************************'
if [[ "${iteration}" == 0 ]]; then
echo "test environment appears invalid, exiting"
exit 90
fi
}
start_docker() {
local docker_up=0
local started=0
while [[ "${docker_up}" == 0 ]]; do
docker info >/dev/null && docker_up=1 || docker_up=0
if [[ "${docker_up}" == 0 && "${started}" == 0 ]]; then
if [[ "${OS}" == "Darwin" ]]; then
echo ""
echo " >> Starting Docker for Desktop ..."
open -a Docker
started=1
elif [[ "${OS}" == "Linux" ]]; then
echo ""
echo " >> Starting Docker Engine ..."
sudo systemctl start docker
started=1
fi
fi
sleep 1
done
# Give time for d4d Kubernetes to begin, if it's around
if [[ "${started}" == 1 ]]; then
sleep 60
fi
}
main() {
# check if cstat is installed
CSTAT=$(which cstat)
if [[ "$?" != 0 ]]; then
echo "cstat in not installed. Install cstat at https://github.com/tstromberg/cstat"
exit 1
fi
echo "----[ versions ]------------------------------------"
k3d version || { echo "k3d version failed. Please install latest k3d"; exit 1; }
kind version || { echo "kind version failed. Please install latest kind"; exit 1; }
out/minikube version || { echo "minikube version failed"; exit 1; }
docker version
echo "----------------------------------------------------"
echo ""
echo "Session ID: ${SESSION_ID}"
mkdir -p "out/benchmark-results/${SESSION_ID}"
echo ""
if [[ "${OS}" == "Darwin" ]]; then
echo "Turning on Wi-Fi for initial downloads"
networksetup -setairportpower Wi-Fi on
fi
for i in $(seq 0 ${TEST_ITERATIONS}); do
echo ""
echo "==> session ${SESSION_ID}, iteration $i"
cleanup
if [[ "$i" = 0 ]]; then
echo "NOTE: The 0 iteration is an unmeasured dry run!"
else
if [[ "${OS}" == "Darwin" ]]; then
pause_if_running_apps
echo "Turning off Wi-Fi to remove background noise"
networksetup -setairportpower Wi-Fi off
echo " >> Killing Docker for Desktop ..."
osascript -e 'quit app "Docker"'
elif [[ "${OS}" == "Linux" ]]; then
echo " >> Killing Docker Engine ..."
sudo systemctl stop docker
fi
# Measure the background noise on this system
sleep 15
measure idle $i
fi
# Run cleanup once we can assert that Docker is up
start_docker
cleanup
docker_k8s=0
# depending on whether Docker for Mac Kubernetes is enabled
if [[ "${OS}" == "Darwin" ]]; then
# wait kubernetes system pods for Docker for Mac, if it is enabled
sleep 60
kubectl --context docker-desktop version
# measure Docker for Mac Kubernetes
if [[ $? == 0 ]]; then
echo "Kubernetes is running in Docker for Desktop - adjusting tests"
docker_k8s=1
kubectl create deployment nginx --image=nginx:1.20.0 && measure docker_k8s $i
echo "end of measurement for Docker for Desktop"
kubectl delete deployment nginx
# measure Docker idle
else
kubectl create deployment nginx --image=nginx:1.20.0
measure docker $i
echo "end of measurement for Docker for Desktop Kubernetes"
kubectl delete deployment nginx
fi
# measure Docker idle only
elif [[ "${OS}" == "Linux" ]]; then
measure docker $i
fi
echo ""
echo "-> k3d"
time k3d cluster create
echo "-> deploy nginx deployment"
kubectl create deployment nginx --image=nginx:1.20.0 && measure k3d $i || fail k3d $i
cleanup
echo ""
echo "-> kind"
time kind create cluster
echo "-> deploy nginx deployment"
kubectl create deployment nginx --image=nginx:1.20.0 && measure kind $i || fail kind $i
cleanup
# test different drivers
if [[ "${OS}" == "Darwin" ]]; then
drivers=(docker hyperkit virtualbox)
elif [[ "${OS}" == "Linux" ]]; then
drivers=(docker kvm2 virtualbox)
fi
for driver in "${drivers[@]}"; do
echo ""
# 1. start minikube cluster
echo "-> out/minikube --driver=${driver}"
time out/minikube start --driver "${driver}"
#2. deploy sample application(nginx deployment) and 3. wait 1 minute without anything and 4. measure No.3 idle CPU usage
echo "-> deploy nginx deployment"
kubectl create deployment nginx --image=nginx:1.20.0 && measure "minikube.${driver}.nonautopause" $i "1m" || fail "minikube.${driver}.nonautopause" $i
# 5. enable auto-pause addons and 6. wait 3 minute without anything and measure No.6 idle CPU usage
echo "-> enable auto-pause to control plane"
out/minikube addons enable auto-pause && measure "minikube.${driver}.autopause" $i "3m" || fail "minikube.${driver}.autopause" $i
cleanup
# We won't be needing docker for the remaining tests this iteration
if [[ "${OS}" == "Darwin" && "${driver}" == "docker" ]]; then
echo " >> Quitting Docker for Desktop ..."
osascript -e 'quit app "Docker"'
elif [[ "${OS}" == "Linux" && ${driver} == "docker" ]]; then
echo " >> Quitting Docker Engine ..."
sudo systemctl stop docker
fi
done ## driver
done ## iteration
}
main "$@"
# update benchmark result into docs contents
./hack/benchmark/cpu_usage/auto_pause/update_summary.sh "${SESSION_ID}"
go run ./hack/benchmark/cpu_usage/auto_pause/chart.go "${SESSION_ID}"

View File

@ -0,0 +1,241 @@
/*
Copyright 2021 The Kubernetes Authors All rights reserved.
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 main
import (
"encoding/csv"
"fmt"
"log"
"math"
"os"
"runtime"
"strconv"
"github.com/pkg/errors"
"gonum.org/v1/plot"
"gonum.org/v1/plot/plotter"
"gonum.org/v1/plot/plotutil"
"gonum.org/v1/plot/vg"
)
var FOLDER = "site/static/images/benchmarks/cpuUsage/autoPause"
type integerTicks struct{}
func (integerTicks) Ticks(min, max float64) []plot.Tick {
var t []plot.Tick
for i := math.Trunc(min); i <= max; i += 50 {
t = append(t, plot.Tick{Value: i, Label: fmt.Sprint(i)})
}
return t
}
func main() {
if err := execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
func execute() error {
// sessionID is generated and used at cpu usage benchmark
sessionID := os.Args[1]
if len(sessionID) == 0 {
return errors.New("Please identify sessionID")
}
// Create plot instance
p := plot.New()
// Set view options
if runtime.GOOS == "darwin" {
p.Title.Text = "CPU% Busy Overhead - With Auto Pause vs. Non Auto Pause (less is better)"
} else if runtime.GOOS == "linux" {
p.Title.Text = "CPU% Busy Overhead - With Auto Pause vs. Non Auto Pause (less is better)"
}
p.Y.Label.Text = "CPU overhead%"
// Open non-autopause csv file of benchmark summary
napResults := []float64{}
var napFn string = "./out/benchmark-results/" + sessionID + "/cstat.nonautopause.summary"
napFile, err := os.Open(napFn)
if err != nil {
return errors.Wrap(err, "Missing summary csv")
}
defer napFile.Close()
// Read result values from benchmark summary csv
napReader := csv.NewReader(napFile)
var napLine []string
for {
napLine, err = napReader.Read()
if err != nil {
break
}
s, err := strconv.ParseFloat(napLine[0], 64)
if err != nil {
return errors.Wrap(err, "Failed to convert to float64")
}
napResults = append(napResults, s)
}
// Open auto-pause csv file of benchmark summary
apResults := []float64{}
var apFn string = "./out/benchmark-results/" + sessionID + "/cstat.autopause.summary"
apFile, err := os.Open(apFn)
if err != nil {
return errors.Wrap(err, "Missing summary csv")
}
defer apFile.Close()
// Read result values from benchmark summary csv
apReader := csv.NewReader(apFile)
var apLine []string
for {
apLine, err = apReader.Read()
if err != nil {
break
}
s, err := strconv.ParseFloat(apLine[0], 64)
if err != nil {
return errors.Wrap(err, "Failed to convert to float64")
}
apResults = append(apResults, s)
}
// Set bar graph width
breadth := vg.Points(40)
// Create Bar instance with non-autopause benchmark results
barNAP, err := plotter.NewBarChart(plotter.Values(napResults), breadth)
if err != nil {
return errors.Wrap(err, "Failed to create bar chart")
}
// Set border of the bar graph. 0 is no border color
barNAP.LineStyle.Width = vg.Length(0)
// Add bar name
p.Legend.Add("Initial start CPU usage", barNAP)
// Set bar color. 2 is blue
barNAP.Color = plotutil.Color(2)
// Create Bar instance with auto-pause benchmark results
barAP, err := plotter.NewBarChart(plotter.Values(apResults), breadth)
if err != nil {
return errors.Wrap(err, "Failed to create bar chart")
}
// Set border of the bar graph. 0 is no border color
barAP.LineStyle.Width = vg.Length(0)
// Add bar name
p.Legend.Add("Auto-paused CPU usage", barAP)
// Set bar color. 1 is green
barAP.Color = plotutil.Color(1)
hb := vg.Points(20)
barNAP.Offset = -hb
barAP.Offset = hb
p.Add(barNAP, barAP)
// Set legend position upper
p.Legend.Top = true
// Add x-lay names
if runtime.GOOS == "darwin" {
p.NominalX("OS idle", "minikube hyperkit", "minikube virtualbox", "minikube docker", "Docker for Mac Kubernetes", "k3d", "kind")
} else if runtime.GOOS == "linux" {
p.NominalX("OS idle", "minikube kvm2", "minikube virtualbox", "minikube docker", "Docker idle", "k3d", "kind")
}
p.X.Label.Text = "Tools"
// Set non-autopause data label to each bar
var napLabels []string
for i := range napResults {
nLabel := strconv.FormatFloat(napResults[i], 'f', -1, 64)
napLabels = append(napLabels, nLabel)
}
var napCPU []plotter.XY
for i := range napResults {
napXPos := float64(i)-0.25
napYPos := napResults[i]+0.1
napXY := plotter.XY{X: napXPos, Y: napYPos}
napCPU = append(napCPU, napXY)
}
// CPU Busy% non-autopause data label
napl, err := plotter.NewLabels(plotter.XYLabels{
XYs: napCPU,
Labels: napLabels,
},
)
if err != nil {
log.Fatalf("could not creates labels plotter: %+v", err)
}
// Set auto-pause data label to each bar
var apLabels []string
for i := range apResults {
if apResults[i] == 0 {
apLabels = append(apLabels, "N/A")
} else {
apLabel := strconv.FormatFloat(apResults[i], 'f', -1, 64)
apLabels = append(apLabels, apLabel)
}
}
var apCPU []plotter.XY
for i := range apResults {
apXPos := float64(i)+0.05
apYPos := apResults[i]+0.1
apXY := plotter.XY{X: apXPos, Y: apYPos}
apCPU = append(apCPU, apXY)
}
// CPU Busy% auto-pause data label
apl, err := plotter.NewLabels(plotter.XYLabels{
XYs: apCPU,
Labels: apLabels,
},
)
if err != nil {
log.Fatalf("could not creates labels plotter: %+v", err)
}
var t []plot.Tick
for i := math.Trunc(0); i <= 300; i += 50 {
t = append(t, plot.Tick{Value: i, Label: fmt.Sprint(i)})
}
// define max cpu busy% to 20%
p.Y.Max = 20
p.Y.Tick.Marker = integerTicks{}
// Add CPU Busy% label to plot
p.Add(napl, apl)
// Output bar graph
if runtime.GOOS == "darwin" {
if err := p.Save(13*vg.Inch, 8*vg.Inch, FOLDER+"/mac.png"); err != nil {
return errors.Wrap(err, "Failed to create bar graph png")
}
log.Printf("Generated graph png to %s/mac.png", FOLDER)
} else if runtime.GOOS == "linux" {
if err := p.Save(13*vg.Inch, 10*vg.Inch, FOLDER+"/linux.png"); err != nil {
return errors.Wrap(err, "Failed to create bar graph png")
}
log.Printf("Generated graph png to %s/linux.png", FOLDER)
}
return nil
}

View File

@ -0,0 +1,92 @@
#!/bin/bash
# Copyright 2021 The Kubernetes Authors All rights reserved.
#
# 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.
SESSION_ID=$1
NONAUTOPAUSE_RESULTS=()
AUTOPAUSE_RESULTS=()
OS=$(uname)
if [[ ${OS} == "Darwin" ]]; then
TESTS_TARGETS=("idle" "minikube.hyperkit" "minikube.virtualbox" "minikube.docker" "docker" "k3d" "kind")
elif [[ ${OS} == "Linux" ]]; then
TESTS_TARGETS=("idle" "minikube.kvm2" "minikube.virtualbox" "minikube.docker" "docker" "k3d" "kind")
fi
# calc average each non-autopause test target
calcAvarageNonAutopause() {
for target in ${TESTS_TARGETS[@]}; do
nap_count=0;
nap_total=0;
if [[ "${target}" == "minikube."* ]]; then
FILES=$(ls out/benchmark-results/${SESSION_ID} | grep cstat.${target} | grep nonautopause)
else
FILES=$(ls out/benchmark-results/${SESSION_ID} | grep cstat.${target})
fi
# calc average per test target
for file in ${FILES[@]}; do
NAP_MEASURED=$(cat out/benchmark-results/${SESSION_ID}/${file} | tail -n 1)
nap_total=$(echo ${nap_total}+${NAP_MEASURED} | bc )
((nap_count++))
done
NONAUTOPAUSE_RESULT=$(echo "scale=4; ${nap_total} / ${nap_count}" | bc | awk '{printf "%.4f\n", $0}')
NONAUTOPAUSE_RESULTS=("${NONAUTOPAUSE_RESULTS[@]}" ${NONAUTOPAUSE_RESULT})
done
}
# calc average each autopause test target
calcAvarageAutopause() {
for target in ${TESTS_TARGETS[@]}; do
if [[ "${target}" == "minikube."* ]]; then
ap_count=0;
ap_total=0;
FILES=$(ls out/benchmark-results/${SESSION_ID} | grep cstat.${target} | grep autopause)
# calc average per test target
for file in ${FILES[@]}; do
AP_MEASURED=$(cat out/benchmark-results/${SESSION_ID}/${file} | tail -n 1)
ap_total=$(echo ${ap_total}+${AP_MEASURED} | bc )
((ap_count++))
done
AUTOPAUSE_RESULT=$(echo "scale=4; ${ap_total} / ${ap_count}" | bc | awk '{printf "%.4f\n", $0}')
AUTOPAUSE_RESULTS=("${AUTOPAUSE_RESULTS[@]}" ${AUTOPAUSE_RESULT})
else
AUTOPAUSE_RESULTS=("${AUTOPAUSE_RESULTS[@]}" 0)
fi
done
}
# create non-autopause summary csv
updateNonAutopauseSummary() {
for ((i = 0; i < ${#NONAUTOPAUSE_RESULTS[@]}; i++)) {
echo "${NONAUTOPAUSE_RESULTS[i]}" >> out/benchmark-results/${SESSION_ID}/cstat.nonautopause.summary
}
}
# create autopause summary csv
updateAutopauseSummary() {
for ((i = 0; i < ${#AUTOPAUSE_RESULTS[@]}; i++)) {
echo "${AUTOPAUSE_RESULTS[i]}" >> out/benchmark-results/${SESSION_ID}/cstat.autopause.summary
}
}
calcAvarageNonAutopause
updateNonAutopauseSummary
calcAvarageAutopause
updateAutopauseSummary

View File

@ -0,0 +1,25 @@
# What is these scripts
These scripts are for the benchmark of cpu usage, minikube vs kind vs k3d.
* `benchmark_local_k8s.sh`: take benchmark for cpu usage. This will take long to take place
* `update_summary.sh`: create one summary csv file of each drivers and products
* `chart.go`: create bar chart graph as a png file
In `benchmark_local_k8s.sh`, we compare minikube drivers(hyperkit, virtualbox, docker, docker with auto-pause) and kind, k3d, Docker for Mac Kubernetes in case of macOS.
In `benchmark_local_k8s.sh`, we compare minikube drivers(kvm2, virtualbox, docker, docker with auto-pause) and kind, k3d in case of Linux.
# How to use these scripts
```
cd <Top of minikube directory>
make cpu-benchmark
```
After running `make cpu-benchmark`, the png file of the bar chart graph will be generated.
If you update the benchmark results to [our website](https://minikube.sigs.k8s.io/docs/benchmarks/), please commit this change.
```
git status
git add <Changed png file>
git commit
```

View File

@ -220,50 +220,35 @@ main() {
measure docker $i
fi
# measure k3d and kind, if Docker for Mac kubernetes is disable
if [[ "${OS}" == "Darwin" && "${docker_k8s}" == 1 ]]; then
echo "Dcoker for Mac Kubernetes is running. Skip k3d and kind measurement"
else
echo ""
echo "-> k3d"
time k3d cluster create && measure k3d $i || fail k3d $i
cleanup
# measure k3d and kind
echo ""
echo "-> k3d"
time k3d cluster create && measure k3d $i || fail k3d $i
cleanup
echo ""
echo "-> kind"
time kind create cluster && measure kind $i || fail kind $i
cleanup
fi
echo ""
echo "-> kind"
time kind create cluster && measure kind $i || fail kind $i
cleanup
# test different drivers
if [[ "${OS}" == "Darwin" ]]; then
drivers=(docker docker-autopause hyperkit virtualbox)
drivers=(docker hyperkit virtualbox)
elif [[ "${OS}" == "Linux" ]]; then
drivers=(docker docker-autopause kvm2 virtualbox)
drivers=(docker kvm2 virtualbox)
fi
for driver in "${drivers[@]}"; do
if [[ "${OS}" == "Darwin" && "${docker_k8s}" == 1 && "${driver}" == "docker" ]]; then
echo " >> Quitting Docker for Desktop ..."
osascript -e 'quit app "Docker"'
continue
fi
echo ""
if [[ "${driver}" == "docker-autopause" ]]; then
echo "-> out/minikube --driver=${driver} --addons=auto-pause"
time out/minikube start --driver docker --addons auto-pause && measure "minikube.${driver}" $i || fail "minikube.${driver}" $i
else
echo "-> out/minikube --driver=${driver}"
time out/minikube start --driver "${driver}" && measure "minikube.${driver}" $i || fail "minikube.${driver}" $i
fi
echo "-> out/minikube --driver=${driver}"
time out/minikube start --driver "${driver}" && measure "minikube.${driver}" $i || fail "minikube.${driver}" $i
cleanup
# We won't be needing docker for the remaining tests this iteration
if [[ "${OS}" == "Darwin" && "${driver}" == "docker-autopause" ]]; then
if [[ "${OS}" == "Darwin" && "${driver}" == "docker" ]]; then
echo " >> Quitting Docker for Desktop ..."
osascript -e 'quit app "Docker"'
elif [[ "${OS}" == "Linux" && ${driver} == "docker-autopause" ]]; then
elif [[ "${OS}" == "Linux" && ${driver} == "docker" ]]; then
echo " >> Quitting Docker Engine ..."
sudo systemctl stop docker
fi
@ -273,5 +258,5 @@ main() {
main "$@"
# update benchmark result into docs contents
./hack/benchmark/cpu_usage/update_summary.sh "${SESSION_ID}"
go run ./hack/benchmark/cpu_usage/chart.go "${SESSION_ID}"
./hack/benchmark/cpu_usage/idle_only/update_summary.sh "${SESSION_ID}"
go run ./hack/benchmark/cpu_usage/idle_only/chart.go "${SESSION_ID}"

View File

@ -32,6 +32,8 @@ import (
"gonum.org/v1/plot/vg"
)
var FOLDER = "site/static/images/benchmarks/cpuUsage/idleOnly"
type integerTicks struct{}
func (integerTicks) Ticks(min, max float64) []plot.Tick {
@ -113,9 +115,9 @@ func execute() error {
// Add x-lay names
if runtime.GOOS == "darwin" {
p.NominalX("OS idle", "minikube hyperkit", "minikube virtualbox", "minikube docker", "minikube docker auto-pause", "Docker for Mac Kubernetes", "k3d", "kind")
p.NominalX("OS idle", "minikube hyperkit", "minikube virtualbox", "minikube docker", "Docker for Mac Kubernetes", "k3d", "kind")
} else if runtime.GOOS == "linux" {
p.NominalX("OS idle", "minikube kvm2", "minikube virtualbox", "minikube docker", "minikube docker auto-pause", "Docker idle", "k3d", "kind")
p.NominalX("OS idle", "minikube kvm2", "minikube virtualbox", "minikube docker", "Docker idle", "k3d", "kind")
}
p.X.Label.Text = "Tools"
@ -142,30 +144,27 @@ func execute() error {
if err != nil {
log.Fatalf("could not creates labels plotter: %+v", err)
}
//for i := range rl.TextStyle {
// rl.TextStyle[i].Color = color.RGBA{R: 255, A: 255}
//}
var t []plot.Tick
for i := math.Trunc(0); i <= 300; i += 50 {
t = append(t, plot.Tick{Value: i, Label: fmt.Sprint(i)})
}
// define max cpu busy% to 30%
p.Y.Max = 30
// define max cpu busy% to 20%
p.Y.Max = 20
p.Y.Tick.Marker = integerTicks{}
// Add CPU Busy% label to plot
p.Add(cl)
// Output bar graph
if runtime.GOOS == "darwin" {
if err := p.Save(13*vg.Inch, 8*vg.Inch, "./site/static/images/benchmarks/cpuUsage/mac.png"); err != nil {
if err := p.Save(13*vg.Inch, 8*vg.Inch, FOLDER+"/mac.png"); err != nil {
return errors.Wrap(err, "Failed to create bar graph png")
}
log.Printf("Generated graph png to 'site/static/images/benchmarks/cpuUsage/mac.png'")
log.Printf("Generated graph png to %s/mac.png", FOLDER)
} else if runtime.GOOS == "linux" {
if err := p.Save(13*vg.Inch, 10*vg.Inch, "./site/static/images/benchmarks/cpuUsage/linux.png"); err != nil {
if err := p.Save(13*vg.Inch, 10*vg.Inch, FOLDER+"/linux.png"); err != nil {
return errors.Wrap(err, "Failed to create bar graph png")
}
log.Printf("Generated graph png to 'site/static/images/benchmarks/cpuUsage/linux.png'")
log.Printf("Generated graph png to %s/linux.png", FOLDER)
}
return nil
}

View File

@ -20,9 +20,9 @@ RESULTS=()
OS=$(uname)
if [[ ${OS} == "Darwin" ]]; then
TESTS_TARGETS=("idle" "minikube.hyperkit" "minikube.virtualbox" "minikube.docker" "minikube.docker-autopause" "docker" "k3d" "kind")
TESTS_TARGETS=("idle" "minikube.hyperkit" "minikube.virtualbox" "minikube.docker" "docker" "k3d" "kind")
elif [[ ${OS} == "Linux" ]]; then
TESTS_TARGETS=("idle" "minikube.kvm2" "minikube.virtualbox" "minikube.docker" "minikube.docker-autopause" "docker" "k3d" "kind")
TESTS_TARGETS=("idle" "minikube.kvm2" "minikube.virtualbox" "minikube.docker" "docker" "k3d" "kind")
fi
# calc average each test target
@ -30,7 +30,7 @@ calcAvarage() {
for target in ${TESTS_TARGETS[@]}; do
count=0;
total=0;
FILES=$(ls out/benchmark-results/${SESSION_ID} | grep cstat.${target})
FILES=$(ls out/benchmark-results/${SESSION_ID} | grep cstat.${target})
# calc average per test target
for file in ${FILES[@]}; do

View File

@ -1,113 +0,0 @@
package main
import (
"fmt"
"image/color"
"log"
"math"
"strconv"
"gonum.org/v1/plot"
"gonum.org/v1/plot/plotter"
"gonum.org/v1/plot/vg"
)
type integerTicks struct{}
func (integerTicks) Ticks(min, max float64) []plot.Tick {
var t []plot.Tick
for i := math.Trunc(min); i <= max; i += 50 {
t = append(t, plot.Tick{Value: i, Label: fmt.Sprint(i)})
}
return t
}
func main() {
red := plotter.Values{213, 206, 256, 256, 16, 122, 291}
black := plotter.Values{16, 86, 109, 290, 42, 257, 9}
days := []string{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}
p := plot.New()
redC := color.RGBA{R: 255, A: 255}
blackC := color.RGBA{R: 196, G: 196, A: 255}
w := vg.Points(8)
redBars, err := plotter.NewBarChart(red, w)
if err != nil {
panic(err)
}
redBars.Color = redC
redBars.Offset = -w
blackBars, err := plotter.NewBarChart(black, w)
if err != nil {
panic(err)
}
blackBars.Color = blackC
blackBars.Offset = w
p.Add(blackBars, redBars)
p.NominalX(days...)
var redLabels []string
var blackLabels []string
for i := range red {
rLabel := strconv.FormatFloat(red[i], 'f', -1, 64)
bLabel := strconv.FormatFloat(black[i], 'f', -1, 64)
redLabels = append(redLabels, rLabel)
blackLabels = append(blackLabels, bLabel)
}
var xysR, xysB []plotter.XY
for i := range red {
rxPos, bxPos := float64(i)-0.5, float64(i)+0.1
ryPos, byPos := red[i]+5, black[i]+5
rXY := plotter.XY{X: rxPos, Y: ryPos}
bXY := plotter.XY{X: bxPos, Y: byPos}
xysR = append(xysR, rXY)
xysB = append(xysB, bXY)
}
rl, err := plotter.NewLabels(plotter.XYLabels{
XYs: xysR,
Labels: redLabels,
},
)
if err != nil {
log.Fatalf("could not creates labels plotter: %+v", err)
}
for i := range rl.TextStyle {
rl.TextStyle[i].Color = color.RGBA{R: 255, A: 255}
//fmt.Println(r, i)
}
bl, err := plotter.NewLabels(plotter.XYLabels{
XYs: xysB,
Labels: blackLabels,
},
)
if err != nil {
log.Fatalf("could not creates labels plotter: %+v", err)
}
var t []plot.Tick
for i := math.Trunc(0); i <= 300; i += 50 {
t = append(t, plot.Tick{Value: i, Label: fmt.Sprint(i)})
}
p.Y.Max = 310
p.Y.Tick.Marker = integerTicks{}
p.Add(rl, bl)
if err := p.Save(4*vg.Inch, 4*vg.Inch, "points.png"); err != nil {
panic(err)
}
}

View File

@ -4,4 +4,27 @@ linkTitle: "CPU Usage Benchmarks(Linux)"
weight: 1
---
![linux](/images/benchmarks/cpuUsage/linux.png)
## CPU% Busy Overhead - Avarage first 5 minutes only
This chart shows each tool's CPU busy overhead percentage.
After each tool's starting, we measured each tool's idle for 5 minutes.
This chart was measured only after the start without deploying any pods.
![idleOnly](/images/benchmarks/cpuUsage/linux.png)
## CPU% Busy Overhead - With Auto Pause vs. Non Auto Pause
This chart shows each tool's CPU busy overhead percentage with auto-pause addon.
The auto-pause is mechanism which reduce CPU busy usage by pausing kube-apiserver.
This chart was measured with the following steps.
By these steps, we compare CPU usage with auto-pause vs. non-auto-pause.
1. start each local kubernetes tool
2. deploy sample application(nginx deployment)
3. wait 1 minute without anything
4. measure No.3 idle CPU usage with [cstat](https://github.com/tstromberg/cstat)
5. enable auto-pause addons(only if tool is minikube)
6. wait 3 minute without anything
7. measure No.6 idle CPU usage with [cstat](https://github.com/tstromberg/cstat)
![autopause](/images/benchmarks/cpuUsage/autoPause/linux.png)

View File

@ -4,4 +4,30 @@ linkTitle: "CPU Usage Benchmarks(macOS)"
weight: 1
---
![mac](/images/benchmarks/cpuUsage/mac.png)
## CPU% Busy Overhead - Avarage first 5 minutes only
This chart shows each tool's CPU busy overhead percentage.
After each tool's starting, we measured each tool's idle for 5 minutes.
This chart was measured only after the start without deploying any pods.
1. start each local kubernetes tool
2. measure its cpu usage with [cstat](https://github.com/tstromberg/cstat)
![idleOnly](/images/benchmarks/cpuUsage/idleOnly/mac.png)
## CPU% Busy Overhead - With Auto Pause vs. Non Auto Pause
This chart shows each tool's CPU busy overhead percentage with auto-pause addon.
The auto-pause is mechanism which reduce CPU busy usage by pausing kube-apiserver.
This chart was measured with the following steps.
By these steps, we compare CPU usage with auto-pause vs. non-auto-pause.
1. start each local kubernetes tool
2. deploy sample application(nginx deployment)
3. wait 1 minute without anything
4. measure No.3 idle CPU usage with [cstat](https://github.com/tstromberg/cstat)
5. enable auto-pause addons(only if tool is minikube)
6. wait 3 minute without anything
7. measure No.6 idle CPU usage with [cstat](https://github.com/tstromberg/cstat)
![autopause](/images/benchmarks/cpuUsage/autoPause/mac.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB