Skip to content

Commit 72c1d93

Browse files
committed
Simulator: speed up bundle loading
Tune the client side rate limit parameter to speed up bundle loading time. - Set QPS and Burst to 100 by default. - Add flags to allow override the values.
1 parent 534d441 commit 72c1d93

File tree

6 files changed

+61
-20
lines changed

6 files changed

+61
-20
lines changed

cmd/simulator.go

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,12 @@ import (
88
"time"
99

1010
"github.com/mitchellh/go-homedir"
11+
wranglerunstructured "github.com/rancher/wrangler/pkg/unstructured"
1112
"github.com/sirupsen/logrus"
1213
"github.com/spf13/cobra"
1314
"golang.org/x/sync/errgroup"
14-
1515
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
1616

17-
wranglerunstructured "github.com/rancher/wrangler/pkg/unstructured"
18-
1917
"github.com/rancher/support-bundle-kit/pkg/simulator/apiserver"
2018
"github.com/rancher/support-bundle-kit/pkg/simulator/certs"
2119
"github.com/rancher/support-bundle-kit/pkg/simulator/etcd"
@@ -24,10 +22,12 @@ import (
2422
)
2523

2624
var (
27-
simHome string
28-
bundlePath string
29-
resetHome bool
30-
skipLoad bool
25+
simHome string
26+
bundlePath string
27+
resetHome bool
28+
skipLoad bool
29+
clientQPS float32
30+
clientBurst int
3131
)
3232

3333
var simulatorCmd = &cobra.Command{
@@ -50,7 +50,7 @@ support bundle contents using native k8s tooling like kubectl`,
5050
ctx, cancel := context.WithCancel(context.TODO())
5151
defer cancel()
5252

53-
a := apiserver.APIServerConfig{}
53+
a := apiserver.NewAPIServerConfig(clientQPS, clientBurst)
5454

5555
generatedCerts, err := certs.GenerateCerts([]string{"localhost"}, simHome)
5656
if err != nil {
@@ -105,6 +105,7 @@ support bundle contents using native k8s tooling like kubectl`,
105105
}
106106

107107
if !skipLoad {
108+
start := time.Now()
108109
err = o.CreateUnstructuredClusterObjects()
109110

110111
if err != nil {
@@ -124,6 +125,8 @@ support bundle contents using native k8s tooling like kubectl`,
124125
// ignore the error creation
125126
_ = o.CreatedFailedObjectsList()
126127
logrus.Info("All resources loaded successfully")
128+
129+
logrus.Infof("Time to load all objects: %s seconds", time.Since(start))
127130
}
128131

129132
err = eg.Wait()
@@ -145,6 +148,8 @@ func init() {
145148
simulatorCmd.PersistentFlags().StringVar(&bundlePath, "bundle-path", ".", "location to support bundle. default is .")
146149
simulatorCmd.PersistentFlags().BoolVar(&resetHome, "reset", false, "reset sim-home, will clear the contents and start a clean etcd + apiserver instance")
147150
simulatorCmd.PersistentFlags().BoolVar(&skipLoad, "skip-load", false, "skip load / re-load of bundle. this will ensure current etcd contents are only accessible")
151+
simulatorCmd.PersistentFlags().Float32Var(&clientQPS, "client-qps", apiserver.DefaultClientQPS, "QPS for the kubernete client to push objects to the api server")
152+
simulatorCmd.PersistentFlags().IntVar(&clientBurst, "client-burst", apiserver.DefaultClientBurst, "Burst for the kubernete client to push objects to the api server")
148153
}
149154

150155
// GetServiceClusterIP will return the service cluster IP from the support bundle

pkg/simulator/apiserver/apiserver.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,45 @@ import (
77
"net"
88
"time"
99

10-
"github.com/rancher/support-bundle-kit/pkg/simulator/certs"
11-
"github.com/rancher/support-bundle-kit/pkg/simulator/etcd"
10+
"github.com/sirupsen/logrus"
1211
utilerrors "k8s.io/apimachinery/pkg/util/errors"
1312
genericapiserver "k8s.io/apiserver/pkg/server"
1413
"k8s.io/client-go/rest"
1514
"k8s.io/client-go/tools/clientcmd"
1615
kubeconfig "k8s.io/client-go/tools/clientcmd/api"
1716
"k8s.io/kubernetes/cmd/kube-apiserver/app"
1817
"k8s.io/kubernetes/cmd/kube-apiserver/app/options"
18+
19+
"github.com/rancher/support-bundle-kit/pkg/simulator/certs"
20+
"github.com/rancher/support-bundle-kit/pkg/simulator/etcd"
1921
)
2022

2123
const (
2224
DefaultServiceClusterIP = "10.53.0.1"
25+
DefaultClientQPS = 100
26+
DefaultClientBurst = 100
2327
)
2428

2529
type APIServerConfig struct {
2630
Certs *certs.CertInfo
2731
Etcd *etcd.EtcdConfig
2832
KubeConfig string
2933
Config *rest.Config
34+
QPS float32
35+
Burst int
3036
}
3137

3238
const (
3339
APIVersionsSupported = "v1=true,api/beta=true,api/alpha=false"
3440
)
3541

42+
func NewAPIServerConfig(qps float32, burst int) APIServerConfig {
43+
return APIServerConfig{
44+
QPS: qps,
45+
Burst: burst,
46+
}
47+
}
48+
3649
// RunAPIServer will bootstrap an API server with only core resources enabled
3750
// No additional controllers will be scheduled
3851
func (a *APIServerConfig) RunAPIServer(ctx context.Context, serviceClusterIP string) error {
@@ -125,6 +138,10 @@ func (a *APIServerConfig) GenerateKubeConfig(path string) error {
125138
return err
126139
}
127140

141+
config.QPS = a.QPS
142+
config.Burst = a.Burst
143+
logrus.Infof("Client will be configured with QPS: %f, Burst: %d", config.QPS, config.Burst)
144+
128145
a.Config = config
129146

130147
return nil

pkg/simulator/apiserver/apiserver_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ package apiserver
22

33
import (
44
"context"
5-
"github.com/rancher/support-bundle-kit/pkg/simulator/certs"
6-
"github.com/rancher/support-bundle-kit/pkg/simulator/etcd"
75
"io/ioutil"
86
"os"
97
"path/filepath"
108
"testing"
119
"time"
10+
11+
"github.com/rancher/support-bundle-kit/pkg/simulator/certs"
12+
"github.com/rancher/support-bundle-kit/pkg/simulator/etcd"
1213
)
1314

1415
func TestRunAPIServer(t *testing.T) {
@@ -22,7 +23,7 @@ func TestRunAPIServer(t *testing.T) {
2223
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
2324
defer cancel()
2425

25-
a := APIServerConfig{}
26+
a := NewAPIServerConfig(DefaultClientQPS, DefaultClientBurst)
2627

2728
generatedCerts, err := certs.GenerateCerts([]string{"localhost", "127.0.0.1"}, dir)
2829
if err != nil {

pkg/simulator/crd/crd_test.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@ package crd
22

33
import (
44
"context"
5-
"github.com/rancher/support-bundle-kit/pkg/simulator/apiserver"
6-
"github.com/rancher/support-bundle-kit/pkg/simulator/certs"
7-
"github.com/rancher/support-bundle-kit/pkg/simulator/etcd"
8-
"golang.org/x/sync/errgroup"
95
"io/ioutil"
106
"os"
117
"path/filepath"
128
"testing"
139
"time"
10+
11+
"golang.org/x/sync/errgroup"
12+
13+
"github.com/rancher/support-bundle-kit/pkg/simulator/apiserver"
14+
"github.com/rancher/support-bundle-kit/pkg/simulator/certs"
15+
"github.com/rancher/support-bundle-kit/pkg/simulator/etcd"
1416
)
1517

1618
func TestWriteFiles(t *testing.T) {
@@ -36,7 +38,7 @@ func TestInstallCRD(t *testing.T) {
3638
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
3739
defer cancel()
3840

39-
a := apiserver.APIServerConfig{}
41+
a := apiserver.NewAPIServerConfig(apiserver.DefaultClientQPS, apiserver.DefaultClientBurst)
4042

4143
generatedCerts, err := certs.GenerateCerts([]string{"localhost", "127.0.0.1"}, dir)
4244
if err != nil {

pkg/simulator/objects/apply.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package objects
33
import (
44
"context"
55
"fmt"
6+
"sync"
67
"time"
78

89
wranglerunstructured "github.com/rancher/wrangler/pkg/unstructured"
@@ -54,7 +55,8 @@ var (
5455
"PodSecurityPolicy": true,
5556
}
5657

57-
cacheMap = make(map[schema.GroupVersionKind]*meta.RESTMapping)
58+
cacheMap = make(map[schema.GroupVersionKind]*meta.RESTMapping)
59+
cacheLock = new(sync.Mutex)
5860
)
5961

6062
// NewObjectManager is a wrapper around apply and support bundle path
@@ -94,6 +96,11 @@ func (o *ObjectManager) CreateUnstructuredClusterObjects() error {
9496
return err
9597
}
9698

99+
// TODO: check all CRDs are created
100+
logrus.Info("Sleeping for 5 seconds before applying cluster objects")
101+
time.Sleep(5 * time.Second)
102+
logrus.Info("Sleeping done")
103+
97104
progressMgr = NewProgressManager("Step 1/4: Cluster objects")
98105
err = o.ApplyObjects(clusterObjs, true, nil, progressMgr.progress)
99106

@@ -271,6 +278,8 @@ func objectHousekeeping(obj *unstructured.Unstructured) error {
271278
// wrapper to lookup GVR for usage with dynamic client
272279
func findGVR(gvk schema.GroupVersionKind, cfg *rest.Config) (*meta.RESTMapping, error) {
273280

281+
cacheLock.Lock()
282+
defer cacheLock.Unlock()
274283
existingMapping, ok := cacheMap[gvk]
275284
if ok {
276285
return existingMapping, nil

pkg/simulator/objects/progress.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ func (p *ProgressManager) progress(current, total int) {
2525

2626
if current == total {
2727
fmt.Printf("\n")
28-
fmt.Printf("Time to load all objects: %s seconds\n\n", time.Since(p.start))
28+
elapsed := time.Since(p.start)
29+
elapsedInSecond := int(elapsed.Seconds())
30+
31+
objsPerSecond := total
32+
if elapsedInSecond != 0 {
33+
objsPerSecond = total / elapsedInSecond
34+
}
35+
fmt.Printf("Time to load all objects: %s seconds. (%d objects/s)\n\n", elapsed, objsPerSecond)
2936
}
3037
}

0 commit comments

Comments
 (0)