Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swei/cmdv1 #22

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,4 @@ bin/
# vendor/

# Go workspace file
go.work

#tmp folder which contains .yaml files
tmp/
go.work
2 changes: 2 additions & 0 deletions api/types/load_traffic.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ type LoadProfileSpec struct {
Total int `json:"total" yaml:"total"`
// Conns defines total number of long connections used for traffic.
Conns int `json:"conns" yaml:"conns"`
// Client defines total number of HTTP clients.
Client int `json:"client" yaml:"client"`
// Requests defines the different kinds of requests with weights.
// The executor should randomly pick by weight.
Requests []*WeightedRequest
Expand Down
78 changes: 76 additions & 2 deletions cmd/kperf/commands/runner/runner.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
package runner

Check failure on line 1 in cmd/kperf/commands/runner/runner.go

View workflow job for this annotation

GitHub Actions / linter

: # github.com/Azure/kperf/cmd/kperf/commands/runner

import (
"context"
"context"
"fmt"
"os"
"sort"

"github.com/Azure/kperf/api/types"
"github.com/Azure/kperf/request"
"os"
"sort"

"github.com/Azure/kperf/api/types"
"github.com/Azure/kperf/request"

"github.com/urfave/cli"
"gopkg.in/yaml.v2"
)

// Command represents runner subcommand.
"gopkg.in/yaml.v2"

Check failure on line 23 in cmd/kperf/commands/runner/runner.go

View workflow job for this annotation

GitHub Actions / test

syntax error: non-declaration statement outside function body

Check failure on line 23 in cmd/kperf/commands/runner/runner.go

View workflow job for this annotation

GitHub Actions / build

syntax error: non-declaration statement outside function body

Check failure on line 23 in cmd/kperf/commands/runner/runner.go

View workflow job for this annotation

GitHub Actions / linter

syntax error: non-declaration statement outside function body (typecheck)

Check failure on line 23 in cmd/kperf/commands/runner/runner.go

View workflow job for this annotation

GitHub Actions / linter

expected declaration, found "gopkg.in/yaml.v2" (typecheck)

Check failure on line 23 in cmd/kperf/commands/runner/runner.go

View workflow job for this annotation

GitHub Actions / linter

syntax error: non-declaration statement outside function body) (typecheck)
)

// Command represents runner subcommand.
var Command = cli.Command{
Name: "runner",
Expand All @@ -30,6 +40,11 @@
Name: "kubeconfig",
Usage: "Path to the kubeconfig file",
},
cli.IntFlag{
Name: "client",
Usage: "Total number of HTTP clients",
Value: 1,
},
cli.StringFlag{
Name: "config",
Usage: "Path to the configuration file",
Expand All @@ -40,6 +55,59 @@
Usage: "Total number of connections. It can override corresponding value defined by --config",
Value: 1,
},
cli.StringFlag{
Name: "content-type",
Usage: "Content type (json or protobuf)",
Value: "json",
},
cli.IntFlag{
Name: "rate",
Usage: "Maximum requests per second (Zero means no limitation). It can override corresponding value defined by --config",
},
cli.IntFlag{
Name: "total",
Usage: "Total number of requests. It can override corresponding value defined by --config",
Value: 1000,
},
cli.StringFlag{
Name: "user-agent",
Usage: "User Agent",
},
},
Usage: "Setup benchmark to kube-apiserver from one endpoint",
Subcommands: []cli.Command{
runCommand,
},
}

var runCommand = cli.Command{
Name: "run",
Usage: "run a benchmark test to kube-apiserver",
Flags: []cli.Flag{
cli.StringFlag{
Name: "kubeconfig",
Usage: "Path to the kubeconfig file",
},
cli.IntFlag{
Name: "client",
Usage: "Total number of HTTP clients",
Value: 1,
},
cli.StringFlag{
Name: "config",
Usage: "Path to the configuration file",
Required: true,
},
cli.IntFlag{
Name: "conns",
Usage: "Total number of connections. It can override corresponding value defined by --config",
Value: 1,
},
cli.StringFlag{
Name: "content-type",
Usage: "Content type (json or protobuf)",
Value: "json",
},
cli.IntFlag{
Name: "rate",
Usage: "Maximum requests per second (Zero means no limitation). It can override corresponding value defined by --config",
Expand All @@ -60,17 +128,20 @@
return err
}

// Get the content type from the command-line flag
contentType := cliCtx.String("content-type")
kubeCfgPath := cliCtx.String("kubeconfig")
userAgent := cliCtx.String("user-agent")

conns := profileCfg.Spec.Conns
client := profileCfg.Spec.Conns
rate := profileCfg.Spec.Rate
restClis, err := request.NewClients(kubeCfgPath, conns, userAgent, rate)
restClis, err := request.NewClients(kubeCfgPath, conns, userAgent, rate, contentType)
if err != nil {
return err
}
stats, err := request.Schedule(context.TODO(), client, &profileCfg.Spec, restClis)

stats, err := request.Schedule(context.TODO(), &profileCfg.Spec, restClis)
if err != nil {
return err
}
Expand Down Expand Up @@ -101,6 +172,9 @@
if v := "conns"; cliCtx.IsSet(v) || profileCfg.Spec.Conns == 0 {
profileCfg.Spec.Conns = cliCtx.Int(v)
}
if v := "client"; cliCtx.IsSet(v) || profileCfg.Spec.Client == 0 {
profileCfg.Spec.Client = cliCtx.Int(v)
}
if v := "total"; cliCtx.IsSet(v) || profileCfg.Spec.Total == 0 {
profileCfg.Spec.Total = cliCtx.Int(v)
}
Expand Down
18 changes: 14 additions & 4 deletions request/client.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package request

import (
"fmt"
"math"

"k8s.io/client-go/rest"
Expand All @@ -14,8 +15,7 @@ import (
//
// 1. Is it possible to build one http2 client with multiple connections?
// 2. How to monitor HTTP2 GOAWAY frame?
// 3. Support Protobuf as accepted content
func NewClients(kubeCfgPath string, num int, userAgent string, qps int) ([]rest.Interface, error) {
func NewClients(kubeCfgPath string, ConnsNum int, userAgent string, qps int, contentType string) ([]rest.Interface, error) {
restCfg, err := clientcmd.BuildConfigFromFlags("", kubeCfgPath)
if err != nil {
return nil, err
Expand All @@ -32,8 +32,18 @@ func NewClients(kubeCfgPath string, num int, userAgent string, qps int) ([]rest.
restCfg.UserAgent = rest.DefaultKubernetesUserAgent()
}

restClients := make([]rest.Interface, 0, num)
for i := 0; i < num; i++ {
// Set the content type
switch contentType {
case "json":
restCfg.ContentType = "application/json"
case "protobuf":
restCfg.ContentType = "application/vnd.kubernetes.protobuf"
default:
return nil, fmt.Errorf("invalid content type: %s", contentType)
}

restClients := make([]rest.Interface, 0, ConnsNum)
for i := 0; i < ConnsNum; i++ {
cfgShallowCopy := *restCfg

restCli, err := rest.UnversionedRESTClientFor(&cfgShallowCopy)
Expand Down
9 changes: 5 additions & 4 deletions request/schedule.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@ func Schedule(ctx context.Context, spec *types.LoadProfileSpec, restCli []rest.I
var wg sync.WaitGroup

respMetric := metrics.NewResponseMetric()
for _, cli := range restCli {
cli := cli
for i := 0; i < spec.Client; i++ {
// reuse connection if clients > conns
cli := restCli[i%len(restCli)]
wg.Add(1)
go func() {
go func(cli rest.Interface) {
defer wg.Done()

for builder := range reqBuilderCh {
Expand Down Expand Up @@ -70,7 +71,7 @@ func Schedule(ctx context.Context, spec *types.LoadProfileSpec, restCli []rest.I
}
}()
}
}()
}(cli)
}

start := time.Now()
Expand Down
17 changes: 17 additions & 0 deletions tmp/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
version: 1
description: test
spec:
rate: 100
total: 11
conns: 10
requests:
- staleList:
version: v1
resource: pods
limit: 500
shares: 100
- quorumList:
version: v1
resource: pods
limit: 1000
shares: 150
Loading