add make command to auto benchmark time-to-k8s and update website
parent
9db3ae665c
commit
a81761ea4a
|
@ -1,3 +1,6 @@
|
|||
[submodule "site/themes/docsy"]
|
||||
path = site/themes/docsy
|
||||
url = https://github.com/google/docsy.git
|
||||
[submodule "hack/benchmark/time-to-k8s/time-to-k8s"]
|
||||
path = hack/benchmark/time-to-k8s/time-to-k8s
|
||||
url = git@github.com:tstromberg/time-to-k8s.git
|
||||
|
|
4
Makefile
4
Makefile
|
@ -967,6 +967,10 @@ cpu-benchmark-idle: ## run the cpu usage 5 minutes idle benchmark
|
|||
cpu-benchmark-autopause: ## run the cpu usage auto-pause benchmark
|
||||
./hack/benchmark/cpu_usage/auto_pause/benchmark_local_k8s.sh
|
||||
|
||||
.PHONY: time-to-k8s-benchmark
|
||||
time-to-k8s-benchmark:
|
||||
./hack/benchmark/time-to-k8s/time-to-k8s.sh
|
||||
|
||||
.PHONY: update-gopogh-version
|
||||
update-gopogh-version: ## update gopogh version
|
||||
(cd hack/update/gopogh_version && \
|
||||
|
|
|
@ -0,0 +1,243 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/csv"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"gonum.org/v1/plot"
|
||||
"gonum.org/v1/plot/plotter"
|
||||
"gonum.org/v1/plot/plotutil"
|
||||
"gonum.org/v1/plot/vg"
|
||||
)
|
||||
|
||||
const (
|
||||
cmdCSVIndex = 8
|
||||
apiCSVIndex = 9
|
||||
k8sCSVIndex = 10
|
||||
dnsSvcCSVIndex = 11
|
||||
appCSVIndex = 12
|
||||
dnsAnsCSVIndex = 13
|
||||
)
|
||||
|
||||
type run struct {
|
||||
cmd float64
|
||||
api float64
|
||||
k8s float64
|
||||
dnsSvc float64
|
||||
app float64
|
||||
dnsAns float64
|
||||
}
|
||||
|
||||
type runs struct {
|
||||
version string
|
||||
runs []run
|
||||
}
|
||||
|
||||
func main() {
|
||||
csvPath := flag.String("csv", "", "path to the CSV file")
|
||||
chartPath := flag.String("output", "", "path to output the chart to")
|
||||
flag.Parse()
|
||||
|
||||
// map of the apps (minikube, kind, k3d) and their runs
|
||||
apps := make(map[string]runs)
|
||||
|
||||
if err := readInCSV(*csvPath, apps); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
values, totals, names := values(apps)
|
||||
|
||||
if err := createChart(*chartPath, values, totals, names); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func readInCSV(csvPath string, apps map[string]runs) error {
|
||||
f, err := os.Open(csvPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r := csv.NewReader(f)
|
||||
for {
|
||||
d, err := r.Read()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// skip the first line of the CSV file
|
||||
if d[0] == "name" {
|
||||
continue
|
||||
}
|
||||
|
||||
values := []float64{}
|
||||
|
||||
// 8-13 contain the run results
|
||||
for i := 8; i <= 13; i++ {
|
||||
v, err := strconv.ParseFloat(d[i], 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
values = append(values, v)
|
||||
}
|
||||
newRun := run{values[0], values[1], values[2], values[3], values[4], values[5]}
|
||||
|
||||
// get the app from the map and add the new run to it
|
||||
name := d[0]
|
||||
k, ok := apps[name]
|
||||
if !ok {
|
||||
k = runs{version: d[5]}
|
||||
}
|
||||
k.runs = append(k.runs, newRun)
|
||||
apps[name] = k
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func values(apps map[string]runs) ([]plotter.Values, []float64, []string) {
|
||||
cmdValues := plotter.Values{}
|
||||
apiValues := plotter.Values{}
|
||||
k8sValues := plotter.Values{}
|
||||
dnsSvcValues := plotter.Values{}
|
||||
appValues := plotter.Values{}
|
||||
dnsAnsValues := plotter.Values{}
|
||||
names := []string{}
|
||||
totals := []float64{}
|
||||
|
||||
// for each app, calculate the average for all the runs, and append them to the charting values
|
||||
for _, name := range []string{"minikube", "kind", "k3d"} {
|
||||
app := apps[name]
|
||||
cmd := 0.0
|
||||
api := 0.0
|
||||
k8s := 0.0
|
||||
dnsSvc := 0.0
|
||||
appRun := 0.0
|
||||
dnsAns := 0.0
|
||||
names = append(names, app.version)
|
||||
|
||||
for _, l := range app.runs {
|
||||
cmd += l.cmd
|
||||
api += l.api
|
||||
k8s += l.k8s
|
||||
dnsSvc += l.dnsSvc
|
||||
appRun += l.app
|
||||
dnsAns += l.dnsAns
|
||||
}
|
||||
|
||||
c := float64(len(app.runs))
|
||||
|
||||
cmdAvg := cmd / c
|
||||
apiAvg := api / c
|
||||
k8sAvg := k8s / c
|
||||
dnsSvcAvg := dnsSvc / c
|
||||
appAvg := appRun / c
|
||||
dnsAnsAvg := dnsAns / c
|
||||
|
||||
cmdValues = append(cmdValues, cmdAvg)
|
||||
apiValues = append(apiValues, apiAvg)
|
||||
k8sValues = append(k8sValues, k8sAvg)
|
||||
dnsSvcValues = append(dnsSvcValues, dnsSvcAvg)
|
||||
appValues = append(appValues, appAvg)
|
||||
dnsAnsValues = append(dnsAnsValues, dnsAnsAvg)
|
||||
|
||||
total := cmdAvg + apiAvg + k8sAvg + dnsSvcAvg + appAvg + dnsAnsAvg
|
||||
totals = append(totals, total)
|
||||
}
|
||||
|
||||
values := []plotter.Values{cmdValues, apiValues, k8sValues, dnsSvcValues, appValues, dnsAnsValues}
|
||||
|
||||
return values, totals, names
|
||||
}
|
||||
|
||||
func createChart(chartPath string, values []plotter.Values, totals []float64, names []string) error {
|
||||
p := plot.New()
|
||||
p.Title.Text = "Time to go from 0 to successful Kubernetes deployment"
|
||||
p.Y.Label.Text = "time (seconds)"
|
||||
|
||||
bars := []*plotter.BarChart{}
|
||||
|
||||
// create bars for all the values
|
||||
for i, v := range values {
|
||||
bar, err := createBars(v, i)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bars = append(bars, bar)
|
||||
p.Add(bar)
|
||||
}
|
||||
|
||||
// stack the bars
|
||||
bars[0].StackOn(bars[1])
|
||||
bars[1].StackOn(bars[2])
|
||||
bars[2].StackOn(bars[3])
|
||||
bars[3].StackOn(bars[4])
|
||||
bars[4].StackOn(bars[5])
|
||||
|
||||
// max Y value of the chart
|
||||
p.Y.Max = 80
|
||||
|
||||
// add all the bars to the legend
|
||||
legends := []string{"Command Exec", "API Server Answering", "Kubernetes SVC", "DNS SVC", "App Running", "DNS Answering"}
|
||||
for i, bar := range bars {
|
||||
p.Legend.Add(legends[i], bar)
|
||||
}
|
||||
|
||||
p.Legend.Top = true
|
||||
|
||||
// add app name to the bars
|
||||
p.NominalX(names...)
|
||||
|
||||
// create total time labels
|
||||
var labels []string
|
||||
for _, total := range totals {
|
||||
label := fmt.Sprintf("%.2f", total)
|
||||
labels = append(labels, label)
|
||||
}
|
||||
|
||||
// create label positions
|
||||
var labelPositions []plotter.XY
|
||||
for i := range totals {
|
||||
x := float64(i) - 0.03
|
||||
y := totals[i] + 0.3
|
||||
labelPosition := plotter.XY{X: x, Y: y}
|
||||
labelPositions = append(labelPositions, labelPosition)
|
||||
}
|
||||
|
||||
l, err := plotter.NewLabels(plotter.XYLabels{
|
||||
XYs: labelPositions,
|
||||
Labels: labels,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p.Add(l)
|
||||
|
||||
if err := p.Save(12*vg.Inch, 8*vg.Inch, chartPath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func createBars(values plotter.Values, index int) (*plotter.BarChart, error) {
|
||||
bars, err := plotter.NewBarChart(values, vg.Points(20))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bars.LineStyle.Width = vg.Length(0)
|
||||
bars.Width = vg.Length(80)
|
||||
bars.Color = plotutil.Color(index)
|
||||
|
||||
return bars, nil
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 72506e948764aeeafc01e58e6bec0ea741c61ca0
|
|
@ -0,0 +1,61 @@
|
|||
#!/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.
|
||||
|
||||
set -e
|
||||
|
||||
install_kind() {
|
||||
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.11.0/kind-linux-amd64
|
||||
chmod +x ./kind
|
||||
sudo mv ./kind /usr/local
|
||||
}
|
||||
|
||||
install_k3d() {
|
||||
curl -s https://raw.githubusercontent.com/rancher/k3d/main/install.sh | bash
|
||||
}
|
||||
|
||||
install_minikube() {
|
||||
make
|
||||
sudo install ./out/minikube /usr/local/bin/minikube
|
||||
}
|
||||
|
||||
run_benchmark() {
|
||||
( cd ./hack/benchmark/time-to-k8s/time-to-k8s/ &&
|
||||
git submodule update --init &&
|
||||
go run . --config local-kubernetes.yaml --iterations 5 --output output.csv )
|
||||
}
|
||||
|
||||
generate_chart() {
|
||||
go run ./hack/benchmark/time-to-k8s/chart.go --csv ./hack/benchmark/time-to-k8s/time-to-k8s/output.csv --output ./site/static/images/benchmarks/timeToK8s/"$1".png
|
||||
}
|
||||
|
||||
create_page() {
|
||||
printf -- "---\ntitle: \"%s Benchmark\"\nlinkTitle: \"%s Benchmark\"\nweight: 1\n---\n\n\n" "$1" "$1" "$1" > ./site/content/en/docs/benchmarks/timeToK8s/"$1".md
|
||||
}
|
||||
|
||||
commit_chart() {
|
||||
git add ./site/static/images/benchmarks/timeToK8s/"$1".png ./site/content/en/docs/benchmarks/timeToK8s/"$1".md
|
||||
git commit -m 'update time-to-k8s chart'
|
||||
}
|
||||
|
||||
install_kind
|
||||
install_k3d
|
||||
install_minikube
|
||||
VERSION=$(minikube version --short)
|
||||
|
||||
run_benchmark
|
||||
generate_chart "$VERSION"
|
||||
create_page "$VERSION"
|
||||
commit_chart "$VERSION"
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: "time-to-k8s Benchmarks"
|
||||
linkTitle: "time-to-k8s Benchmarks"
|
||||
weight: 1
|
||||
---
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
title: "v1.20.0 Benchmark"
|
||||
linkTitle: "v1.20.0 Benchmark"
|
||||
weight: 1
|
||||
---
|
||||
|
||||

|
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
Loading…
Reference in New Issue