Skip to content

Commit

Permalink
[Access-tokens] Add access-tokens image from github.com/mm4tt/k8s-uti…
Browse files Browse the repository at this point in the history
…l/experiments

This image is required to run clusterloader2 load test with access-tokens testing

Also:
* update modules
* increase image tag
* sanitize personal repository specific code
  • Loading branch information
jprzychodzen committed Jan 28, 2020
1 parent 2c10999 commit ac410ac
Show file tree
Hide file tree
Showing 10 changed files with 477 additions and 2 deletions.
16 changes: 16 additions & 0 deletions util-images/access-tokens/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM golang:1.13.4 AS build-env

ARG gopkg=k8s.io/perf-tests/util-images/access-tokens

ADD ["cmd", "/go/src/$gopkg/cmd"]
ADD ["go.mod", "/go/src/$gopkg"]
ADD ["go.sum", "/go/src/$gopkg"]

WORKDIR /go/src/$gopkg
RUN CGO_ENABLED=0 go build -o /workspace/access-tokens ./cmd

FROM scratch
WORKDIR /
COPY --from=build-env /workspace/access-tokens /access-tokens
ENTRYPOINT ["/access-tokens"]

17 changes: 17 additions & 0 deletions util-images/access-tokens/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
PROJECT ?= k8s-testimages
IMG = gcr.io/$(PROJECT)/perf-tests-util/access-tokens
TAG = v0.0.5

all: push

.PHONY: build
build: cmd
docker build --pull -t $(IMG):$(TAG) .
docker tag $(IMG):$(TAG) $(IMG):latest
@echo Built $(IMG):$(TAG) and tagged with latest

.PHONY: push
push: build
docker push $(IMG):$(TAG)
docker push $(IMG):latest
@echo Pushed $(IMG) with :latest and :$(TAG) tags
27 changes: 27 additions & 0 deletions util-images/access-tokens/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Access-tokens

Utility image used in [access token (explanation in issue)](https://github.com/kubernetes/kubernetes/issues/83375) testing.

Generates X number of requests per second to kube-apiserver using Y access tokens where both X, Y are configurable by flags.


## Testing and Usage

1. Build an image with `PROJECT=<TEST-PROJECT> make build`
1. Apply example yaml to your cluster
* `PROJECT=<TEST-PROJECT> cat example/example.yaml.template | envsubst | kubectl apply -f -`


## Releasing

1. If required, test with steps from `Testing and Usage`
1. Increment the `TAG` in the Makefile
1. Build with `make build`
1. Release with `make push`


## Go Modules

This project uses [Go Modules] to manage the external dependencies.

[Go Modules]: https://github.com/golang/go/wiki/Modules
107 changes: 107 additions & 0 deletions util-images/access-tokens/cmd/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
Copyright 2020 The Kubernetes Authors.
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 (
goflag "flag"
flag "github.com/spf13/pflag"
"io/ioutil"
"k8s.io/client-go/rest"
"net"
"os"
"path/filepath"
"time"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
certutil "k8s.io/client-go/util/cert"
"k8s.io/klog"
)

var (
namespace = flag.String("namespace", "", "Namespace that is targeted with request flow.")
tokenDirs = flag.StringSlice("access-token-dirs", nil, "Directories with access-token. A worker will be started per each dir/token")
qps = flag.Float64("qps-per-worker", 0.5, "QPS per worker")
)

func main() {
initFlagsAndKlog()
for i, tokenDir := range *tokenDirs {
tokenFile := filepath.Join(tokenDir, "token")
rootCAFile := filepath.Join(tokenDir, "ca.crt")
config, err := newConfig(tokenFile, rootCAFile)
if err != nil {
klog.Fatal(err.Error())
}
client, err := kubernetes.NewForConfig(config)
if err != nil {
klog.Fatal(err.Error())
}
klog.Infof("Starting worker %d\n", i)
go worker(i, client, *qps)
}
klog.Infof("Started %d workers \n", len(*tokenDirs))
if len(*tokenDirs) > 0 {
<-make(chan bool) // Block main routine.
}
}

func initFlagsAndKlog() {
flag.Set("alsologtostderr", "true")
klogFlags := goflag.NewFlagSet("klog", goflag.ExitOnError)
klog.InitFlags(klogFlags)
flag.CommandLine.AddGoFlagSet(klogFlags)
flag.Parse()
}

func worker(id int, client kubernetes.Interface, qps float64) {
duration := time.Duration(float64(int64(time.Second)) / qps)
ticker := time.NewTicker(duration)
for {
klog.V(4).Infof("Worker %v sends request\n", id)
svcAccount, err := client.CoreV1().ServiceAccounts(*namespace).Get("default", metav1.GetOptions{})
if err != nil {
klog.Warningf("Got error when getting default svcAccount: %v", err)
} else {
klog.V(4).Infof("Worker %v fetched %s svcAccount in namespace %s\n", id, svcAccount.Name, svcAccount.Namespace)
}
<-ticker.C
}
}

func newConfig(tokenFile, rootCAFile string) (*rest.Config, error) {
host, port := os.Getenv("KUBERNETES_SERVICE_HOST"), os.Getenv("KUBERNETES_SERVICE_PORT")
if len(host) == 0 || len(port) == 0 {
return nil, rest.ErrNotInCluster
}
token, err := ioutil.ReadFile(tokenFile)
if err != nil {
return nil, err
}
tlsClientConfig := rest.TLSClientConfig{}
if _, err := certutil.NewPool(rootCAFile); err != nil {
klog.Errorf("Expected to load root CA config from %s, but got err: %v", rootCAFile, err)
} else {
tlsClientConfig.CAFile = rootCAFile
}
return &rest.Config{
Host: "https://" + net.JoinHostPort(host, port),
TLSClientConfig: tlsClientConfig,
BearerToken: string(token),
BearerTokenFile: tokenFile,
}, nil
}
82 changes: 82 additions & 0 deletions util-images/access-tokens/example/example.yaml.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
apiVersion: v1
kind: Namespace
metadata:
name: access-tokens
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: access-token-user
namespace: access-tokens
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: access-token-viewer
namespace: access-tokens
rules:
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: access-token-viewer-binding
namespace: access-tokens
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: access-token-viewer
subjects:
- kind: ServiceAccount
name: access-token-user
namespace: access-tokens
---
apiVersion: v1
kind: Secret
metadata:
name: access-token
namespace: access-tokens
annotations:
kubernetes.io/service-account.name: access-token-user
type: kubernetes.io/service-account-token
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: access-tokens
name: qps-generator
labels:
app: access-tokens
spec:
selector:
matchLabels:
app: access-tokens
replicas: 1
template:
metadata:
labels:
app: access-tokens
spec:
containers:
- name: access-tokens
image: gcr.io/${PROJECT}/perf-tests-util/access-tokens:latest
args:
- --access-token-dirs=/var/tokens/access-token
- --qps-per-worker=1
- --namespace=access-tokens
resources:
limits:
cpu: 200m
memory: 200Mi
volumeMounts:
- name: access-token
mountPath: /var/tokens/access-token
volumes:
- name: access-token
secret:
secretName: access-token
10 changes: 10 additions & 0 deletions util-images/access-tokens/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module k8s.io/perf-tests/access-tokens

go 1.13

require (
github.com/spf13/pflag v1.0.5
k8s.io/apimachinery v0.0.0-20191004115801-a2eda9f80ab8
k8s.io/client-go v0.0.0-20191016111102-bec269661e48
k8s.io/klog v0.4.0
)
Loading

0 comments on commit ac410ac

Please sign in to comment.