mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 19:01:49 +00:00
test images: Adds Windows support for resource-consumer
stress was being used for the memory consumption part. This adds a golang equivalent, which will also work on Windows.
This commit is contained in:
parent
0072d8ae23
commit
28e1dee333
@ -3,3 +3,8 @@ linux/arm=k8s.gcr.io/debian-base-arm:0.4.1
|
||||
linux/arm64=k8s.gcr.io/debian-base-arm64:0.4.1
|
||||
linux/ppc64le=k8s.gcr.io/debian-base-ppc64le:0.4.1
|
||||
linux/s390x=k8s.gcr.io/debian-base-s390x:0.4.1
|
||||
windows/amd64/1809=mcr.microsoft.com/windows/nanoserver:1809
|
||||
windows/amd64/1903=mcr.microsoft.com/windows/nanoserver:1903
|
||||
windows/amd64/1909=mcr.microsoft.com/windows/nanoserver:1909
|
||||
windows/amd64/2004=mcr.microsoft.com/windows/nanoserver:2004
|
||||
windows/amd64/20H2=mcr.microsoft.com/windows/nanoserver:20H2
|
||||
|
@ -17,6 +17,8 @@ go_library(
|
||||
"resource_consumer.go",
|
||||
"resource_consumer_handler.go",
|
||||
"utils.go",
|
||||
"utils_common.go",
|
||||
"utils_windows.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/test/images/resource-consumer",
|
||||
deps = ["//test/images/resource-consumer/common:go_default_library"],
|
||||
|
33
test/images/resource-consumer/Dockerfile_windows
Normal file
33
test/images/resource-consumer/Dockerfile_windows
Normal file
@ -0,0 +1,33 @@
|
||||
# Copyright 2021 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.
|
||||
|
||||
ARG BASEIMAGE
|
||||
|
||||
# We're using a Linux image to unpack the archives, then we're copying them over to Windows.
|
||||
FROM --platform=linux/amd64 alpine:3.6 as prep
|
||||
|
||||
ADD https://download.sysinternals.com/files/Testlimit.zip /Testlimit.zip
|
||||
RUN unzip /Testlimit.zip -d /
|
||||
|
||||
FROM $BASEIMAGE
|
||||
|
||||
COPY --from=prep /Testlimit64.exe /bin/testlimit.exe
|
||||
COPY --from=prep /Eula.txt /bin/
|
||||
|
||||
ADD consumer /consumer.exe
|
||||
ADD consume-cpu/consume-cpu /consume-cpu/consume-cpu.exe
|
||||
|
||||
ENV PATH="C:\bin\;C:\curl\;C:\Windows\system32;C:\Windows;C:\Program Files\PowerShell;"
|
||||
EXPOSE 8080
|
||||
ENTRYPOINT ["/consumer.exe"]
|
@ -13,9 +13,60 @@ go_binary(
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["consume_cpu.go"],
|
||||
srcs = [
|
||||
"common.go",
|
||||
"consume_cpu.go",
|
||||
"consume_cpu_windows.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/test/images/resource-consumer/consume-cpu",
|
||||
deps = ["//vendor/bitbucket.org/bertimus9/systemstat:go_default_library"],
|
||||
deps = select({
|
||||
"@io_bazel_rules_go//go/platform:aix": [
|
||||
"//vendor/bitbucket.org/bertimus9/systemstat:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:android": [
|
||||
"//vendor/bitbucket.org/bertimus9/systemstat:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:darwin": [
|
||||
"//vendor/bitbucket.org/bertimus9/systemstat:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:dragonfly": [
|
||||
"//vendor/bitbucket.org/bertimus9/systemstat:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:freebsd": [
|
||||
"//vendor/bitbucket.org/bertimus9/systemstat:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:illumos": [
|
||||
"//vendor/bitbucket.org/bertimus9/systemstat:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:ios": [
|
||||
"//vendor/bitbucket.org/bertimus9/systemstat:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:js": [
|
||||
"//vendor/bitbucket.org/bertimus9/systemstat:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:linux": [
|
||||
"//vendor/bitbucket.org/bertimus9/systemstat:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:nacl": [
|
||||
"//vendor/bitbucket.org/bertimus9/systemstat:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:netbsd": [
|
||||
"//vendor/bitbucket.org/bertimus9/systemstat:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:openbsd": [
|
||||
"//vendor/bitbucket.org/bertimus9/systemstat:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:plan9": [
|
||||
"//vendor/bitbucket.org/bertimus9/systemstat:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:solaris": [
|
||||
"//vendor/bitbucket.org/bertimus9/systemstat:go_default_library",
|
||||
],
|
||||
"@io_bazel_rules_go//go/platform:windows": [
|
||||
"//vendor/golang.org/x/sys/windows:go_default_library",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
)
|
||||
|
||||
filegroup(
|
||||
|
37
test/images/resource-consumer/consume-cpu/common.go
Normal file
37
test/images/resource-consumer/consume-cpu/common.go
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
Copyright 2021 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 (
|
||||
"flag"
|
||||
"math"
|
||||
"time"
|
||||
)
|
||||
|
||||
const sleep = time.Duration(10) * time.Millisecond
|
||||
|
||||
func doSomething() {
|
||||
for i := 1; i < 10000000; i++ {
|
||||
x := float64(0)
|
||||
x += math.Sqrt(0)
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
millicores = flag.Int("millicores", 0, "millicores number")
|
||||
durationSec = flag.Int("duration-sec", 0, "duration time in seconds")
|
||||
)
|
@ -1,3 +1,5 @@
|
||||
// +build !windows
|
||||
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
@ -18,26 +20,11 @@ package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"bitbucket.org/bertimus9/systemstat"
|
||||
)
|
||||
|
||||
const sleep = time.Duration(10) * time.Millisecond
|
||||
|
||||
func doSomething() {
|
||||
for i := 1; i < 10000000; i++ {
|
||||
x := float64(0)
|
||||
x += math.Sqrt(0)
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
millicores = flag.Int("millicores", 0, "millicores number")
|
||||
durationSec = flag.Int("duration-sec", 0, "duration time in seconds")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
// convert millicores to percentage
|
||||
|
@ -0,0 +1,77 @@
|
||||
// +build windows
|
||||
|
||||
/*
|
||||
Copyright 2021 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 (
|
||||
"flag"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
syswin "golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
type procCPUStats struct {
|
||||
User int64 // nanoseconds spent in user mode
|
||||
System int64 // nanoseconds spent in system mode
|
||||
Time time.Time // when the sample was taken
|
||||
Total int64 // total of all time fields (nanoseconds)
|
||||
}
|
||||
|
||||
// Retrieves the amount of CPU time this process has used since it started.
|
||||
func statsNow(handle syscall.Handle) (s procCPUStats) {
|
||||
var processInfo syscall.Rusage
|
||||
syscall.GetProcessTimes(handle, &processInfo.CreationTime, &processInfo.ExitTime, &processInfo.KernelTime, &processInfo.UserTime)
|
||||
s.Time = time.Now()
|
||||
s.User = processInfo.UserTime.Nanoseconds()
|
||||
s.System = processInfo.KernelTime.Nanoseconds()
|
||||
s.Total = s.User + s.System
|
||||
return s
|
||||
}
|
||||
|
||||
// Given stats from two time points, calculates the millicores used by this
|
||||
// process between the two samples.
|
||||
func usageNow(first procCPUStats, second procCPUStats) int64 {
|
||||
dT := second.Time.Sub(first.Time).Nanoseconds()
|
||||
dUsage := (second.Total - first.Total)
|
||||
if dT == 0 {
|
||||
return 0
|
||||
}
|
||||
return 1000 * dUsage / dT
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
phandle, err := syswin.GetCurrentProcess()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
handle := syscall.Handle(phandle)
|
||||
|
||||
duration := time.Duration(*durationSec) * time.Second
|
||||
start := time.Now()
|
||||
first := statsNow(handle)
|
||||
for time.Since(start) < duration {
|
||||
currentMillicores := usageNow(first, statsNow(handle))
|
||||
if currentMillicores < int64(*millicores) {
|
||||
doSomething()
|
||||
} else {
|
||||
time.Sleep(sleep)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
// +build !windows
|
||||
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
Copyright 2021 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.
|
||||
@ -17,27 +19,16 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
var (
|
||||
consumeCPUBinary = "./consume-cpu/consume-cpu"
|
||||
consumeMemBinary = "stress"
|
||||
)
|
||||
|
||||
// ConsumeCPU consumes a given number of millicores for the specified duration.
|
||||
func ConsumeCPU(millicores int, durationSec int) {
|
||||
log.Printf("ConsumeCPU millicores: %v, durationSec: %v", millicores, durationSec)
|
||||
// creating new consume cpu process
|
||||
arg1 := fmt.Sprintf("-millicores=%d", millicores)
|
||||
arg2 := fmt.Sprintf("-duration-sec=%d", durationSec)
|
||||
consumeCPU := exec.Command(consumeCPUBinary, arg1, arg2)
|
||||
consumeCPU.Run()
|
||||
}
|
||||
|
||||
// ConsumeMem consumes a given number of megabytes for the specified duration.
|
||||
func ConsumeMem(megabytes int, durationSec int) {
|
||||
log.Printf("ConsumeMem megabytes: %v, durationSec: %v", megabytes, durationSec)
|
||||
@ -45,11 +36,8 @@ func ConsumeMem(megabytes int, durationSec int) {
|
||||
durationSecString := strconv.Itoa(durationSec)
|
||||
// creating new consume memory process
|
||||
consumeMem := exec.Command(consumeMemBinary, "-m", "1", "--vm-bytes", megabytesString, "--vm-hang", "0", "-t", durationSecString)
|
||||
consumeMem.Run()
|
||||
}
|
||||
|
||||
// GetCurrentStatus prints out a no-op.
|
||||
func GetCurrentStatus() {
|
||||
log.Printf("GetCurrentStatus")
|
||||
// not implemented
|
||||
err := consumeMem.Run()
|
||||
if err != nil {
|
||||
log.Printf("Error while consuming memory: %v", err)
|
||||
}
|
||||
}
|
||||
|
42
test/images/resource-consumer/utils_common.go
Normal file
42
test/images/resource-consumer/utils_common.go
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright 2015 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 (
|
||||
"fmt"
|
||||
"log"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
// ConsumeCPU consumes a given number of millicores for the specified duration.
|
||||
func ConsumeCPU(millicores int, durationSec int) {
|
||||
log.Printf("ConsumeCPU millicores: %v, durationSec: %v", millicores, durationSec)
|
||||
// creating new consume cpu process
|
||||
arg1 := fmt.Sprintf("-millicores=%d", millicores)
|
||||
arg2 := fmt.Sprintf("-duration-sec=%d", durationSec)
|
||||
consumeCPU := exec.Command(consumeCPUBinary, arg1, arg2)
|
||||
err := consumeCPU.Run()
|
||||
if err != nil {
|
||||
log.Printf("Error while consuming CPU: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// GetCurrentStatus prints out a no-op.
|
||||
func GetCurrentStatus() {
|
||||
log.Printf("GetCurrentStatus")
|
||||
// not implemented
|
||||
}
|
52
test/images/resource-consumer/utils_windows.go
Normal file
52
test/images/resource-consumer/utils_windows.go
Normal file
@ -0,0 +1,52 @@
|
||||
// +build windows
|
||||
|
||||
/*
|
||||
Copyright 2021 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 (
|
||||
"log"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
consumeCPUBinary = "./consume-cpu/consume-cpu.exe"
|
||||
consumeMemBinary = "testlimit.exe"
|
||||
)
|
||||
|
||||
// ConsumeMem consumes a given number of megabytes for the specified duration.
|
||||
func ConsumeMem(megabytes int, durationSec int) {
|
||||
log.Printf("ConsumeMem megabytes: %v, durationSec: %v", megabytes, durationSec)
|
||||
megabytesString := strconv.Itoa(megabytes)
|
||||
durationSecString := strconv.Itoa(durationSec)
|
||||
// creating new consume memory process
|
||||
consumeMem := exec.Command(consumeMemBinary, "-accepteula", "-r", megabytesString, "-e", "0", durationSecString, "-c", "1")
|
||||
err := consumeMem.Start()
|
||||
if err != nil {
|
||||
log.Printf("Error while consuming memory: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// testlimit does not end after durationSec elapsed, so we'll stop it ourselves.
|
||||
time.AfterFunc(time.Duration(durationSec)*time.Second, func() {
|
||||
if err := consumeMem.Process.Kill(); err != nil {
|
||||
log.Printf("Could not kill testlimit process! Error: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue
Block a user