From 13f7501477df09ca48946f0ac5751b27adc7f085 Mon Sep 17 00:00:00 2001 From: ocichina001 <165124541+ocichina001@users.noreply.github.com> Date: Wed, 27 Mar 2024 13:11:17 +0800 Subject: [PATCH 01/36] Add files via upload Signed-off-by: ocichina001 <165124541+ocichina001@users.noreply.github.com> Signed-off-by: george --- .../util/runtime/handler/crio_runtime.go | 102 ++++++++++++++ .../util/runtime/handler/crio_runtime_test.go | 130 ++++++++++++++++++ 2 files changed, 232 insertions(+) create mode 100644 pkg/koordlet/util/runtime/handler/crio_runtime.go create mode 100644 pkg/koordlet/util/runtime/handler/crio_runtime_test.go diff --git a/pkg/koordlet/util/runtime/handler/crio_runtime.go b/pkg/koordlet/util/runtime/handler/crio_runtime.go new file mode 100644 index 000000000..0c368ca38 --- /dev/null +++ b/pkg/koordlet/util/runtime/handler/crio_runtime.go @@ -0,0 +1,102 @@ +/* +Copyright 2022 The Koordinator 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 handler + +import ( + "context" + "fmt" + "os" + "path/filepath" + "strings" + "time" + + runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" + + "github.com/koordinator-sh/koordinator/pkg/koordlet/util/system" +) + + +func GetCrioEndpoint() string { + return filepath.Join(system.Conf.VarRunRootDir, "crio/crio.sock") +} + +func GetCrioEndpoint2() string { + return filepath.Join(system.Conf.VarRunRootDir, "crio.sock") +} + +type CrioRuntimeHandler struct { + runtimeServiceClient runtimeapi.RuntimeServiceClient + timeout time.Duration + endpoint string +} + +func NewCrioRuntimeHandler(endpoint string) (ContainerRuntimeHandler, error) { + ep := strings.TrimPrefix(endpoint, "unix://") + if _, err := os.Stat(ep); err != nil { + return nil, err + } + + client, err := getRuntimeClient(endpoint) + if err != nil { + return nil, err + } + + return &CrioRuntimeHandler{ + runtimeServiceClient: client, + timeout: defaultConnectionTimeout, + endpoint: endpoint, + }, nil +} + +func (c *CrioRuntimeHandler) StopContainer(containerID string, timeout int64) error { + if containerID == "" { + return fmt.Errorf("containerID cannot be empty") + } + t := c.timeout + time.Duration(timeout) + ctx, cancel := context.WithTimeout(context.Background(), t) + defer cancel() + + request := &runtimeapi.StopContainerRequest{ + ContainerId: containerID, + Timeout: timeout, + } + _, err := c.runtimeServiceClient.StopContainer(ctx, request) + return err +} + + +func (c *CrioRuntimeHandler) UpdateContainerResources(containerID string, opts UpdateOptions) error { + if containerID == "" { + return fmt.Errorf("containerID cannot be empty") + } + ctx, cancel := context.WithTimeout(context.Background(), c.timeout) + defer cancel() + request := &runtimeapi.UpdateContainerResourcesRequest{ + ContainerId: containerID, + Linux: &runtimeapi.LinuxContainerResources{ + CpuPeriod: opts.CPUPeriod, + CpuQuota: opts.CPUQuota, + CpuShares: opts.CPUShares, + CpusetCpus: opts.CpusetCpus, + CpusetMems: opts.CpusetMems, + MemoryLimitInBytes: opts.MemoryLimitInBytes, + OomScoreAdj: opts.OomScoreAdj, + }, + } + _, err := c.runtimeServiceClient.UpdateContainerResources(ctx, request) + return err +} diff --git a/pkg/koordlet/util/runtime/handler/crio_runtime_test.go b/pkg/koordlet/util/runtime/handler/crio_runtime_test.go new file mode 100644 index 000000000..edc9c64b8 --- /dev/null +++ b/pkg/koordlet/util/runtime/handler/crio_runtime_test.go @@ -0,0 +1,130 @@ +/* +Copyright 2022 The Koordinator 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 handler + +import ( + "context" + "fmt" + "path/filepath" + "testing" + + "github.com/golang/mock/gomock" + "github.com/prashantv/gostub" + "github.com/stretchr/testify/assert" + "google.golang.org/grpc" + + mockclient "github.com/koordinator-sh/koordinator/pkg/koordlet/util/runtime/handler/mockclient" + "github.com/koordinator-sh/koordinator/pkg/koordlet/util/system" +) + +func Test_NewCrioRuntimeHandler(t *testing.T) { + stubs := gostub.Stub(&GrpcDial, func(context context.Context, target string, opts ...grpc.DialOption) (*grpc.ClientConn, error) { + return &grpc.ClientConn{}, nil + }) + defer stubs.Reset() + + helper := system.NewFileTestUtil(t) + defer helper.Cleanup() + + helper.WriteFileContents("/var/run/crio/crio.sock", "test") + system.Conf.VarRunRootDir = filepath.Join(helper.TempDir, "/var/run") + CrioEndpoint1 := GetCrioEndpoint() + unixEndPoint := fmt.Sprintf("unix://%s", CrioEndpoint1) + crioRuntime, err := NewCrioRuntimeHandler(unixEndPoint) + assert.NoError(t, err) + assert.NotNil(t, crioRuntime) + + // custom VarRunRootDir + helper.WriteFileContents("/host-var-run/crio/crio.sock", "test1") + system.Conf.VarRunRootDir = filepath.Join(helper.TempDir, "/host-var-run") + CrioEndpoint1 = GetCrioEndpoint() + unixEndPoint = fmt.Sprintf("unix://%s", CrioEndpoint1) + crioRuntime, err = NewCrioRuntimeHandler(unixEndPoint) + assert.NoError(t, err) + assert.NotNil(t, crioRuntime) +} + +func Test_Crio_StopContainer(t *testing.T) { + type args struct { + name string + containerId string + runtimeError error + expectError bool + } + tests := []args{ + { + name: "test_stopContainer_success", + containerId: "test_container_id", + runtimeError: nil, + expectError: false, + }, + { + name: "test_stopContainer_fail", + containerId: "test_container_id", + runtimeError: fmt.Errorf("stopContainer error"), + expectError: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctl := gomock.NewController(t) + defer ctl.Finish() + mockRuntimeClient := mockclient.NewMockRuntimeServiceClient(ctl) + mockRuntimeClient.EXPECT().StopContainer(gomock.Any(), gomock.Any()).Return(nil, tt.runtimeError) + + runtimeHandler := ContainerdRuntimeHandler{runtimeServiceClient: mockRuntimeClient, timeout: 1, endpoint: GetCrioEndpoint()} + gotErr := runtimeHandler.StopContainer(tt.containerId, 1) + assert.Equal(t, gotErr != nil, tt.expectError) + + }) + } +} + +func Test_Crio_UpdateContainerResources(t *testing.T) { + type args struct { + name string + containerId string + runtimeError error + expectError bool + } + tests := []args{ + { + name: "test_UpdateContainerResources_success", + containerId: "test_container_id", + runtimeError: nil, + expectError: false, + }, + { + name: "test_UpdateContainerResources_fail", + containerId: "test_container_id", + runtimeError: fmt.Errorf("UpdateContainerResources error"), + expectError: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctl := gomock.NewController(t) + defer ctl.Finish() + mockRuntimeClient := mockclient.NewMockRuntimeServiceClient(ctl) + mockRuntimeClient.EXPECT().UpdateContainerResources(gomock.Any(), gomock.Any()).Return(nil, tt.runtimeError) + + runtimeHandler := ContainerdRuntimeHandler{runtimeServiceClient: mockRuntimeClient, timeout: 1, endpoint: GetCrioEndpoint()} + gotErr := runtimeHandler.UpdateContainerResources(tt.containerId, UpdateOptions{}) + assert.Equal(t, tt.expectError, gotErr != nil) + }) + } +} From 9fa6b84919bdda556210cb2351756a0aec0dc602 Mon Sep 17 00:00:00 2001 From: ocichina001 <165124541+ocichina001@users.noreply.github.com> Date: Wed, 27 Mar 2024 13:15:04 +0800 Subject: [PATCH 02/36] Add files via upload Signed-off-by: ocichina001 <165124541+ocichina001@users.noreply.github.com> Signed-off-by: george --- pkg/koordlet/util/system/config.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/koordlet/util/system/config.go b/pkg/koordlet/util/system/config.go index 9dda99659..4091a64c8 100644 --- a/pkg/koordlet/util/system/config.go +++ b/pkg/koordlet/util/system/config.go @@ -47,6 +47,7 @@ type Config struct { ContainerdEndPoint string PouchEndpoint string DockerEndPoint string + CrioEndPoint string DefaultRuntimeType string } From f20ed46af9994ea08aaad7630170a7d7a499bf03 Mon Sep 17 00:00:00 2001 From: ocichina001 <165124541+ocichina001@users.noreply.github.com> Date: Wed, 27 Mar 2024 13:15:51 +0800 Subject: [PATCH 03/36] Update config.go Signed-off-by: ocichina001 <165124541+ocichina001@users.noreply.github.com> Signed-off-by: george --- pkg/koordlet/util/system/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/koordlet/util/system/config.go b/pkg/koordlet/util/system/config.go index 4091a64c8..45a3e4231 100644 --- a/pkg/koordlet/util/system/config.go +++ b/pkg/koordlet/util/system/config.go @@ -47,7 +47,7 @@ type Config struct { ContainerdEndPoint string PouchEndpoint string DockerEndPoint string - CrioEndPoint string + CrioEndPoint string DefaultRuntimeType string } From 9d2c8b3a64bc8eb0b8590404e2e2216eaa7b46c2 Mon Sep 17 00:00:00 2001 From: ocichina001 <165124541+ocichina001@users.noreply.github.com> Date: Wed, 27 Mar 2024 13:19:20 +0800 Subject: [PATCH 04/36] Add files via upload Signed-off-by: ocichina001 <165124541+ocichina001@users.noreply.github.com> Signed-off-by: george --- pkg/koordlet/util/runtime/runtime.go | 40 +++++++++++++++++++++++ pkg/koordlet/util/runtime/runtime_test.go | 22 +++++++++++++ 2 files changed, 62 insertions(+) diff --git a/pkg/koordlet/util/runtime/runtime.go b/pkg/koordlet/util/runtime/runtime.go index 5db9be180..db71e6505 100644 --- a/pkg/koordlet/util/runtime/runtime.go +++ b/pkg/koordlet/util/runtime/runtime.go @@ -32,6 +32,7 @@ var ( DockerHandler handler.ContainerRuntimeHandler ContainerdHandler handler.ContainerRuntimeHandler PouchHandler handler.ContainerRuntimeHandler + CrioHandler handler.ContainerRuntimeHandler mutex = &sync.Mutex{} ) @@ -46,6 +47,8 @@ func GetRuntimeHandler(runtimeType string) (handler.ContainerRuntimeHandler, err return getContainerdHandler() case system.RuntimeTypePouch: return getPouchHandler() + case system.RuntimeTypeCrio: + return getCrioHandler() default: return nil, fmt.Errorf("runtime type %v is not supported", runtimeType) } @@ -152,6 +155,43 @@ func getPouchEndpoint() (string, error) { return "", fmt.Errorf("pouch endpoint does not exist") } +func getCrioHandler() (handler.ContainerRuntimeHandler, error) { + if CrioHandler != nil { + return CrioHandler, nil + } + + unixEndpoint, err := getCrioEndpoint() + if err != nil { + klog.Errorf("failed to get cri-o endpoint, error: %v", err) + return nil, err + } + + CrioHandler, err = handler.NewCrioRuntimeHandler(unixEndpoint) + if err != nil { + klog.Errorf("failed to create cri-o runtime handler, error: %v", err) + return nil, err + } + + return CrioHandler, nil +} + +func getCrioEndpoint() (string, error) { + if crioEndpoint := handler.GetCrioEndpoint(); isFile(crioEndpoint) { + return fmt.Sprintf("unix://%s", crioEndpoint), nil + } + + if crioEndpoint2 := handler.GetCrioEndpoint2(); isFile(crioEndpoint2) { + return fmt.Sprintf("unix://%s", crioEndpoint2), nil + } + + if len(system.Conf.CrioEndPoint) > 0 && isFile(system.Conf.CrioEndPoint) { + klog.Infof("find cri-o Endpoint : %v", system.Conf.CrioEndPoint) + return fmt.Sprintf("unix://%s", system.Conf.CrioEndPoint), nil + } + + return "", fmt.Errorf("cri-o endpoint does not exist") +} + func isFile(path string) bool { s, err := os.Stat(path) if err != nil || s == nil { diff --git a/pkg/koordlet/util/runtime/runtime_test.go b/pkg/koordlet/util/runtime/runtime_test.go index 4e92af885..0e5699469 100644 --- a/pkg/koordlet/util/runtime/runtime_test.go +++ b/pkg/koordlet/util/runtime/runtime_test.go @@ -95,6 +95,20 @@ func Test_GetRuntimeHandler(t *testing.T) { expectRuntimeHandler: "PouchRuntimeHandler", expectErr: false, }, + { + name: "test_/var/run/crio.sock", + endPoint: "/var/run/crio.sock", + runtimeType: "cri-o", + expectRuntimeHandler: "CrioRuntimeHandler", + expectErr: false, + }, + { + name: "test_/var/run/crio/crio.sock", + endPoint: "/var/run/crio/crio.sock", + runtimeType: "cri-o", + expectRuntimeHandler: "CrioRuntimeHandler", + expectErr: false, + }, { name: "custom containerd", endPoint: "/var/run/test1/containerd.sock", @@ -119,6 +133,14 @@ func Test_GetRuntimeHandler(t *testing.T) { expectRuntimeHandler: "PouchRuntimeHandler", expectErr: false, }, + { + name: "custom crio", + endPoint: "/var/run/test4/crio.sock", + flag: "test4/crio.sock", + runtimeType: "cri-o", + expectRuntimeHandler: "CrioRuntimeHandler", + expectErr: false, + }, } for _, tt := range tests { From 02e430ba736a9c716b8dc403141ee10b376c104e Mon Sep 17 00:00:00 2001 From: ocichina001 <165124541+ocichina001@users.noreply.github.com> Date: Wed, 27 Mar 2024 13:22:04 +0800 Subject: [PATCH 05/36] Add files via upload Signed-off-by: ocichina001 <165124541+ocichina001@users.noreply.github.com> Signed-off-by: george --- pkg/koordlet/util/system/cgroup_driver.go | 15 ++++++++++++--- pkg/koordlet/util/system/cgroup_driver_test.go | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/pkg/koordlet/util/system/cgroup_driver.go b/pkg/koordlet/util/system/cgroup_driver.go index c391fdae9..e7eba96b8 100644 --- a/pkg/koordlet/util/system/cgroup_driver.go +++ b/pkg/koordlet/util/system/cgroup_driver.go @@ -50,6 +50,7 @@ const ( RuntimeTypeDocker = "docker" RuntimeTypeContainerd = "containerd" RuntimeTypePouch = "pouch" + RuntimeTypeCrio = "cri-o" RuntimeTypeUnknown = "unknown" ) @@ -106,6 +107,8 @@ var cgroupPathFormatterInSystemd = Formatter{ return RuntimeTypeContainerd, fmt.Sprintf("cri-containerd-%s.scope", hashID[1]), nil case RuntimeTypePouch: return RuntimeTypePouch, fmt.Sprintf("pouch-%s.scope", hashID[1]), nil + case RuntimeTypeCrio: + return RuntimeTypeCrio, fmt.Sprintf("crio-%s.scope", hashID[1]), nil default: return RuntimeTypeUnknown, "", fmt.Errorf("unknown container protocol %s", id) } @@ -123,7 +126,6 @@ var cgroupPathFormatterInSystemd = Formatter{ prefix: "kubepods-burstable-pod", suffix: ".slice", }, - { prefix: "kubepods-pod", suffix: ".slice", @@ -150,12 +152,19 @@ var cgroupPathFormatterInSystemd = Formatter{ prefix: "cri-containerd-", suffix: ".scope", }, + { + prefix: "crio-", + suffix: ".scope", + }, } for i := range patterns { if strings.HasPrefix(basename, patterns[i].prefix) && strings.HasSuffix(basename, patterns[i].suffix) { return basename[len(patterns[i].prefix) : len(basename)-len(patterns[i].suffix)], nil - } + } + } + if strings.HasPrefix(basename, "crio-") { + return basename[len("crio-") : len(basename)], nil } return "", fmt.Errorf("fail to parse container id: %v", basename) }, @@ -182,7 +191,7 @@ var cgroupPathFormatterInCgroupfs = Formatter{ if len(hashID) < 2 { return RuntimeTypeUnknown, "", fmt.Errorf("parse container id %s failed", id) } - if hashID[0] == RuntimeTypeDocker || hashID[0] == RuntimeTypeContainerd || hashID[0] == RuntimeTypePouch { + if hashID[0] == RuntimeTypeDocker || hashID[0] == RuntimeTypeContainerd || hashID[0] == RuntimeTypePouch || hashID[0] == RuntimeTypeCrio { return hashID[0], fmt.Sprintf("%s", hashID[1]), nil } else { return RuntimeTypeUnknown, "", fmt.Errorf("unknown container protocol %s", id) diff --git a/pkg/koordlet/util/system/cgroup_driver_test.go b/pkg/koordlet/util/system/cgroup_driver_test.go index a20e21806..f3d6971f2 100644 --- a/pkg/koordlet/util/system/cgroup_driver_test.go +++ b/pkg/koordlet/util/system/cgroup_driver_test.go @@ -108,6 +108,10 @@ func Test_ParseContainerIDSystemd(t *testing.T) { basename: "cri-containerd-12345.scope", expeceted: "12345", }, + { + basename: "crio-12345.scope", + expeceted: "12345", + }, { basename: "12345", wantError: true, @@ -179,6 +183,13 @@ func Test_SystemdCgroupPathContainerDirFn(t *testing.T) { wantDirName: "pouch-testPouchContainerID.scope", wantError: false, }, + { + name: "cri-o", + containerID: "cri-o://testCrioContainerID", + wantType: RuntimeTypeCrio, + wantDirName: "crio-testCrioContainerID.scope", + wantError: false, + }, { name: "bad-format", containerID: "bad-format-id", @@ -224,6 +235,13 @@ func Test_CgroupfsCgroupPathContainerDirFn(t *testing.T) { wantDirName: "testPouchContainerID", wantError: false, }, + { + name: "cri-o", + containerID: "cri-o://testCrioContainerID", + wantType: RuntimeTypeCrio, + wantDirName: "testCrioContainerID", + wantError: false, + }, { name: "bad-format", containerID: "bad-format-id", From fd3c34a09bbf075c24885907b7caf55f1aa8012c Mon Sep 17 00:00:00 2001 From: ocichina001 <165124541+ocichina001@users.noreply.github.com> Date: Wed, 27 Mar 2024 13:25:17 +0800 Subject: [PATCH 06/36] Update Makefile Signed-off-by: ocichina001 <165124541+ocichina001@users.noreply.github.com> Signed-off-by: george --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index efee1fec2..08c203b79 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ GIT_COMMIT_ID ?= $(shell git rev-parse --short HEAD) # Image URL to use all building/pushing image targets REG ?= ghcr.io -REG_NS ?= koordinator-sh +REG_NS ?= ocichina REG_USER ?= "" REG_PWD ?= "" @@ -15,7 +15,7 @@ KOORD_SCHEDULER_IMG ?= "${REG}/${REG_NS}/koord-scheduler:${GIT_BRANCH}-${GIT_COM KOORD_DESCHEDULER_IMG ?= "${REG}/${REG_NS}/koord-descheduler:${GIT_BRANCH}-${GIT_COMMIT_ID}" # ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. -ENVTEST_K8S_VERSION = 1.22 +ENVTEST_K8S_VERSION = 1.28 AGENT_MODE ?= hostMode # Set license header files. From 0574594604b8583b4c12796fd2d16ad2182f1636 Mon Sep 17 00:00:00 2001 From: ocichina001 <165124541+ocichina001@users.noreply.github.com> Date: Wed, 27 Mar 2024 17:56:27 +0800 Subject: [PATCH 07/36] Update pod.go Signed-off-by: ocichina001 <165124541+ocichina001@users.noreply.github.com> Signed-off-by: george --- pkg/koordlet/util/pod.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/koordlet/util/pod.go b/pkg/koordlet/util/pod.go index fc7343b14..6b16ddc44 100644 --- a/pkg/koordlet/util/pod.go +++ b/pkg/koordlet/util/pod.go @@ -79,7 +79,9 @@ func GetPodSandboxContainerID(pod *corev1.Pod) (string, error) { continue } if _, exist := containerSubDirNames[containerDir.Name()]; !exist { - sandboxCandidates = append(sandboxCandidates, containerDir.Name()) + if containerDir.Name().HasSuffix(".scope") { + sandboxCandidates = append(sandboxCandidates, containerDir.Name()) + } } } From 4f18730a8fee9bfe0a65a267d664dfa3286ee7df Mon Sep 17 00:00:00 2001 From: ocichina001 <165124541+ocichina001@users.noreply.github.com> Date: Wed, 27 Mar 2024 18:02:27 +0800 Subject: [PATCH 08/36] Update pod.go Signed-off-by: ocichina001 <165124541+ocichina001@users.noreply.github.com> Signed-off-by: george --- pkg/koordlet/util/pod.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pkg/koordlet/util/pod.go b/pkg/koordlet/util/pod.go index 6b16ddc44..4a87b6c87 100644 --- a/pkg/koordlet/util/pod.go +++ b/pkg/koordlet/util/pod.go @@ -78,9 +78,10 @@ func GetPodSandboxContainerID(pod *corev1.Pod) (string, error) { if !containerDir.IsDir() { continue } - if _, exist := containerSubDirNames[containerDir.Name()]; !exist { - if containerDir.Name().HasSuffix(".scope") { - sandboxCandidates = append(sandboxCandidates, containerDir.Name()) + containerDirName = containerDir.Name() + if _, exist := containerSubDirNames[containerDirName]; !exist { + if containerDirName.HasSuffix(".scope") { + sandboxCandidates = append(sandboxCandidates, containerDirName) } } } From c99a6a60ba8e3555d467ef779d749ac6cb1730b7 Mon Sep 17 00:00:00 2001 From: ocichina001 <165124541+ocichina001@users.noreply.github.com> Date: Wed, 27 Mar 2024 18:04:56 +0800 Subject: [PATCH 09/36] Update pod.go Signed-off-by: ocichina001 <165124541+ocichina001@users.noreply.github.com> Signed-off-by: george --- pkg/koordlet/util/pod.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/koordlet/util/pod.go b/pkg/koordlet/util/pod.go index 4a87b6c87..c48d91905 100644 --- a/pkg/koordlet/util/pod.go +++ b/pkg/koordlet/util/pod.go @@ -78,7 +78,7 @@ func GetPodSandboxContainerID(pod *corev1.Pod) (string, error) { if !containerDir.IsDir() { continue } - containerDirName = containerDir.Name() + var containerDirName = containerDir.Name() if _, exist := containerSubDirNames[containerDirName]; !exist { if containerDirName.HasSuffix(".scope") { sandboxCandidates = append(sandboxCandidates, containerDirName) From 6cb5f9bdf3913e5bf562d3d03814582598be6b73 Mon Sep 17 00:00:00 2001 From: ocichina001 <165124541+ocichina001@users.noreply.github.com> Date: Wed, 27 Mar 2024 18:07:04 +0800 Subject: [PATCH 10/36] Update pod.go Signed-off-by: ocichina001 <165124541+ocichina001@users.noreply.github.com> Signed-off-by: george --- pkg/koordlet/util/pod.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/koordlet/util/pod.go b/pkg/koordlet/util/pod.go index c48d91905..48d79ae7f 100644 --- a/pkg/koordlet/util/pod.go +++ b/pkg/koordlet/util/pod.go @@ -20,6 +20,7 @@ import ( "fmt" "os" "path/filepath" + "strings" corev1 "k8s.io/api/core/v1" @@ -80,7 +81,7 @@ func GetPodSandboxContainerID(pod *corev1.Pod) (string, error) { } var containerDirName = containerDir.Name() if _, exist := containerSubDirNames[containerDirName]; !exist { - if containerDirName.HasSuffix(".scope") { + if strings.HasSuffix(containerDirName,".scope") { sandboxCandidates = append(sandboxCandidates, containerDirName) } } From 86a63031269d09967b35e6920672b2dda1e86655 Mon Sep 17 00:00:00 2001 From: ocichina001 <165124541+ocichina001@users.noreply.github.com> Date: Wed, 27 Mar 2024 19:32:03 +0800 Subject: [PATCH 11/36] Update pod.go Signed-off-by: ocichina001 <165124541+ocichina001@users.noreply.github.com> Signed-off-by: george --- pkg/koordlet/util/pod.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/pkg/koordlet/util/pod.go b/pkg/koordlet/util/pod.go index 48d79ae7f..b70b35c30 100644 --- a/pkg/koordlet/util/pod.go +++ b/pkg/koordlet/util/pod.go @@ -79,11 +79,15 @@ func GetPodSandboxContainerID(pod *corev1.Pod) (string, error) { if !containerDir.IsDir() { continue } - var containerDirName = containerDir.Name() - if _, exist := containerSubDirNames[containerDirName]; !exist { - if strings.HasSuffix(containerDirName,".scope") { - sandboxCandidates = append(sandboxCandidates, containerDirName) - } + if _, exist := containerSubDirNames[containerDir.Name()]; !exist { + fmt.Sprintf("************Container Sub Dir Name is %s\n",containerDir.Name()) + if strings.HasPrefix(containerDir.Name(), "crio-") { + if strings.HasSuffix(containerDir.Name(), ".scope") { + sandboxCandidates = append(sandboxCandidates, containerDir.Name()) + } + }else { + sandboxCandidates = append(sandboxCandidates, containerDir.Name()) + } } } From 28557682c0b18811f37f9d8db1792f15bd640b06 Mon Sep 17 00:00:00 2001 From: ocichina001 <165124541+ocichina001@users.noreply.github.com> Date: Wed, 27 Mar 2024 19:52:20 +0800 Subject: [PATCH 12/36] Update pod.go Signed-off-by: ocichina001 <165124541+ocichina001@users.noreply.github.com> Signed-off-by: george --- pkg/koordlet/util/pod.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/koordlet/util/pod.go b/pkg/koordlet/util/pod.go index b70b35c30..f0836083c 100644 --- a/pkg/koordlet/util/pod.go +++ b/pkg/koordlet/util/pod.go @@ -80,7 +80,7 @@ func GetPodSandboxContainerID(pod *corev1.Pod) (string, error) { continue } if _, exist := containerSubDirNames[containerDir.Name()]; !exist { - fmt.Sprintf("************Container Sub Dir Name is %s\n",containerDir.Name()) + log.Printf("************Container Sub Dir Name is %s\n",containerDir.Name()) if strings.HasPrefix(containerDir.Name(), "crio-") { if strings.HasSuffix(containerDir.Name(), ".scope") { sandboxCandidates = append(sandboxCandidates, containerDir.Name()) From 4ee8a95a578b505be8aac2b12bb8e9e622088f8c Mon Sep 17 00:00:00 2001 From: ocichina001 <165124541+ocichina001@users.noreply.github.com> Date: Wed, 27 Mar 2024 19:53:34 +0800 Subject: [PATCH 13/36] Update pod.go Signed-off-by: ocichina001 <165124541+ocichina001@users.noreply.github.com> Signed-off-by: george --- pkg/koordlet/util/pod.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/koordlet/util/pod.go b/pkg/koordlet/util/pod.go index f0836083c..c46faec1e 100644 --- a/pkg/koordlet/util/pod.go +++ b/pkg/koordlet/util/pod.go @@ -80,7 +80,7 @@ func GetPodSandboxContainerID(pod *corev1.Pod) (string, error) { continue } if _, exist := containerSubDirNames[containerDir.Name()]; !exist { - log.Printf("************Container Sub Dir Name is %s\n",containerDir.Name()) + fmt.Errorf("************Container Sub Dir Name is %v\n",containerDir.Name()) if strings.HasPrefix(containerDir.Name(), "crio-") { if strings.HasSuffix(containerDir.Name(), ".scope") { sandboxCandidates = append(sandboxCandidates, containerDir.Name()) From 6b28f831b1f773659a5e7ff2eba5799e6e824845 Mon Sep 17 00:00:00 2001 From: ocichina001 <165124541+ocichina001@users.noreply.github.com> Date: Wed, 27 Mar 2024 20:03:40 +0800 Subject: [PATCH 14/36] Update pod.go Signed-off-by: ocichina001 <165124541+ocichina001@users.noreply.github.com> Signed-off-by: george --- pkg/koordlet/util/pod.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/koordlet/util/pod.go b/pkg/koordlet/util/pod.go index c46faec1e..58f9ffe2f 100644 --- a/pkg/koordlet/util/pod.go +++ b/pkg/koordlet/util/pod.go @@ -80,7 +80,7 @@ func GetPodSandboxContainerID(pod *corev1.Pod) (string, error) { continue } if _, exist := containerSubDirNames[containerDir.Name()]; !exist { - fmt.Errorf("************Container Sub Dir Name is %v\n",containerDir.Name()) + klog.V(4).Infof("************Container Sub Dir Name is %v\n",containerDir.Name()) if strings.HasPrefix(containerDir.Name(), "crio-") { if strings.HasSuffix(containerDir.Name(), ".scope") { sandboxCandidates = append(sandboxCandidates, containerDir.Name()) From 67eacc3fe7d5d13bead7d4de9369f0bfcec6c60e Mon Sep 17 00:00:00 2001 From: ocichina001 <165124541+ocichina001@users.noreply.github.com> Date: Wed, 27 Mar 2024 20:05:03 +0800 Subject: [PATCH 15/36] Update pod.go Signed-off-by: ocichina001 <165124541+ocichina001@users.noreply.github.com> Signed-off-by: george --- pkg/koordlet/util/pod.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/koordlet/util/pod.go b/pkg/koordlet/util/pod.go index 58f9ffe2f..8f059a010 100644 --- a/pkg/koordlet/util/pod.go +++ b/pkg/koordlet/util/pod.go @@ -21,8 +21,10 @@ import ( "os" "path/filepath" "strings" + "k8s.io/klog/v2" corev1 "k8s.io/api/core/v1" + "github.com/koordinator-sh/koordinator/pkg/koordlet/util/system" ) From 3993903975eab2062e9d4af749cf3e2ebf1811a4 Mon Sep 17 00:00:00 2001 From: ocichina001 <165124541+ocichina001@users.noreply.github.com> Date: Wed, 27 Mar 2024 20:19:31 +0800 Subject: [PATCH 16/36] Update pod.go Signed-off-by: ocichina001 <165124541+ocichina001@users.noreply.github.com> Signed-off-by: george --- pkg/koordlet/util/pod.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/koordlet/util/pod.go b/pkg/koordlet/util/pod.go index 8f059a010..7a62c0a37 100644 --- a/pkg/koordlet/util/pod.go +++ b/pkg/koordlet/util/pod.go @@ -54,6 +54,7 @@ func GetPodSandboxContainerID(pod *corev1.Pod) (string, error) { cpuSetCgroupRootDir := system.GetRootCgroupSubfsDir(system.CgroupCPUSetDir) podCgroupDir := GetPodCgroupParentDir(pod) podCPUSetCgroupRootDir := filepath.Join(cpuSetCgroupRootDir, podCgroupDir) + klog.V(4).Infof("************podCPUSetCgroupRootDir is %v\n",podCPUSetCgroupRootDir()) if len(pod.Status.ContainerStatuses) <= 0 { // container not created, skip until container is created because container runtime is unknown @@ -70,6 +71,8 @@ func GetPodSandboxContainerID(pod *corev1.Pod) (string, error) { } containerSubDirNames[containerDirName] = struct{}{} containerRuntime = runtimeType + klog.V(4).Infof("************containerSubDirNames is %v\n",containerSubDirNames[]) + klog.V(4).Infof("************containerRuntime is %v\n",containerRuntime) } sandboxCandidates := make([]string, 0) From e8f7e7cb37b62a0f7d76ea87102c35cd9025f876 Mon Sep 17 00:00:00 2001 From: ocichina001 <165124541+ocichina001@users.noreply.github.com> Date: Wed, 27 Mar 2024 20:20:21 +0800 Subject: [PATCH 17/36] Update pod.go Signed-off-by: ocichina001 <165124541+ocichina001@users.noreply.github.com> Signed-off-by: george --- pkg/koordlet/util/pod.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/koordlet/util/pod.go b/pkg/koordlet/util/pod.go index 7a62c0a37..c27e6d183 100644 --- a/pkg/koordlet/util/pod.go +++ b/pkg/koordlet/util/pod.go @@ -71,7 +71,7 @@ func GetPodSandboxContainerID(pod *corev1.Pod) (string, error) { } containerSubDirNames[containerDirName] = struct{}{} containerRuntime = runtimeType - klog.V(4).Infof("************containerSubDirNames is %v\n",containerSubDirNames[]) + klog.V(4).Infof("************containerSubDirNames is %v\n",containerSubDirNames) klog.V(4).Infof("************containerRuntime is %v\n",containerRuntime) } From 9923a3de53bb82786749cb06cefee42e6de7b380 Mon Sep 17 00:00:00 2001 From: ocichina001 <165124541+ocichina001@users.noreply.github.com> Date: Wed, 27 Mar 2024 20:21:03 +0800 Subject: [PATCH 18/36] Update pod.go Signed-off-by: ocichina001 <165124541+ocichina001@users.noreply.github.com> Signed-off-by: george --- pkg/koordlet/util/pod.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/koordlet/util/pod.go b/pkg/koordlet/util/pod.go index c27e6d183..00fc7112d 100644 --- a/pkg/koordlet/util/pod.go +++ b/pkg/koordlet/util/pod.go @@ -54,7 +54,7 @@ func GetPodSandboxContainerID(pod *corev1.Pod) (string, error) { cpuSetCgroupRootDir := system.GetRootCgroupSubfsDir(system.CgroupCPUSetDir) podCgroupDir := GetPodCgroupParentDir(pod) podCPUSetCgroupRootDir := filepath.Join(cpuSetCgroupRootDir, podCgroupDir) - klog.V(4).Infof("************podCPUSetCgroupRootDir is %v\n",podCPUSetCgroupRootDir()) + klog.V(4).Infof("************podCPUSetCgroupRootDir is %v\n",podCPUSetCgroupRootDir) if len(pod.Status.ContainerStatuses) <= 0 { // container not created, skip until container is created because container runtime is unknown From c8a3002076dda3c6b6130f90838db393fa892ddf Mon Sep 17 00:00:00 2001 From: ocichina Date: Wed, 27 Mar 2024 16:44:49 +0000 Subject: [PATCH 19/36] update pod.go Signed-off-by: george --- pkg/koordlet/util/pod.go | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/pkg/koordlet/util/pod.go b/pkg/koordlet/util/pod.go index 00fc7112d..182ae3137 100644 --- a/pkg/koordlet/util/pod.go +++ b/pkg/koordlet/util/pod.go @@ -21,10 +21,8 @@ import ( "os" "path/filepath" "strings" - "k8s.io/klog/v2" corev1 "k8s.io/api/core/v1" - "github.com/koordinator-sh/koordinator/pkg/koordlet/util/system" ) @@ -54,7 +52,6 @@ func GetPodSandboxContainerID(pod *corev1.Pod) (string, error) { cpuSetCgroupRootDir := system.GetRootCgroupSubfsDir(system.CgroupCPUSetDir) podCgroupDir := GetPodCgroupParentDir(pod) podCPUSetCgroupRootDir := filepath.Join(cpuSetCgroupRootDir, podCgroupDir) - klog.V(4).Infof("************podCPUSetCgroupRootDir is %v\n",podCPUSetCgroupRootDir) if len(pod.Status.ContainerStatuses) <= 0 { // container not created, skip until container is created because container runtime is unknown @@ -71,8 +68,6 @@ func GetPodSandboxContainerID(pod *corev1.Pod) (string, error) { } containerSubDirNames[containerDirName] = struct{}{} containerRuntime = runtimeType - klog.V(4).Infof("************containerSubDirNames is %v\n",containerSubDirNames) - klog.V(4).Infof("************containerRuntime is %v\n",containerRuntime) } sandboxCandidates := make([]string, 0) @@ -85,11 +80,10 @@ func GetPodSandboxContainerID(pod *corev1.Pod) (string, error) { continue } if _, exist := containerSubDirNames[containerDir.Name()]; !exist { - klog.V(4).Infof("************Container Sub Dir Name is %v\n",containerDir.Name()) if strings.HasPrefix(containerDir.Name(), "crio-") { - if strings.HasSuffix(containerDir.Name(), ".scope") { + if ! strings.HasSuffix(containerDir.Name(), ".scope") { sandboxCandidates = append(sandboxCandidates, containerDir.Name()) - } + } }else { sandboxCandidates = append(sandboxCandidates, containerDir.Name()) } From 3ed8b5e254ebb143e7d0fc04588188050b6f599b Mon Sep 17 00:00:00 2001 From: Frame Date: Fri, 29 Mar 2024 12:02:23 +0800 Subject: [PATCH 20/36] koordlet: record invoke metrics for runtime hook (#1961) Signed-off-by: saintube Signed-off-by: george --- pkg/koordlet/metrics/internal_metrics.go | 1 + pkg/koordlet/metrics/metrics_test.go | 32 +++++++ pkg/koordlet/metrics/runtime_hook.go | 83 +++++++++++++++++++ pkg/koordlet/runtimehooks/hooks/hooks.go | 7 +- .../runtimehooks/reconciler/reconciler.go | 25 ++++-- 5 files changed, 141 insertions(+), 7 deletions(-) create mode 100644 pkg/koordlet/metrics/runtime_hook.go diff --git a/pkg/koordlet/metrics/internal_metrics.go b/pkg/koordlet/metrics/internal_metrics.go index b049ed337..d34393f81 100644 --- a/pkg/koordlet/metrics/internal_metrics.go +++ b/pkg/koordlet/metrics/internal_metrics.go @@ -43,4 +43,5 @@ func init() { internalMustRegister(CoreSchedCollector...) internalMustRegister(ResourceExecutorCollector...) internalMustRegister(KubeletStubCollector...) + internalMustRegister(RuntimeHookCollectors...) } diff --git a/pkg/koordlet/metrics/metrics_test.go b/pkg/koordlet/metrics/metrics_test.go index 998ea477a..531f1d77b 100644 --- a/pkg/koordlet/metrics/metrics_test.go +++ b/pkg/koordlet/metrics/metrics_test.go @@ -380,3 +380,35 @@ func TestCoreSchedCollector(t *testing.T) { testCoreSchedGroup, testCoreSchedCookie) }) } + +func TestRuntimeHookCollector(t *testing.T) { + testingNode := &corev1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-node", + Labels: map[string]string{}, + }, + Status: corev1.NodeStatus{ + Allocatable: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("100"), + corev1.ResourceMemory: resource.MustParse("200Gi"), + apiext.BatchCPU: resource.MustParse("50000"), + apiext.BatchMemory: resource.MustParse("80Gi"), + }, + Capacity: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("100"), + corev1.ResourceMemory: resource.MustParse("200Gi"), + apiext.BatchCPU: resource.MustParse("50000"), + apiext.BatchMemory: resource.MustParse("80Gi"), + }, + }, + } + testErr := fmt.Errorf("expected error") + t.Run("test", func(t *testing.T) { + Register(testingNode) + defer Register(nil) + RecordRuntimeHookInvokedDurationMilliSeconds("testHook", "testStage", nil, 10.0) + RecordRuntimeHookInvokedDurationMilliSeconds("testHook", "testStage", testErr, 5.0) + RecordRuntimeHookReconcilerInvokedDurationMilliSeconds("pod", "cpu.cfs_quota_us", nil, 10.0) + RecordRuntimeHookReconcilerInvokedDurationMilliSeconds("pod", "cpu.cfs_quota_us", testErr, 5.0) + }) +} diff --git a/pkg/koordlet/metrics/runtime_hook.go b/pkg/koordlet/metrics/runtime_hook.go new file mode 100644 index 000000000..5f4b76c90 --- /dev/null +++ b/pkg/koordlet/metrics/runtime_hook.go @@ -0,0 +1,83 @@ +/* +Copyright 2022 The Koordinator 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 metrics + +import "github.com/prometheus/client_golang/prometheus" + +const ( + // RuntimeHookName represents the hook plugin name of runtime hook. + RuntimeHookName = "hook" + // RuntimeHookStage represents the stage of invoked runtime hook. + RuntimeHookStage = "stage" + // RuntimeHookReconcilerLevel represents the level (e.g. pod-level) of invoked runtime hook reconciler. + RuntimeHookReconcilerLevel = "level" + // RuntimeHookReconcilerResourceType represents the resource type (e.g. cpu.cfs_quota_us) of invoked runtime hook reconciler. + RuntimeHookReconcilerResourceType = "resource_type" +) + +var ( + runtimeHookInvokedDurationMilliSeconds = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Subsystem: KoordletSubsystem, + Name: "runtime_hook_invoked_duration_milliseconds", + Help: "time duration of invocations of runtime hook plugins", + // 10us ~ 10.24ms, cgroup <= 40us + Buckets: prometheus.ExponentialBuckets(0.01, 4, 8), + }, []string{NodeKey, RuntimeHookName, RuntimeHookStage, StatusKey}) + + runtimeHookReconcilerInvokedDurationMilliSeconds = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Subsystem: KoordletSubsystem, + Name: "runtime_hook_reconciler_invoked_duration_milliseconds", + Help: "time duration of invocations of runtime hook reconciler plugins", + // 10us ~ 10.24ms, cgroup <= 40us + Buckets: prometheus.ExponentialBuckets(0.01, 4, 8), + }, []string{NodeKey, RuntimeHookReconcilerLevel, RuntimeHookReconcilerResourceType, StatusKey}) + + RuntimeHookCollectors = []prometheus.Collector{ + runtimeHookInvokedDurationMilliSeconds, + runtimeHookReconcilerInvokedDurationMilliSeconds, + } +) + +func RecordRuntimeHookInvokedDurationMilliSeconds(hookName, stage string, err error, seconds float64) { + labels := genNodeLabels() + if labels == nil { + return + } + labels[RuntimeHookName] = hookName + labels[RuntimeHookStage] = stage + labels[StatusKey] = StatusSucceed + if err != nil { + labels[StatusKey] = StatusFailed + } + // convert seconds to milliseconds + runtimeHookInvokedDurationMilliSeconds.With(labels).Observe(seconds * 1000) +} + +func RecordRuntimeHookReconcilerInvokedDurationMilliSeconds(level, resourceType string, err error, seconds float64) { + labels := genNodeLabels() + if labels == nil { + return + } + labels[RuntimeHookReconcilerLevel] = level + labels[RuntimeHookReconcilerResourceType] = resourceType + labels[StatusKey] = StatusSucceed + if err != nil { + labels[StatusKey] = StatusFailed + } + // convert seconds to milliseconds + runtimeHookReconcilerInvokedDurationMilliSeconds.With(labels).Observe(seconds * 1000) +} diff --git a/pkg/koordlet/runtimehooks/hooks/hooks.go b/pkg/koordlet/runtimehooks/hooks/hooks.go index ef7613d07..c1ca3e350 100644 --- a/pkg/koordlet/runtimehooks/hooks/hooks.go +++ b/pkg/koordlet/runtimehooks/hooks/hooks.go @@ -18,9 +18,11 @@ package hooks import ( "fmt" + "time" "k8s.io/klog/v2" + "github.com/koordinator-sh/koordinator/pkg/koordlet/metrics" "github.com/koordinator-sh/koordinator/pkg/koordlet/resourceexecutor" "github.com/koordinator-sh/koordinator/pkg/koordlet/runtimehooks/protocol" rmconfig "github.com/koordinator-sh/koordinator/pkg/runtimeproxy/config" @@ -81,8 +83,11 @@ func RunHooks(failPolicy rmconfig.FailurePolicyType, stage rmconfig.RuntimeHookT hooks := getHooksByStage(stage) klog.V(5).Infof("start run %v hooks at %s", len(hooks), stage) for _, hook := range hooks { + start := time.Now() klog.V(5).Infof("call hook %v", hook.name) - if err := hook.fn(protocol); err != nil { + err := hook.fn(protocol) + metrics.RecordRuntimeHookInvokedDurationMilliSeconds(hook.name, string(stage), err, metrics.SinceInSeconds(start)) + if err != nil { klog.Errorf("failed to run hook %s in stage %s, reason: %v", hook.name, stage, err) if failPolicy == rmconfig.PolicyFail { return err diff --git a/pkg/koordlet/runtimehooks/reconciler/reconciler.go b/pkg/koordlet/runtimehooks/reconciler/reconciler.go index cef2f8656..7f38153e8 100644 --- a/pkg/koordlet/runtimehooks/reconciler/reconciler.go +++ b/pkg/koordlet/runtimehooks/reconciler/reconciler.go @@ -24,6 +24,7 @@ import ( "k8s.io/klog/v2" apiext "github.com/koordinator-sh/koordinator/apis/extension" + "github.com/koordinator-sh/koordinator/pkg/koordlet/metrics" "github.com/koordinator-sh/koordinator/pkg/koordlet/resourceexecutor" "github.com/koordinator-sh/koordinator/pkg/koordlet/runtimehooks/protocol" "github.com/koordinator-sh/koordinator/pkg/koordlet/statesinformer" @@ -91,7 +92,7 @@ func (d *noneFilter) Filter(podMeta *statesinformer.PodMeta) string { var singletonNoneFilter *noneFilter // NoneFilter returns a Filter which skip filtering anything (into the same condition) -func NoneFilter() *noneFilter { +func NoneFilter() Filter { if singletonNoneFilter == nil { singletonNoneFilter = &noneFilter{} } @@ -125,7 +126,7 @@ func (p *podQOSFilter) Filter(podMeta *statesinformer.PodMeta) string { var singletonPodQOSFilter *podQOSFilter // PodQOSFilter returns a Filter which filters pod qos class -func PodQOSFilter() *podQOSFilter { +func PodQOSFilter() Filter { if singletonPodQOSFilter == nil { singletonPodQOSFilter = &podQOSFilter{} } @@ -286,7 +287,7 @@ func (c *reconciler) reconcileKubeQOSCgroup(stopCh <-chan struct{}) { func doKubeQOSCgroup(e resourceexecutor.ResourceUpdateExecutor) { for _, kubeQOS := range []corev1.PodQOSClass{ corev1.PodQOSGuaranteed, corev1.PodQOSBurstable, corev1.PodQOSBestEffort} { - for _, r := range globalCgroupReconcilers.kubeQOSLevel { + for resourceType, r := range globalCgroupReconcilers.kubeQOSLevel { kubeQOSCtx := protocol.HooksProtocolBuilder.KubeQOS(kubeQOS) reconcileFn, ok := r.fn[NoneFilterCondition] if !ok { // all kube qos reconcilers should register in this condition @@ -294,11 +295,14 @@ func doKubeQOSCgroup(e resourceexecutor.ResourceUpdateExecutor) { r.description, NoneFilterCondition) continue } + start := time.Now() if err := reconcileFn(kubeQOSCtx); err != nil { + metrics.RecordRuntimeHookReconcilerInvokedDurationMilliSeconds(string(KubeQOSLevel), resourceType, err, metrics.SinceInSeconds(start)) klog.Warningf("calling reconcile function %v for kube qos %v failed, error %v", r.description, kubeQOS, err) } else { kubeQOSCtx.ReconcilerDone(e) + metrics.RecordRuntimeHookReconcilerInvokedDurationMilliSeconds(string(KubeQOSLevel), resourceType, nil, metrics.SinceInSeconds(start)) klog.V(5).Infof("calling reconcile function %v for kube qos %v finish", r.description, kubeQOS) } @@ -314,7 +318,7 @@ func (c *reconciler) reconcilePodCgroup(stopCh <-chan struct{}) { case <-c.podUpdated: podsMeta := c.getPodsMeta() for _, podMeta := range podsMeta { - for _, r := range globalCgroupReconcilers.podLevel { + for resourceType, r := range globalCgroupReconcilers.podLevel { reconcileFn, ok := r.fn[r.filter.Filter(podMeta)] if !ok { klog.V(5).Infof("calling reconcile function %v aborted for pod %v, condition %s not registered", @@ -323,17 +327,20 @@ func (c *reconciler) reconcilePodCgroup(stopCh <-chan struct{}) { } podCtx := protocol.HooksProtocolBuilder.Pod(podMeta) + start := time.Now() if err := reconcileFn(podCtx); err != nil { + metrics.RecordRuntimeHookReconcilerInvokedDurationMilliSeconds(string(PodLevel), resourceType, err, metrics.SinceInSeconds(start)) klog.Warningf("calling reconcile function %v for pod %v failed, error %v", r.description, podMeta.Key(), err) } else { podCtx.ReconcilerDone(c.executor) + metrics.RecordRuntimeHookReconcilerInvokedDurationMilliSeconds(string(PodLevel), resourceType, nil, metrics.SinceInSeconds(start)) klog.V(5).Infof("calling reconcile function %v for pod %v finished", r.description, podMeta.Key()) } } - for _, r := range globalCgroupReconcilers.sandboxContainerLevel { + for resourceType, r := range globalCgroupReconcilers.sandboxContainerLevel { reconcileFn, ok := r.fn[r.filter.Filter(podMeta)] if !ok { klog.V(5).Infof("calling reconcile function %v aborted for pod %v, condition %s not registered", @@ -341,18 +348,21 @@ func (c *reconciler) reconcilePodCgroup(stopCh <-chan struct{}) { continue } sandboxContainerCtx := protocol.HooksProtocolBuilder.Sandbox(podMeta) + start := time.Now() if err := reconcileFn(sandboxContainerCtx); err != nil { + metrics.RecordRuntimeHookReconcilerInvokedDurationMilliSeconds(string(SandboxLevel), resourceType, err, metrics.SinceInSeconds(start)) klog.Warningf("calling reconcile function %v failed for sandbox %v, error %v", r.description, podMeta.Key(), err) } else { sandboxContainerCtx.ReconcilerDone(c.executor) + metrics.RecordRuntimeHookReconcilerInvokedDurationMilliSeconds(string(SandboxLevel), resourceType, nil, metrics.SinceInSeconds(start)) klog.V(5).Infof("calling reconcile function %v for pod sandbox %v finished", r.description, podMeta.Key()) } } for _, containerStat := range podMeta.Pod.Status.ContainerStatuses { - for _, r := range globalCgroupReconcilers.containerLevel { + for resourceType, r := range globalCgroupReconcilers.containerLevel { reconcileFn, ok := r.fn[r.filter.Filter(podMeta)] if !ok { klog.V(5).Infof("calling reconcile function %v aborted for container %v/%v, condition %s not registered", @@ -361,11 +371,14 @@ func (c *reconciler) reconcilePodCgroup(stopCh <-chan struct{}) { } containerCtx := protocol.HooksProtocolBuilder.Container(podMeta, containerStat.Name) + start := time.Now() if err := reconcileFn(containerCtx); err != nil { + metrics.RecordRuntimeHookReconcilerInvokedDurationMilliSeconds(string(ContainerLevel), resourceType, err, metrics.SinceInSeconds(start)) klog.Warningf("calling reconcile function %v for container %v/%v failed, error %v", r.description, podMeta.Key(), containerStat.Name, err) } else { containerCtx.ReconcilerDone(c.executor) + metrics.RecordRuntimeHookReconcilerInvokedDurationMilliSeconds(string(ContainerLevel), resourceType, nil, metrics.SinceInSeconds(start)) klog.V(5).Infof("calling reconcile function %v for container %v/%v finish", r.description, podMeta.Key(), containerStat.Name) } From b8626d8e4b79d601299da8b605863f06d9dc1005 Mon Sep 17 00:00:00 2001 From: wangjianyu Date: Fri, 29 Mar 2024 14:50:23 +0800 Subject: [PATCH 21/36] scheduler: optimize QueueSort func when Gang and Barepod Coexists (#1977) Signed-off-by: wangjianyu.wjy Co-authored-by: wangjianyu.wjy Signed-off-by: george --- .../plugins/coscheduling/core/core.go | 17 +++++++ .../plugins/coscheduling/coscheduling.go | 41 +++++++++-------- .../plugins/coscheduling/coscheduling_test.go | 46 +++++++++---------- 3 files changed, 61 insertions(+), 43 deletions(-) diff --git a/pkg/scheduler/plugins/coscheduling/core/core.go b/pkg/scheduler/plugins/coscheduling/core/core.go index b114ed4f1..c0f2a11d5 100644 --- a/pkg/scheduler/plugins/coscheduling/core/core.go +++ b/pkg/scheduler/plugins/coscheduling/core/core.go @@ -73,6 +73,7 @@ type Manager interface { GetGangSummaries() map[string]*GangSummary IsGangMinSatisfied(*corev1.Pod) bool GetChildScheduleCycle(*corev1.Pod) int + GetGangGroupWaitingBoundPodNum(pod *corev1.Pod) int } // PodGroupManager defines the scheduling operation called @@ -552,3 +553,19 @@ func (pgMgr *PodGroupManager) GetChildScheduleCycle(pod *corev1.Pod) int { return gang.getChildScheduleCycle(pod) } + +func (pgMgr *PodGroupManager) GetGangGroupWaitingBoundPodNum(pod *corev1.Pod) int { + gang := pgMgr.GetGangByPod(pod) + if gang == nil { + return 0 + } + gangGroup := gang.GangGroup + waitingPodNum := 0 + for _, memberGangID := range gangGroup { + memberGang := pgMgr.cache.getGangFromCacheByGangId(memberGangID, false) + if memberGang != nil { + waitingPodNum += memberGang.getGangWaitingPods() + } + } + return waitingPodNum +} diff --git a/pkg/scheduler/plugins/coscheduling/coscheduling.go b/pkg/scheduler/plugins/coscheduling/coscheduling.go index 7b29f066b..f59a12eb8 100644 --- a/pkg/scheduler/plugins/coscheduling/coscheduling.go +++ b/pkg/scheduler/plugins/coscheduling/coscheduling.go @@ -135,28 +135,29 @@ func (cs *Coscheduling) Less(podInfo1, podInfo2 *framework.QueuedPodInfo) bool { group1, _ := cs.pgMgr.GetGroupId(podInfo1.Pod) group2, _ := cs.pgMgr.GetGroupId(podInfo2.Pod) - if group1 != group2 { - return group1 < group2 - } - - isgang1satisfied := cs.pgMgr.IsGangMinSatisfied(podInfo1.Pod) - isgang2satisfied := cs.pgMgr.IsGangMinSatisfied(podInfo2.Pod) - if isgang1satisfied != isgang2satisfied { - return !isgang1satisfied - } - childScheduleCycle1 := cs.pgMgr.GetChildScheduleCycle(podInfo1.Pod) - childScheduleCycle2 := cs.pgMgr.GetChildScheduleCycle(podInfo2.Pod) - if childScheduleCycle1 != childScheduleCycle2 { - return childScheduleCycle1 < childScheduleCycle2 - } - - creationTime1 := cs.pgMgr.GetCreatTime(podInfo1) - creationTime2 := cs.pgMgr.GetCreatTime(podInfo2) - if creationTime1.Equal(creationTime2) { - return util.GetId(podInfo1.Pod.Namespace, podInfo1.Pod.Name) < util.GetId(podInfo2.Pod.Namespace, podInfo2.Pod.Name) + waitingBoundPodNum1 := cs.pgMgr.GetGangGroupWaitingBoundPodNum(podInfo1.Pod) + waitingBoundPodNum2 := cs.pgMgr.GetGangGroupWaitingBoundPodNum(podInfo2.Pod) + if waitingBoundPodNum1 != 0 || waitingBoundPodNum2 != 0 { + // At the same time, only member pod of one podGroup should be assumed, so we prefer the pod already having sibling assumed, then they can succeed together. + if waitingBoundPodNum1 == 0 || waitingBoundPodNum2 == 0 { + return waitingBoundPodNum1 != 0 + } + /* + Two gang groups may both already have some assumed sibling pods. + For example: + 1. GroupA has submitted 6 member, and have 5 already assumed; + 2. then the sixth has been deleted; + 3. then GroupB submitted its pods and have 3 already assumed; + 4. GroupA submit the sixth pod + In this case, waitingPodNum will make no sense, so just sort it by group id to give fixed order. + Because no matter former succeed or fail, it's waitingPodNum will be zeroed. And the deadlock will be avoided + */ + return group1 < group2 } - return creationTime1.Before(creationTime2) + // If no pod succeed, we will schedule all pod by RoundRobin to assure fairness. + // If some time-consuming member pod of one gang failed, then it's sibling will fail soon(because scheduling cycle invalid), so no need to assure all sibling should fail together. + return podInfo1.Timestamp.Before(podInfo2.Timestamp) } // PreFilter diff --git a/pkg/scheduler/plugins/coscheduling/coscheduling_test.go b/pkg/scheduler/plugins/coscheduling/coscheduling_test.go index 8299e1aae..b3535131a 100644 --- a/pkg/scheduler/plugins/coscheduling/coscheduling_test.go +++ b/pkg/scheduler/plugins/coscheduling/coscheduling_test.go @@ -382,12 +382,12 @@ func TestLess(t *testing.T) { { name: "equal priority, but p1 is added to schedulingQ earlier than p2", p1: &framework.QueuedPodInfo{ - PodInfo: framework.NewPodInfo(st.MakePod().Namespace(gangA_ns).Name("pod1").Priority(highPriority).Label(extension.LabelPodPriority, lowSubPriority).Obj()), - InitialAttemptTimestamp: earltTime, + PodInfo: framework.NewPodInfo(st.MakePod().Namespace(gangA_ns).Name("pod1").Priority(highPriority).Label(extension.LabelPodPriority, lowSubPriority).Obj()), + Timestamp: earltTime, }, p2: &framework.QueuedPodInfo{ - PodInfo: framework.NewPodInfo(st.MakePod().Namespace(gangB_ns).Name("pod2").Priority(highPriority).Label(extension.LabelPodPriority, lowSubPriority).Obj()), - InitialAttemptTimestamp: lateTime, + PodInfo: framework.NewPodInfo(st.MakePod().Namespace(gangB_ns).Name("pod2").Priority(highPriority).Label(extension.LabelPodPriority, lowSubPriority).Obj()), + Timestamp: lateTime, }, expected: true, // p1 should be ahead of p2 in the queue }, @@ -404,12 +404,12 @@ func TestLess(t *testing.T) { { name: "equal priority, p1 is added to schedulingQ earlier than p2", p1: &framework.QueuedPodInfo{ - PodInfo: framework.NewPodInfo(st.MakePod().Namespace(gangB_ns).Name("pod1").Priority(highPriority).Obj()), - InitialAttemptTimestamp: earltTime, + PodInfo: framework.NewPodInfo(st.MakePod().Namespace(gangB_ns).Name("pod1").Priority(highPriority).Obj()), + Timestamp: earltTime, }, p2: &framework.QueuedPodInfo{ - PodInfo: framework.NewPodInfo(st.MakePod().Namespace(gangA_ns).Name("pod2").Priority(highPriority).Obj()), - InitialAttemptTimestamp: lateTime, + PodInfo: framework.NewPodInfo(st.MakePod().Namespace(gangA_ns).Name("pod2").Priority(highPriority).Obj()), + Timestamp: lateTime, }, expected: true, // p1 should be ahead of p2 in the queue }, @@ -439,27 +439,27 @@ func TestLess(t *testing.T) { { name: "equal priority. p2 is added to schedulingQ earlier than p1, p1 belongs to gangA and p2 belongs to gangB", p1: &framework.QueuedPodInfo{ - PodInfo: framework.NewPodInfo(st.MakePod().Namespace(gangA_ns).Name("pod1").Priority(highPriority).Obj()), - InitialAttemptTimestamp: lateTime, + PodInfo: framework.NewPodInfo(st.MakePod().Namespace(gangA_ns).Name("pod1").Priority(highPriority).Obj()), + Timestamp: lateTime, }, annotations: map[string]string{extension.AnnotationGangName: "gangA"}, p2: &framework.QueuedPodInfo{ - PodInfo: framework.NewPodInfo(st.MakePod().Namespace(gangB_ns).Name("pod2").Priority(highPriority).Label(v1alpha1.PodGroupLabel, "gangB").Obj()), - InitialAttemptTimestamp: earltTime, + PodInfo: framework.NewPodInfo(st.MakePod().Namespace(gangB_ns).Name("pod2").Priority(highPriority).Label(v1alpha1.PodGroupLabel, "gangB").Obj()), + Timestamp: earltTime, }, - expected: true, // p1 should be ahead of p2 in the queue + expected: false, // p1 should be ahead of p2 in the queue }, { name: "equal priority and creation time, both belongs to gangB", p1: &framework.QueuedPodInfo{ - PodInfo: framework.NewPodInfo(st.MakePod().Namespace(gangB_ns).Name("pod1").Priority(highPriority).Label(v1alpha1.PodGroupLabel, "gangB").Obj()), - InitialAttemptTimestamp: lateTime, + PodInfo: framework.NewPodInfo(st.MakePod().Namespace(gangB_ns).Name("pod1").Priority(highPriority).Label(v1alpha1.PodGroupLabel, "gangB").Obj()), + Timestamp: lateTime, }, p2: &framework.QueuedPodInfo{ - PodInfo: framework.NewPodInfo(st.MakePod().Namespace(gangB_ns).Name("pod2").Priority(highPriority).Label(v1alpha1.PodGroupLabel, "gangB").Obj()), - InitialAttemptTimestamp: earltTime, + PodInfo: framework.NewPodInfo(st.MakePod().Namespace(gangB_ns).Name("pod2").Priority(highPriority).Label(v1alpha1.PodGroupLabel, "gangB").Obj()), + Timestamp: earltTime, }, - expected: true, // p1 should be ahead of p2 in the queue + expected: false, }, { name: "equal priority and creation time, both belongs to gangB, childScheduleCycle not equal", @@ -478,14 +478,14 @@ func TestLess(t *testing.T) { { name: "equal priority and creation time, p1 belongs to gangA that has been satisfied", p1: &framework.QueuedPodInfo{ - PodInfo: framework.NewPodInfo(st.MakePod().Namespace(gangB_ns).Name("pod1").Priority(highPriority).Label(v1alpha1.PodGroupLabel, "gangD").Obj()), - InitialAttemptTimestamp: lateTime, + PodInfo: framework.NewPodInfo(st.MakePod().Namespace(gangB_ns).Name("pod1").Priority(highPriority).Label(v1alpha1.PodGroupLabel, "gangD").Obj()), + Timestamp: lateTime, }, p2: &framework.QueuedPodInfo{ - PodInfo: framework.NewPodInfo(st.MakePod().Namespace(gangC_ns).Name("pod2").Priority(highPriority).Label(v1alpha1.PodGroupLabel, "gangC").Obj()), - InitialAttemptTimestamp: earltTime, + PodInfo: framework.NewPodInfo(st.MakePod().Namespace(gangC_ns).Name("pod2").Priority(highPriority).Label(v1alpha1.PodGroupLabel, "gangC").Obj()), + Timestamp: earltTime, }, - expected: true, // p1 should be ahead of p2 in the queue + expected: false, }, } { t.Run(tt.name, func(t *testing.T) { From 1ba2f1a7ad7dedfeea9fe6882c00e09d010745b4 Mon Sep 17 00:00:00 2001 From: george Date: Wed, 3 Apr 2024 13:42:47 +0800 Subject: [PATCH 22/36] Modify the name of the REG_NS variable to koordinator-sh Signed-off-by: george --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 08c203b79..f4fd4fd17 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ GIT_COMMIT_ID ?= $(shell git rev-parse --short HEAD) # Image URL to use all building/pushing image targets REG ?= ghcr.io -REG_NS ?= ocichina +REG_NS ?= koordinator-sh REG_USER ?= "" REG_PWD ?= "" From dd886e438343e257971f2ab49a3218d014c31359 Mon Sep 17 00:00:00 2001 From: xulinfei1996 <1187938268@qq.com> Date: Sun, 7 Apr 2024 15:41:30 +0800 Subject: [PATCH 23/36] scheduler: fix reservation nominator residual bug (#1985) Signed-off-by: xulinfei.xlf Co-authored-by: xulinfei.xlf Signed-off-by: george --- pkg/scheduler/plugins/reservation/eventhandler.go | 13 ++++++++++--- .../plugins/reservation/eventhandler_test.go | 9 +++++++-- pkg/scheduler/plugins/reservation/plugin.go | 2 +- pkg/scheduler/plugins/reservation/transformer.go | 3 ++- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/pkg/scheduler/plugins/reservation/eventhandler.go b/pkg/scheduler/plugins/reservation/eventhandler.go index 8e589bc79..56b2fe6d3 100644 --- a/pkg/scheduler/plugins/reservation/eventhandler.go +++ b/pkg/scheduler/plugins/reservation/eventhandler.go @@ -21,6 +21,7 @@ import ( "k8s.io/client-go/tools/cache" "k8s.io/klog/v2" + "k8s.io/kubernetes/pkg/scheduler/framework" schedulingv1alpha1 "github.com/koordinator-sh/koordinator/apis/scheduling/v1alpha1" koordinatorinformers "github.com/koordinator-sh/koordinator/pkg/client/informers/externalversions" @@ -29,12 +30,15 @@ import ( ) type reservationEventHandler struct { - cache *reservationCache + cache *reservationCache + rrNominator *nominator } -func registerReservationEventHandler(cache *reservationCache, koordinatorInformerFactory koordinatorinformers.SharedInformerFactory) { +func registerReservationEventHandler(cache *reservationCache, koordinatorInformerFactory koordinatorinformers.SharedInformerFactory, + rrNominator *nominator) { eventHandler := &reservationEventHandler{ - cache: cache, + cache: cache, + rrNominator: rrNominator, } reservationInformer := koordinatorInformerFactory.Scheduling().V1alpha1().Reservations().Informer() frameworkexthelper.ForceSyncFromInformer(context.TODO().Done(), koordinatorInformerFactory, reservationInformer, eventHandler) @@ -63,6 +67,7 @@ func (h *reservationEventHandler) OnUpdate(oldObj, newObj interface{}) { if reservationutil.IsReservationActive(newR) || reservationutil.IsReservationFailed(newR) || reservationutil.IsReservationSucceeded(newR) { h.cache.updateReservation(newR) + h.rrNominator.DeleteReservePod(framework.NewPodInfo(reservationutil.NewReservePod(newR))) klog.V(4).InfoS("update reservation into reservationCache", "reservation", klog.KObj(newR)) } } @@ -83,6 +88,8 @@ func (h *reservationEventHandler) OnDelete(obj interface{}) { return } + h.rrNominator.DeleteReservePod(framework.NewPodInfo(reservationutil.NewReservePod(r))) + // Here it is only marked that ReservationInfo is unavailable, // and the real deletion operation is executed in deleteReservationFromCache(pkg/scheduler/frameworkext/eventhandlers/reservation_handler.go). // This ensures that the Reserve Pod and the resources it holds are deleted correctly. diff --git a/pkg/scheduler/plugins/reservation/eventhandler_test.go b/pkg/scheduler/plugins/reservation/eventhandler_test.go index d81fcaf06..8f8d25732 100644 --- a/pkg/scheduler/plugins/reservation/eventhandler_test.go +++ b/pkg/scheduler/plugins/reservation/eventhandler_test.go @@ -24,8 +24,10 @@ import ( "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/uuid" + "k8s.io/kubernetes/pkg/scheduler/framework" schedulingv1alpha1 "github.com/koordinator-sh/koordinator/apis/scheduling/v1alpha1" + "github.com/koordinator-sh/koordinator/pkg/util/reservation" ) func TestEventHandlerOnAdd(t *testing.T) { @@ -194,7 +196,7 @@ func TestEventHandlerUpdate(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { cache := newReservationCache(nil) - eh := &reservationEventHandler{cache: cache} + eh := &reservationEventHandler{cache: cache, rrNominator: newNominator()} eh.OnUpdate(tt.oldReservation, tt.newReservation) if tt.wantReservation == nil { rInfo := cache.getReservationInfoByUID(tt.newReservation.UID) @@ -239,12 +241,15 @@ func TestEventHandlerDelete(t *testing.T) { }, } cache := newReservationCache(nil) - eh := &reservationEventHandler{cache: cache} + eh := &reservationEventHandler{cache: cache, rrNominator: newNominator()} eh.OnAdd(activeReservation) rInfo := cache.getReservationInfoByUID(activeReservation.UID) assert.NotNil(t, rInfo) + eh.rrNominator.AddNominatedReservePod(framework.NewPodInfo(reservation.NewReservePod(activeReservation)), "test-node") + assert.Equal(t, []*framework.PodInfo{framework.NewPodInfo(reservation.NewReservePod(activeReservation))}, eh.rrNominator.NominatedReservePodForNode("test-node")) eh.OnDelete(activeReservation) rInfo = cache.getReservationInfoByUID(activeReservation.UID) assert.NotNil(t, rInfo) assert.False(t, rInfo.IsAvailable()) + assert.Equal(t, []*framework.PodInfo{}, eh.rrNominator.NominatedReservePodForNode("test-node")) } diff --git a/pkg/scheduler/plugins/reservation/plugin.go b/pkg/scheduler/plugins/reservation/plugin.go index d28940f1f..08187fa20 100644 --- a/pkg/scheduler/plugins/reservation/plugin.go +++ b/pkg/scheduler/plugins/reservation/plugin.go @@ -102,8 +102,8 @@ func New(args runtime.Object, handle framework.Handle) (framework.Plugin, error) koordSharedInformerFactory := extendedHandle.KoordinatorSharedInformerFactory() reservationLister := koordSharedInformerFactory.Scheduling().V1alpha1().Reservations().Lister() cache := newReservationCache(reservationLister) - registerReservationEventHandler(cache, koordSharedInformerFactory) nominator := newNominator() + registerReservationEventHandler(cache, koordSharedInformerFactory, nominator) registerPodEventHandler(cache, nominator, sharedInformerFactory) // TODO(joseph): Considering the amount of changed code, diff --git a/pkg/scheduler/plugins/reservation/transformer.go b/pkg/scheduler/plugins/reservation/transformer.go index 033600e52..8abc415f0 100644 --- a/pkg/scheduler/plugins/reservation/transformer.go +++ b/pkg/scheduler/plugins/reservation/transformer.go @@ -444,7 +444,8 @@ func (pl *Plugin) BeforeFilter(ctx context.Context, cycleState *framework.CycleS if !status.IsSuccess() { return pod, nodeInfo, false, status } - klog.V(4).Infof("toschedule reservation: %s, added reservation: %s", + klog.V(4).Infof("nodeName: %s,toschedule reservation: %s, added reservation: %s", + nodeInfo.Node().Name, reservationutil.GetReservationNameFromReservePod(pod), reservationutil.GetReservationNameFromReservePod(rInfo.Pod)) } From a2157ee6aa9c6a2f0e6b9cd401cf5918ec7ec444 Mon Sep 17 00:00:00 2001 From: Siyu Wang Date: Sun, 7 Apr 2024 17:17:30 +0800 Subject: [PATCH 24/36] Add codecov token (#1987) Signed-off-by: Siyu Wang Signed-off-by: george --- .github/workflows/ci.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 62525d445..eed4fb752 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -71,6 +71,8 @@ jobs: - if: matrix.step == 'test' name: Upload coverage to Codecov uses: codecov/codecov-action@v3 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: flags: unittests file: cover.out From c415bfb11864003e460eaaf464de3c5401fc59cc Mon Sep 17 00:00:00 2001 From: Fansong Zeng Date: Sun, 7 Apr 2024 19:18:35 +0800 Subject: [PATCH 25/36] slo-controller: refactor codes for reading (#1973) Signed-off-by: Fansong Zeng Signed-off-by: george --- docs/images/node-resource-model.png | Bin 0 -> 224029 bytes .../plugins/batchresource/plugin.go | 25 +++- .../plugins/batchresource/plugin_test.go | 112 +++++++++--------- .../plugins/batchresource/util.go | 44 +++---- .../plugins/batchresource/util_test.go | 2 +- .../noderesource/resource_calculator_test.go | 31 +++-- 6 files changed, 119 insertions(+), 95 deletions(-) create mode 100644 docs/images/node-resource-model.png diff --git a/docs/images/node-resource-model.png b/docs/images/node-resource-model.png new file mode 100644 index 0000000000000000000000000000000000000000..8b7dcb56dda43529defc694a07baa17b48815af4 GIT binary patch literal 224029 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%0DY1h)E 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 literal 0 HcmV?d00001 diff --git a/pkg/slo-controller/noderesource/plugins/batchresource/plugin.go b/pkg/slo-controller/noderesource/plugins/batchresource/plugin.go index 68db3167a..9f68b86e0 100644 --- a/pkg/slo-controller/noderesource/plugins/batchresource/plugin.go +++ b/pkg/slo-controller/noderesource/plugins/batchresource/plugin.go @@ -211,6 +211,18 @@ func (p *Plugin) calculate(strategy *configuration.ColocationStrategy, node *cor }, nil } +// In order to support the colocation requirements of different enterprise environments, a configurable colocation strategy is provided. +// The resource view from the node perspective is as follows: +// +// https://github.com/koordinator-sh/koordinator/blob/main/docs/images/node-resource-model.png +// +// Typical colocation scenario: +// 1. default policy, and the CPU and memory that can be collocated are automatically calculated based on the load level of the node. +// 2. default policy on CPU, and the Memory is configured not to be overcommitted. This can reduce the probability of batch pods +// being killed due to high memory water levels (reduce the kill rate) +// +// In each scenario, users can also adjust the resource water level configuration according to your own needs and control the deployment +// density of batch pods. func (p *Plugin) calculateOnNode(strategy *configuration.ColocationStrategy, node *corev1.Node, podList *corev1.PodList, resourceMetrics *framework.ResourceMetrics) (corev1.ResourceList, string, string) { // compute the requests and usages according to the pods' priority classes. @@ -293,7 +305,7 @@ func (p *Plugin) calculateOnNode(strategy *configuration.ColocationStrategy, nod "cpu", podsDanglingUsed.Cpu().String(), "memory", podsDanglingUsed.Memory().String()) nodeCapacity := getNodeCapacity(node) - nodeReservation := getNodeReservation(strategy, nodeCapacity) + nodeSafetyMargin := getNodeSafetyMargin(strategy, nodeCapacity) systemUsed := getResourceListForCPUAndMemory(nodeMetric.Status.NodeMetric.SystemUsage.ResourceList) // resource usage of host applications with prod priority will be count as host system usage since they consumes the @@ -303,9 +315,10 @@ func (p *Plugin) calculateOnNode(strategy *configuration.ColocationStrategy, nod // System.Reserved = Node.Anno.Reserved, Node.Kubelet.Reserved) nodeAnnoReserved := util.GetNodeReservationFromAnnotation(node.Annotations) nodeKubeletReserved := util.GetNodeReservationFromKubelet(node) - systemReserved := quotav1.Max(nodeKubeletReserved, nodeAnnoReserved) + // FIXME: resource reservation taking max is rather confusing. + nodeReserved := quotav1.Max(nodeKubeletReserved, nodeAnnoReserved) - batchAllocatable, cpuMsg, memMsg := calculateBatchResourceByPolicy(strategy, nodeCapacity, nodeReservation, systemReserved, + batchAllocatable, cpuMsg, memMsg := calculateBatchResourceByPolicy(strategy, nodeCapacity, nodeSafetyMargin, nodeReserved, systemUsed, podsHPRequest, podsHPUsed, podsHPMaxUsedReq) metrics.RecordNodeExtendedResourceAllocatableInternal(node, string(extension.BatchCPU), metrics.UnitInteger, float64(batchAllocatable.Cpu().MilliValue())/1000) metrics.RecordNodeExtendedResourceAllocatableInternal(node, string(extension.BatchMemory), metrics.UnitByte, float64(batchAllocatable.Memory().Value())) @@ -366,7 +379,7 @@ func (p *Plugin) calculateOnNUMALevel(strategy *configuration.ColocationStrategy systemUsed = quotav1.Add(systemUsed, hostAppHPUsed) nodeAnnoReserved := util.GetNodeReservationFromAnnotation(node.Annotations) nodeKubeletReserved := util.GetNodeReservationFromKubelet(node) - systemReserved := quotav1.Max(nodeKubeletReserved, nodeAnnoReserved) + nodeReserved := quotav1.Max(nodeKubeletReserved, nodeAnnoReserved) for i, zone := range nrt.Zones { zoneIdxMap[i] = zone.Name @@ -380,9 +393,9 @@ func (p *Plugin) calculateOnNUMALevel(strategy *configuration.ColocationStrategy nodeZoneAllocatable[i][corev1.ResourceName(resourceInfo.Name)] = resourceInfo.Allocatable.DeepCopy() } } - nodeZoneReserve[i] = getNodeReservation(strategy, nodeZoneAllocatable[i]) + nodeZoneReserve[i] = getNodeSafetyMargin(strategy, nodeZoneAllocatable[i]) systemZoneUsed[i] = divideResourceList(systemUsed, float64(zoneNum)) - systemZoneReserved[i] = divideResourceList(systemReserved, float64(zoneNum)) + systemZoneReserved[i] = divideResourceList(nodeReserved, float64(zoneNum)) } podMetricMap := make(map[string]*slov1alpha1.PodMetricInfo) podMetricUnknownMap := make(map[string]*slov1alpha1.PodMetricInfo) diff --git a/pkg/slo-controller/noderesource/plugins/batchresource/plugin_test.go b/pkg/slo-controller/noderesource/plugins/batchresource/plugin_test.go index c4782e74c..6746b6826 100644 --- a/pkg/slo-controller/noderesource/plugins/batchresource/plugin_test.go +++ b/pkg/slo-controller/noderesource/plugins/batchresource/plugin_test.go @@ -1694,12 +1694,12 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(25000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:25000 = nodeCapacity:100000 - nodeReservation:35000 - systemUsageOrReserved:7000 - podHPUsed:33000", + Message: "batchAllocatable[CPU(Milli-Core)]:25000 = nodeCapacity:100000 - nodeSafetyMargin:35000 - systemUsageOrNodeReserved:7000 - podHPUsed:33000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(33, 9), - Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeReservation:42 - systemUsage:12 - podHPUsed:33", + Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeSafetyMargin:42 - systemUsage:12 - podHPUsed:33", }, }, wantErr: false, @@ -1729,12 +1729,12 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(25000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:25000 = nodeCapacity:100000 - nodeReservation:35000 - systemUsageOrReserved:7000 - podHPUsed:33000", + Message: "batchAllocatable[CPU(Milli-Core)]:25000 = nodeCapacity:100000 - nodeSafetyMargin:35000 - systemUsageOrNodeReserved:7000 - podHPUsed:33000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(33, 9), - Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeReservation:42 - systemUsage:12 - podHPUsed:33", + Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeSafetyMargin:42 - systemUsage:12 - podHPUsed:33", }, }, wantErr: false, @@ -1766,12 +1766,12 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(25000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:25000 = nodeCapacity:100000 - nodeReservation:35000 - systemUsageOrReserved:7000 - podHPUsed:33000", + Message: "batchAllocatable[CPU(Milli-Core)]:25000 = nodeCapacity:100000 - nodeSafetyMargin:35000 - systemUsageOrNodeReserved:7000 - podHPUsed:33000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(33, 9), - Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeReservation:42 - systemUsage:12 - podHPUsed:33", + Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeSafetyMargin:42 - systemUsage:12 - podHPUsed:33", }, }, wantErr: false, @@ -1803,12 +1803,12 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(12000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:12000 = nodeCapacity:100000 - nodeReservation:35000 - systemUsageOrReserved:20000 - podHPUsed:33000", + Message: "batchAllocatable[CPU(Milli-Core)]:12000 = nodeCapacity:100000 - nodeSafetyMargin:35000 - systemUsageOrNodeReserved:20000 - podHPUsed:33000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(33, 9), - Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeReservation:42 - systemUsage:12 - podHPUsed:33", + Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeSafetyMargin:42 - systemUsage:12 - podHPUsed:33", }, }, wantErr: false, @@ -1840,12 +1840,12 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(12000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:12000 = nodeCapacity:100000 - nodeReservation:35000 - systemUsageOrReserved:20000 - podHPUsed:33000", + Message: "batchAllocatable[CPU(Milli-Core)]:12000 = nodeCapacity:100000 - nodeSafetyMargin:35000 - systemUsageOrNodeReserved:20000 - podHPUsed:33000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(33, 9), - Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeReservation:42 - systemUsage:12 - podHPUsed:33", + Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeSafetyMargin:42 - systemUsage:12 - podHPUsed:33", }, }, wantErr: false, @@ -1878,12 +1878,12 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(22000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:22000 = nodeCapacity:100000 - nodeReservation:35000 - systemUsageOrReserved:10000 - podHPUsed:33000", + Message: "batchAllocatable[CPU(Milli-Core)]:22000 = nodeCapacity:100000 - nodeSafetyMargin:35000 - systemUsageOrNodeReserved:10000 - podHPUsed:33000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(33, 9), - Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeReservation:42 - systemUsage:12 - podHPUsed:33", + Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeSafetyMargin:42 - systemUsage:12 - podHPUsed:33", }, }, wantErr: false, @@ -1915,12 +1915,12 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(25000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:25000 = nodeCapacity:100000 - nodeReservation:35000 - systemUsageOrReserved:7000 - podHPUsed:33000", + Message: "batchAllocatable[CPU(Milli-Core)]:25000 = nodeCapacity:100000 - nodeSafetyMargin:35000 - systemUsageOrNodeReserved:7000 - podHPUsed:33000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(25, 9), - Message: "batchAllocatable[Mem(GB)]:25 = nodeCapacity:120 - nodeReservation:42 - systemUsage:20 - podHPUsed:33", + Message: "batchAllocatable[Mem(GB)]:25 = nodeCapacity:120 - nodeSafetyMargin:42 - systemUsage:20 - podHPUsed:33", }, }, wantErr: false, @@ -1952,12 +1952,12 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(25000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:25000 = nodeCapacity:100000 - nodeReservation:35000 - systemUsageOrReserved:7000 - podHPUsed:33000", + Message: "batchAllocatable[CPU(Milli-Core)]:25000 = nodeCapacity:100000 - nodeSafetyMargin:35000 - systemUsageOrNodeReserved:7000 - podHPUsed:33000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(33, 9), - Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeReservation:42 - systemUsage:12 - podHPUsed:33", + Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeSafetyMargin:42 - systemUsage:12 - podHPUsed:33", }, }, wantErr: false, @@ -1992,12 +1992,12 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(25000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:25000 = nodeCapacity:100000 - nodeReservation:35000 - systemUsageOrReserved:7000 - podHPUsed:33000", + Message: "batchAllocatable[CPU(Milli-Core)]:25000 = nodeCapacity:100000 - nodeSafetyMargin:35000 - systemUsageOrNodeReserved:7000 - podHPUsed:33000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(33, 9), - Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeReservation:42 - systemUsage:12 - podHPUsed:33", + Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeSafetyMargin:42 - systemUsage:12 - podHPUsed:33", }, }, wantErr: false, @@ -2032,12 +2032,12 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(22000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:22000 = nodeCapacity:100000 - nodeReservation:35000 - systemUsageOrReserved:10000 - podHPUsed:33000", + Message: "batchAllocatable[CPU(Milli-Core)]:22000 = nodeCapacity:100000 - nodeSafetyMargin:35000 - systemUsageOrNodeReserved:10000 - podHPUsed:33000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(25, 9), - Message: "batchAllocatable[Mem(GB)]:25 = nodeCapacity:120 - nodeReservation:42 - systemUsage:20 - podHPUsed:33", + Message: "batchAllocatable[Mem(GB)]:25 = nodeCapacity:120 - nodeSafetyMargin:42 - systemUsage:20 - podHPUsed:33", }, }, wantErr: false, @@ -2072,12 +2072,12 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(22000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:22000 = nodeCapacity:100000 - nodeReservation:35000 - systemUsageOrReserved:10000 - podHPUsed:33000", + Message: "batchAllocatable[CPU(Milli-Core)]:22000 = nodeCapacity:100000 - nodeSafetyMargin:35000 - systemUsageOrNodeReserved:10000 - podHPUsed:33000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(25, 9), - Message: "batchAllocatable[Mem(GB)]:25 = nodeCapacity:120 - nodeReservation:42 - systemUsage:20 - podHPUsed:33", + Message: "batchAllocatable[Mem(GB)]:25 = nodeCapacity:120 - nodeSafetyMargin:42 - systemUsage:20 - podHPUsed:33", }, }, wantErr: false, @@ -2112,12 +2112,12 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(22000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:22000 = nodeCapacity:100000 - nodeReservation:35000 - systemUsageOrReserved:10000 - podHPUsed:33000", + Message: "batchAllocatable[CPU(Milli-Core)]:22000 = nodeCapacity:100000 - nodeSafetyMargin:35000 - systemUsageOrNodeReserved:10000 - podHPUsed:33000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(25, 9), - Message: "batchAllocatable[Mem(GB)]:25 = nodeCapacity:120 - nodeReservation:42 - systemUsage:20 - podHPUsed:33", + Message: "batchAllocatable[Mem(GB)]:25 = nodeCapacity:120 - nodeSafetyMargin:42 - systemUsage:20 - podHPUsed:33", }, }, wantErr: false, @@ -2148,12 +2148,12 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(30000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:30000 = nodeCapacity:100000 - nodeReservation:30000 - systemUsageOrReserved:7000 - podHPUsed:33000", + Message: "batchAllocatable[CPU(Milli-Core)]:30000 = nodeCapacity:100000 - nodeSafetyMargin:30000 - systemUsageOrNodeReserved:7000 - podHPUsed:33000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(36, 9), - Message: "batchAllocatable[Mem(GB)]:36 = nodeCapacity:120 - nodeReservation:24 - systemReserved:0 - podHPRequest:60", + Message: "batchAllocatable[Mem(GB)]:36 = nodeCapacity:120 - nodeSafetyMargin:24 - nodeReserved:0 - podHPRequest:60", }, }, wantErr: false, @@ -2189,12 +2189,12 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(30000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:30000 = nodeCapacity:100000 - nodeReservation:30000 - systemUsageOrReserved:7000 - podHPUsed:33000", + Message: "batchAllocatable[CPU(Milli-Core)]:30000 = nodeCapacity:100000 - nodeSafetyMargin:30000 - systemUsageOrNodeReserved:7000 - podHPUsed:33000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(31, 9), - Message: "batchAllocatable[Mem(GB)]:31 = nodeCapacity:120 - nodeReservation:24 - systemReserved:5 - podHPRequest:60", + Message: "batchAllocatable[Mem(GB)]:31 = nodeCapacity:120 - nodeSafetyMargin:24 - nodeReserved:5 - podHPRequest:60", }, }, wantErr: false, @@ -2230,12 +2230,12 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(27000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:27000 = nodeCapacity:100000 - nodeReservation:30000 - systemUsageOrReserved:10000 - podHPUsed:33000", + Message: "batchAllocatable[CPU(Milli-Core)]:27000 = nodeCapacity:100000 - nodeSafetyMargin:30000 - systemUsageOrNodeReserved:10000 - podHPUsed:33000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(16, 9), - Message: "batchAllocatable[Mem(GB)]:16 = nodeCapacity:120 - nodeReservation:24 - systemReserved:20 - podHPRequest:60", + Message: "batchAllocatable[Mem(GB)]:16 = nodeCapacity:120 - nodeSafetyMargin:24 - nodeReserved:20 - podHPRequest:60", }, }, wantErr: false, @@ -2271,12 +2271,12 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(30000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:30000 = nodeCapacity:100000 - nodeReservation:30000 - systemUsageOrReserved:7000 - podHPUsed:33000", + Message: "batchAllocatable[CPU(Milli-Core)]:30000 = nodeCapacity:100000 - nodeSafetyMargin:30000 - systemUsageOrNodeReserved:7000 - podHPUsed:33000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(26, 9), - Message: "batchAllocatable[Mem(GB)]:26 = nodeCapacity:120 - nodeReservation:24 - systemReserved:10 - podHPRequest:60", + Message: "batchAllocatable[Mem(GB)]:26 = nodeCapacity:120 - nodeSafetyMargin:24 - nodeReserved:10 - podHPRequest:60", }, }, wantErr: false, @@ -2435,12 +2435,12 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(25000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:25000 = nodeCapacity:100000 - nodeReservation:35000 - systemUsageOrReserved:7000 - podHPUsed:33000", + Message: "batchAllocatable[CPU(Milli-Core)]:25000 = nodeCapacity:100000 - nodeSafetyMargin:35000 - systemUsageOrNodeReserved:7000 - podHPUsed:33000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(33, 9), - Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeReservation:42 - systemUsage:12 - podHPUsed:33", + Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeSafetyMargin:42 - systemUsage:12 - podHPUsed:33", }, }, wantErr: false, @@ -2534,12 +2534,12 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(35000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:35000 = nodeCapacity:100000 - nodeReservation:35000 - systemUsageOrReserved:5000 - podHPUsed:25000", + Message: "batchAllocatable[CPU(Milli-Core)]:35000 = nodeCapacity:100000 - nodeSafetyMargin:35000 - systemUsageOrNodeReserved:5000 - podHPUsed:25000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(43, 9), - Message: "batchAllocatable[Mem(GB)]:43 = nodeCapacity:120 - nodeReservation:42 - systemUsage:10 - podHPUsed:25", + Message: "batchAllocatable[Mem(GB)]:43 = nodeCapacity:120 - nodeSafetyMargin:42 - systemUsage:10 - podHPUsed:25", }, }, wantErr: false, @@ -2698,12 +2698,12 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(20000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:20000 = nodeCapacity:100000 - nodeReservation:35000 - systemUsageOrReserved:7000 - podHPUsed:38000", + Message: "batchAllocatable[CPU(Milli-Core)]:20000 = nodeCapacity:100000 - nodeSafetyMargin:35000 - systemUsageOrNodeReserved:7000 - podHPUsed:38000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(33, 9), - Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeReservation:42 - systemUsage:12 - podHPUsed:33", + Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeSafetyMargin:42 - systemUsage:12 - podHPUsed:33", }, }, wantErr: false, @@ -2890,7 +2890,7 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(25000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:25000 = nodeCapacity:100000 - nodeReservation:35000 - systemUsageOrReserved:7000 - podHPUsed:33000", + Message: "batchAllocatable[CPU(Milli-Core)]:25000 = nodeCapacity:100000 - nodeSafetyMargin:35000 - systemUsageOrNodeReserved:7000 - podHPUsed:33000", ZoneQuantity: map[string]resource.Quantity{ util.GenNodeZoneName(0): *resource.NewQuantity(25000, resource.DecimalSI), }, @@ -2898,7 +2898,7 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(33, 9), - Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeReservation:42 - systemUsage:12 - podHPUsed:33", + Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeSafetyMargin:42 - systemUsage:12 - podHPUsed:33", ZoneQuantity: map[string]resource.Quantity{ util.GenNodeZoneName(0): *resource.NewScaledQuantity(33, 9), }, @@ -3115,7 +3115,7 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(25000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:25000 = nodeCapacity:100000 - nodeReservation:35000 - systemUsageOrReserved:7000 - podHPUsed:33000", + Message: "batchAllocatable[CPU(Milli-Core)]:25000 = nodeCapacity:100000 - nodeSafetyMargin:35000 - systemUsageOrNodeReserved:7000 - podHPUsed:33000", ZoneQuantity: map[string]resource.Quantity{ util.GenNodeZoneName(0): *resource.NewQuantity(10000, resource.DecimalSI), // 50 - 17.5 - 3.5 - (14 + 5) util.GenNodeZoneName(1): *resource.NewQuantity(15000, resource.DecimalSI), // 50 - 17.5 - 3.5 - 14 @@ -3124,7 +3124,7 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(33, 9), - Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeReservation:42 - systemUsage:12 - podHPUsed:33", + Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeSafetyMargin:42 - systemUsage:12 - podHPUsed:33", ZoneQuantity: map[string]resource.Quantity{ util.GenNodeZoneName(0): *resource.NewScaledQuantity(15300, 6), // 62 - 21.7(62*0.35) - 6 - (14 + 5) util.GenNodeZoneName(1): *resource.NewScaledQuantity(17700, 6), // 58 - 20.3(58*0.35) - 6 - 14 @@ -3345,7 +3345,7 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(20000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:20000 = nodeCapacity:100000 - nodeReservation:35000 - systemUsageOrReserved:7000 - podHPUsed:38000", + Message: "batchAllocatable[CPU(Milli-Core)]:20000 = nodeCapacity:100000 - nodeSafetyMargin:35000 - systemUsageOrNodeReserved:7000 - podHPUsed:38000", ZoneQuantity: map[string]resource.Quantity{ util.GenNodeZoneName(0): *resource.NewQuantity(5000, resource.DecimalSI), // 50 - 17.5 - 3.5 - (14 + 10) util.GenNodeZoneName(1): *resource.NewQuantity(15000, resource.DecimalSI), // 50 - 17.5 - 3.5 - 14 @@ -3354,7 +3354,7 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(18, 9), - Message: "batchAllocatable[Mem(GB)]:18 = nodeCapacity:120 - nodeReservation:42 - systemReserved:0 - podHPRequest:60", + Message: "batchAllocatable[Mem(GB)]:18 = nodeCapacity:120 - nodeSafetyMargin:42 - nodeReserved:0 - podHPRequest:60", ZoneQuantity: map[string]resource.Quantity{ util.GenNodeZoneName(0): *resource.NewScaledQuantity(5300, 6), // 62 - 21.7(62*0.35) - (25 + 10) util.GenNodeZoneName(1): *resource.NewScaledQuantity(12700, 6), // 58 - 20.3(58*0.35) - 25 @@ -3575,7 +3575,7 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(18000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:18000 = nodeCapacity:100000 - nodeReservation:35000 - systemUsageOrReserved:7000 - podHPUsed:40000", + Message: "batchAllocatable[CPU(Milli-Core)]:18000 = nodeCapacity:100000 - nodeSafetyMargin:35000 - systemUsageOrNodeReserved:7000 - podHPUsed:40000", ZoneQuantity: map[string]resource.Quantity{ util.GenNodeZoneName(0): *resource.NewQuantity(4000, resource.DecimalSI), // 50 - 17.5 - 3.5 - (14 + 10 + 1) util.GenNodeZoneName(1): *resource.NewQuantity(14000, resource.DecimalSI), // 50 - 17.5 - 3.5 - (14 + 1) @@ -3584,7 +3584,7 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(18, 9), - Message: "batchAllocatable[Mem(GB)]:18 = nodeCapacity:120 - nodeReservation:42 - systemReserved:0 - podHPRequest:60", + Message: "batchAllocatable[Mem(GB)]:18 = nodeCapacity:120 - nodeSafetyMargin:42 - nodeReserved:0 - podHPRequest:60", ZoneQuantity: map[string]resource.Quantity{ util.GenNodeZoneName(0): *resource.NewScaledQuantity(5300, 6), // 62 - 21.7(62*0.35) - (25 + 10) util.GenNodeZoneName(1): *resource.NewScaledQuantity(12700, 6), // 58 - 20.3(58*0.35) - 25 @@ -3621,12 +3621,12 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(21000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:21000 = nodeCapacity:100000 - nodeReservation:30000 - systemUsageOrReserved:7000 - podHPMaxUsedRequest:42000", + Message: "batchAllocatable[CPU(Milli-Core)]:21000 = nodeCapacity:100000 - nodeSafetyMargin:30000 - systemUsageOrNodeReserved:7000 - podHPMaxUsedRequest:42000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(36, 9), - Message: "batchAllocatable[Mem(GB)]:36 = nodeCapacity:120 - nodeReservation:24 - systemReserved:0 - podHPRequest:60", + Message: "batchAllocatable[Mem(GB)]:36 = nodeCapacity:120 - nodeSafetyMargin:24 - nodeReserved:0 - podHPRequest:60", }, }, wantErr: false, @@ -3659,12 +3659,12 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(101000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:101000 = nodeCapacity:100000 - nodeReservation:-50000 - systemUsageOrReserved:7000 - podHPMaxUsedRequest:42000", + Message: "batchAllocatable[CPU(Milli-Core)]:101000 = nodeCapacity:100000 - nodeSafetyMargin:-50000 - systemUsageOrNodeReserved:7000 - podHPMaxUsedRequest:42000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(84, 9), - Message: "batchAllocatable[Mem(GB)]:84 = nodeCapacity:120 - nodeReservation:-24 - systemReserved:0 - podHPRequest:60", + Message: "batchAllocatable[Mem(GB)]:84 = nodeCapacity:120 - nodeSafetyMargin:-24 - nodeReserved:0 - podHPRequest:60", }, }, wantErr: false, @@ -3720,12 +3720,12 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(25000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:25000 = nodeCapacity:100000 - nodeReservation:35000 - systemUsageOrReserved:7000 - podHPUsed:33000", + Message: "batchAllocatable[CPU(Milli-Core)]:25000 = nodeCapacity:100000 - nodeSafetyMargin:35000 - systemUsageOrNodeReserved:7000 - podHPUsed:33000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(33, 9), - Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeReservation:42 - systemUsage:12 - podHPUsed:33", + Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeSafetyMargin:42 - systemUsage:12 - podHPUsed:33", }, }, wantErr: false, @@ -3781,12 +3781,12 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(28000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:28000 = nodeCapacity:100000 - nodeReservation:35000 - systemUsageOrReserved:4000 - podHPUsed:33000", + Message: "batchAllocatable[CPU(Milli-Core)]:28000 = nodeCapacity:100000 - nodeSafetyMargin:35000 - systemUsageOrNodeReserved:4000 - podHPUsed:33000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(39, 9), - Message: "batchAllocatable[Mem(GB)]:39 = nodeCapacity:120 - nodeReservation:42 - systemUsage:6 - podHPUsed:33", + Message: "batchAllocatable[Mem(GB)]:39 = nodeCapacity:120 - nodeSafetyMargin:42 - systemUsage:6 - podHPUsed:33", }, }, wantErr: false, @@ -4005,7 +4005,7 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(14000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:14000 = nodeCapacity:100000 - nodeReservation:35000 - systemUsageOrReserved:7000 - podHPUsed:44000", + Message: "batchAllocatable[CPU(Milli-Core)]:14000 = nodeCapacity:100000 - nodeSafetyMargin:35000 - systemUsageOrNodeReserved:7000 - podHPUsed:44000", ZoneQuantity: map[string]resource.Quantity{ util.GenNodeZoneName(0): *resource.NewQuantity(2000, resource.DecimalSI), // 50 - 17.5 - 3.5 - (14 + 10 + 1 + 2) util.GenNodeZoneName(1): *resource.NewQuantity(12000, resource.DecimalSI), // 50 - 17.5 - 3.5 - (14 + 1 + 2) @@ -4014,7 +4014,7 @@ func TestPluginCalculate(t *testing.T) { { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(18, 9), - Message: "batchAllocatable[Mem(GB)]:18 = nodeCapacity:120 - nodeReservation:42 - systemReserved:0 - podHPRequest:60", + Message: "batchAllocatable[Mem(GB)]:18 = nodeCapacity:120 - nodeSafetyMargin:42 - nodeReserved:0 - podHPRequest:60", ZoneQuantity: map[string]resource.Quantity{ util.GenNodeZoneName(0): *resource.NewScaledQuantity(5300, 6), // 62 - 21.7(62*0.35) - (25 + 10) util.GenNodeZoneName(1): *resource.NewScaledQuantity(12700, 6), // 58 - 20.3(58*0.35) - 25 diff --git a/pkg/slo-controller/noderesource/plugins/batchresource/util.go b/pkg/slo-controller/noderesource/plugins/batchresource/util.go index b7d5d5df2..9411f63c9 100644 --- a/pkg/slo-controller/noderesource/plugins/batchresource/util.go +++ b/pkg/slo-controller/noderesource/plugins/batchresource/util.go @@ -35,22 +35,22 @@ import ( "github.com/koordinator-sh/koordinator/pkg/util" ) -func calculateBatchResourceByPolicy(strategy *configuration.ColocationStrategy, nodeCapacity, nodeReserved, systemReserved, +func calculateBatchResourceByPolicy(strategy *configuration.ColocationStrategy, nodeCapacity, nodeSafetyMargin, nodeReserved, systemUsed, podHPReq, podHPUsed, podHPMaxUsedReq corev1.ResourceList) (corev1.ResourceList, string, string) { - // Node(Batch).Alloc[usage] := Node.Total - Node.Reserved - System.Used - sum(Pod(Prod/Mid).Used) + // Node(Batch).Alloc[usage] := Node.Total - Node.SafetyMargin - System.Used - sum(Pod(Prod/Mid).Used) // System.Used = max(Node.Used - Pod(All).Used, Node.Anno.Reserved, Node.Kubelet.Reserved) - systemUsed = quotav1.Max(systemUsed, systemReserved) + systemUsed = quotav1.Max(systemUsed, nodeReserved) batchAllocatableByUsage := quotav1.Max(quotav1.Subtract(quotav1.Subtract(quotav1.Subtract( - nodeCapacity, nodeReserved), systemUsed), podHPUsed), util.NewZeroResourceList()) + nodeCapacity, nodeSafetyMargin), systemUsed), podHPUsed), util.NewZeroResourceList()) - // Node(Batch).Alloc[request] := Node.Total - Node.Reserved - System.Reserved - sum(Pod(Prod/Mid).Request) + // Node(Batch).Alloc[request] := Node.Total - Node.SafetyMargin - System.Reserved - sum(Pod(Prod/Mid).Request) // System.Reserved = max(Node.Anno.Reserved, Node.Kubelet.Reserved) batchAllocatableByRequest := quotav1.Max(quotav1.Subtract(quotav1.Subtract(quotav1.Subtract( - nodeCapacity, nodeReserved), systemReserved), podHPReq), util.NewZeroResourceList()) + nodeCapacity, nodeSafetyMargin), nodeReserved), podHPReq), util.NewZeroResourceList()) - // Node(Batch).Alloc[maxUsageRequest] := Node.Total - Node.Reserved - System.Used - sum(max(Pod(Prod/Mid).Request, Pod(Prod/Mid).Used)) + // Node(Batch).Alloc[maxUsageRequest] := Node.Total - Node.SafetyMargin - System.Used - sum(max(Pod(Prod/Mid).Request, Pod(Prod/Mid).Used)) batchAllocatableByMaxUsageRequest := quotav1.Max(quotav1.Subtract(quotav1.Subtract(quotav1.Subtract( - nodeCapacity, nodeReserved), systemUsed), podHPMaxUsedReq), util.NewZeroResourceList()) + nodeCapacity, nodeSafetyMargin), systemUsed), podHPMaxUsedReq), util.NewZeroResourceList()) batchAllocatable := batchAllocatableByUsage @@ -58,12 +58,12 @@ func calculateBatchResourceByPolicy(strategy *configuration.ColocationStrategy, // batch cpu support policy "usage" and "maxUsageRequest" if strategy != nil && strategy.CPUCalculatePolicy != nil && *strategy.CPUCalculatePolicy == configuration.CalculateByPodMaxUsageRequest { batchAllocatable[corev1.ResourceCPU] = *batchAllocatableByMaxUsageRequest.Cpu() - cpuMsg = fmt.Sprintf("batchAllocatable[CPU(Milli-Core)]:%v = nodeCapacity:%v - nodeReservation:%v - systemUsageOrReserved:%v - podHPMaxUsedRequest:%v", - batchAllocatable.Cpu().MilliValue(), nodeCapacity.Cpu().MilliValue(), nodeReserved.Cpu().MilliValue(), + cpuMsg = fmt.Sprintf("batchAllocatable[CPU(Milli-Core)]:%v = nodeCapacity:%v - nodeSafetyMargin:%v - systemUsageOrNodeReserved:%v - podHPMaxUsedRequest:%v", + batchAllocatable.Cpu().MilliValue(), nodeCapacity.Cpu().MilliValue(), nodeSafetyMargin.Cpu().MilliValue(), systemUsed.Cpu().MilliValue(), podHPMaxUsedReq.Cpu().MilliValue()) } else { // use CalculatePolicy "usage" by default - cpuMsg = fmt.Sprintf("batchAllocatable[CPU(Milli-Core)]:%v = nodeCapacity:%v - nodeReservation:%v - systemUsageOrReserved:%v - podHPUsed:%v", - batchAllocatable.Cpu().MilliValue(), nodeCapacity.Cpu().MilliValue(), nodeReserved.Cpu().MilliValue(), + cpuMsg = fmt.Sprintf("batchAllocatable[CPU(Milli-Core)]:%v = nodeCapacity:%v - nodeSafetyMargin:%v - systemUsageOrNodeReserved:%v - podHPUsed:%v", + batchAllocatable.Cpu().MilliValue(), nodeCapacity.Cpu().MilliValue(), nodeSafetyMargin.Cpu().MilliValue(), systemUsed.Cpu().MilliValue(), podHPUsed.Cpu().MilliValue()) } @@ -71,20 +71,20 @@ func calculateBatchResourceByPolicy(strategy *configuration.ColocationStrategy, // batch memory support policy "usage", "request" and "maxUsageRequest" if strategy != nil && strategy.MemoryCalculatePolicy != nil && *strategy.MemoryCalculatePolicy == configuration.CalculateByPodRequest { batchAllocatable[corev1.ResourceMemory] = *batchAllocatableByRequest.Memory() - memMsg = fmt.Sprintf("batchAllocatable[Mem(GB)]:%v = nodeCapacity:%v - nodeReservation:%v - systemReserved:%v - podHPRequest:%v", + memMsg = fmt.Sprintf("batchAllocatable[Mem(GB)]:%v = nodeCapacity:%v - nodeSafetyMargin:%v - nodeReserved:%v - podHPRequest:%v", batchAllocatable.Memory().ScaledValue(resource.Giga), nodeCapacity.Memory().ScaledValue(resource.Giga), - nodeReserved.Memory().ScaledValue(resource.Giga), systemReserved.Memory().ScaledValue(resource.Giga), + nodeSafetyMargin.Memory().ScaledValue(resource.Giga), nodeReserved.Memory().ScaledValue(resource.Giga), podHPReq.Memory().ScaledValue(resource.Giga)) } else if strategy != nil && strategy.MemoryCalculatePolicy != nil && *strategy.MemoryCalculatePolicy == configuration.CalculateByPodMaxUsageRequest { batchAllocatable[corev1.ResourceMemory] = *batchAllocatableByMaxUsageRequest.Memory() - memMsg = fmt.Sprintf("batchAllocatable[Mem(GB)]:%v = nodeCapacity:%v - nodeReservation:%v - systemUsage:%v - podHPMaxUsedRequest:%v", + memMsg = fmt.Sprintf("batchAllocatable[Mem(GB)]:%v = nodeCapacity:%v - nodeSafetyMargin:%v - systemUsage:%v - podHPMaxUsedRequest:%v", batchAllocatable.Memory().ScaledValue(resource.Giga), nodeCapacity.Memory().ScaledValue(resource.Giga), - nodeReserved.Memory().ScaledValue(resource.Giga), systemUsed.Memory().ScaledValue(resource.Giga), + nodeSafetyMargin.Memory().ScaledValue(resource.Giga), systemUsed.Memory().ScaledValue(resource.Giga), podHPMaxUsedReq.Memory().ScaledValue(resource.Giga)) } else { // use CalculatePolicy "usage" by default - memMsg = fmt.Sprintf("batchAllocatable[Mem(GB)]:%v = nodeCapacity:%v - nodeReservation:%v - systemUsage:%v - podHPUsed:%v", + memMsg = fmt.Sprintf("batchAllocatable[Mem(GB)]:%v = nodeCapacity:%v - nodeSafetyMargin:%v - systemUsage:%v - podHPUsed:%v", batchAllocatable.Memory().ScaledValue(resource.Giga), nodeCapacity.Memory().ScaledValue(resource.Giga), - nodeReserved.Memory().ScaledValue(resource.Giga), systemUsed.Memory().ScaledValue(resource.Giga), + nodeSafetyMargin.Memory().ScaledValue(resource.Giga), systemUsed.Memory().ScaledValue(resource.Giga), podHPUsed.Memory().ScaledValue(resource.Giga)) } return batchAllocatable, cpuMsg, memMsg @@ -201,10 +201,10 @@ func getNodeCapacity(node *corev1.Node) corev1.ResourceList { return getResourceListForCPUAndMemory(node.Status.Capacity) } -// getNodeReservation gets node-level safe-guarding reservation with the node's allocatable -func getNodeReservation(strategy *configuration.ColocationStrategy, nodeAllocatable corev1.ResourceList) corev1.ResourceList { - cpuReserveQuant := util.MultiplyMilliQuant(nodeAllocatable[corev1.ResourceCPU], getReserveRatio(*strategy.CPUReclaimThresholdPercent)) - memReserveQuant := util.MultiplyQuant(nodeAllocatable[corev1.ResourceMemory], getReserveRatio(*strategy.MemoryReclaimThresholdPercent)) +// getNodeSafetyMargin gets node-level safe-guarding reservation with the node's allocatable +func getNodeSafetyMargin(strategy *configuration.ColocationStrategy, nodeCapacity corev1.ResourceList) corev1.ResourceList { + cpuReserveQuant := util.MultiplyMilliQuant(nodeCapacity[corev1.ResourceCPU], getReserveRatio(*strategy.CPUReclaimThresholdPercent)) + memReserveQuant := util.MultiplyQuant(nodeCapacity[corev1.ResourceMemory], getReserveRatio(*strategy.MemoryReclaimThresholdPercent)) return corev1.ResourceList{ corev1.ResourceCPU: cpuReserveQuant, diff --git a/pkg/slo-controller/noderesource/plugins/batchresource/util_test.go b/pkg/slo-controller/noderesource/plugins/batchresource/util_test.go index 9e0a86356..285f4df4d 100644 --- a/pkg/slo-controller/noderesource/plugins/batchresource/util_test.go +++ b/pkg/slo-controller/noderesource/plugins/batchresource/util_test.go @@ -121,7 +121,7 @@ func Test_getNodeReservation(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := getNodeReservation(tt.args.strategy, tt.args.nodeAllocatable) + got := getNodeSafetyMargin(tt.args.strategy, tt.args.nodeAllocatable) testingCorrectResourceList(t, &tt.want, &got) }) } diff --git a/pkg/slo-controller/noderesource/resource_calculator_test.go b/pkg/slo-controller/noderesource/resource_calculator_test.go index 2154aa5ec..2fffb9a51 100644 --- a/pkg/slo-controller/noderesource/resource_calculator_test.go +++ b/pkg/slo-controller/noderesource/resource_calculator_test.go @@ -29,12 +29,15 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/clock" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" "k8s.io/utils/pointer" + "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" "github.com/koordinator-sh/koordinator/apis/configuration" "github.com/koordinator-sh/koordinator/apis/extension" + schedulingv1alpha1 "github.com/koordinator-sh/koordinator/apis/scheduling/v1alpha1" slov1alpha1 "github.com/koordinator-sh/koordinator/apis/slo/v1alpha1" "github.com/koordinator-sh/koordinator/pkg/slo-controller/noderesource/framework" "github.com/koordinator-sh/koordinator/pkg/slo-controller/noderesource/plugins/batchresource" @@ -176,12 +179,12 @@ func Test_calculateNodeResource(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(0, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:0 = nodeCapacity:20000 - nodeReservation:7000 - systemUsageOrReserved:0 - podHPUsed:20000", + Message: "batchAllocatable[CPU(Milli-Core)]:0 = nodeCapacity:20000 - nodeSafetyMargin:7000 - systemUsageOrNodeReserved:0 - podHPUsed:20000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(6, 9), - Message: "batchAllocatable[Mem(GB)]:6 = nodeCapacity:40 - nodeReservation:14 - systemUsage:0 - podHPUsed:20", + Message: "batchAllocatable[Mem(GB)]:6 = nodeCapacity:40 - nodeSafetyMargin:14 - systemUsage:0 - podHPUsed:20", }, { Name: extension.MidCPU, @@ -383,12 +386,12 @@ func Test_calculateNodeResource(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(25000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:25000 = nodeCapacity:100000 - nodeReservation:35000 - systemUsageOrReserved:7000 - podHPUsed:33000", + Message: "batchAllocatable[CPU(Milli-Core)]:25000 = nodeCapacity:100000 - nodeSafetyMargin:35000 - systemUsageOrNodeReserved:7000 - podHPUsed:33000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(33, 9), - Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeReservation:42 - systemUsage:12 - podHPUsed:33", + Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeSafetyMargin:42 - systemUsage:12 - podHPUsed:33", }, { Name: extension.MidCPU, @@ -593,12 +596,12 @@ func Test_calculateNodeResource(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(30000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:30000 = nodeCapacity:100000 - nodeReservation:30000 - systemUsageOrReserved:7000 - podHPUsed:33000", + Message: "batchAllocatable[CPU(Milli-Core)]:30000 = nodeCapacity:100000 - nodeSafetyMargin:30000 - systemUsageOrNodeReserved:7000 - podHPUsed:33000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(39, 9), - Message: "batchAllocatable[Mem(GB)]:39 = nodeCapacity:120 - nodeReservation:36 - systemUsage:12 - podHPUsed:33", + Message: "batchAllocatable[Mem(GB)]:39 = nodeCapacity:120 - nodeSafetyMargin:36 - systemUsage:12 - podHPUsed:33", }, { Name: extension.MidCPU, @@ -803,12 +806,12 @@ func Test_calculateNodeResource(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(30000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:30000 = nodeCapacity:100000 - nodeReservation:30000 - systemUsageOrReserved:7000 - podHPUsed:33000", + Message: "batchAllocatable[CPU(Milli-Core)]:30000 = nodeCapacity:100000 - nodeSafetyMargin:30000 - systemUsageOrNodeReserved:7000 - podHPUsed:33000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(36, 9), - Message: "batchAllocatable[Mem(GB)]:36 = nodeCapacity:120 - nodeReservation:24 - systemReserved:0 - podHPRequest:60", + Message: "batchAllocatable[Mem(GB)]:36 = nodeCapacity:120 - nodeSafetyMargin:24 - nodeReserved:0 - podHPRequest:60", }, { Name: extension.MidCPU, @@ -1018,12 +1021,12 @@ func Test_calculateNodeResource(t *testing.T) { { Name: extension.BatchCPU, Quantity: resource.NewQuantity(25000, resource.DecimalSI), - Message: "batchAllocatable[CPU(Milli-Core)]:25000 = nodeCapacity:100000 - nodeReservation:35000 - systemUsageOrReserved:7000 - podHPUsed:33000", + Message: "batchAllocatable[CPU(Milli-Core)]:25000 = nodeCapacity:100000 - nodeSafetyMargin:35000 - systemUsageOrNodeReserved:7000 - podHPUsed:33000", }, { Name: extension.BatchMemory, Quantity: resource.NewScaledQuantity(33, 9), - Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeReservation:42 - systemUsage:12 - podHPUsed:33", + Message: "batchAllocatable[Mem(GB)]:33 = nodeCapacity:120 - nodeSafetyMargin:42 - systemUsage:12 - podHPUsed:33", }, { Name: extension.MidCPU, @@ -1039,6 +1042,14 @@ func Test_calculateNodeResource(t *testing.T) { }, } + scheme := runtime.NewScheme() + clientgoscheme.AddToScheme(scheme) + slov1alpha1.AddToScheme(scheme) + schedulingv1alpha1.AddToScheme(scheme) + client := fake.NewClientBuilder().WithScheme(scheme).Build() + opt := framework.NewOption().WithClient(client).WithScheme(scheme).WithControllerBuilder(&builder.Builder{}) + framework.RunSetupExtenders(opt) + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { memoryCalculateByReq := configuration.CalculateByPodRequest From c875583b99599c59e155aad2ca5080c1013a7d04 Mon Sep 17 00:00:00 2001 From: Siyu Wang Date: Mon, 8 Apr 2024 20:24:31 +0800 Subject: [PATCH 26/36] CI workflow with codecov token (#1989) Signed-off-by: Siyu Wang Signed-off-by: george --- .github/workflows/ci.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index eed4fb752..45026ce2f 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -70,10 +70,11 @@ jobs: ${{ matrix.command }} - if: matrix.step == 'test' name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: + token: ${{ secrets.CODECOV_TOKEN }} flags: unittests file: cover.out fail_ci_if_error: true From e60793fb6f0381ae80d4e56a3bf95a43726cccdb Mon Sep 17 00:00:00 2001 From: ls-2018 Date: Mon, 8 Apr 2024 20:39:31 +0800 Subject: [PATCH 27/36] chores: fix some fmt err (#1970) Signed-off-by: acejilam Signed-off-by: george --- pkg/descheduler/controllers/migration/evict.go | 2 +- .../collectors/coldmemoryresource/cold_page_kidled.go | 4 ++-- pkg/koordlet/qosmanager/framework/pod_qos_control.go | 2 +- pkg/koordlet/qosmanager/plugins/cpuevict/cpu_evict.go | 4 ++-- pkg/koordlet/qosmanager/plugins/cpusuppress/cpu_suppress.go | 2 +- pkg/koordlet/runtimehooks/hooks/coresched/helper.go | 5 ++--- pkg/koordlet/runtimehooks/hooks/groupidentity/rule.go | 2 +- pkg/koordlet/runtimehooks/protocol/container_context.go | 6 +++--- pkg/koordlet/runtimehooks/rule/rule.go | 2 +- pkg/koordlet/statesinformer/impl/callback_runner.go | 2 +- pkg/koordlet/statesinformer/impl/states_pods.go | 2 +- pkg/koordlet/util/meminfo.go | 2 +- pkg/koordlet/util/system/config.go | 2 +- pkg/util/httputil/reverseproxy.go | 2 +- pkg/util/metrics/expire_metric.go | 4 ++-- pkg/webhook/api_debug_server.go | 2 +- pkg/webhook/pod/mutating/extended_resource_spec.go | 2 +- 17 files changed, 23 insertions(+), 24 deletions(-) diff --git a/pkg/descheduler/controllers/migration/evict.go b/pkg/descheduler/controllers/migration/evict.go index 3f5b7ae63..91dca072d 100644 --- a/pkg/descheduler/controllers/migration/evict.go +++ b/pkg/descheduler/controllers/migration/evict.go @@ -83,7 +83,7 @@ func CreatePodMigrationJob(ctx context.Context, pod *corev1.Pod, evictOptions fr err := client.Create(ctx, job) if err != nil { - klog.Errorf("Failed to create PodMigrationJob for Pod %s/s, err: %v", pod.Namespace, pod.Name, err) + klog.Errorf("Failed to create PodMigrationJob for Pod %s/%s, err: %v", pod.Namespace, pod.Name, err) return err } return nil diff --git a/pkg/koordlet/metricsadvisor/collectors/coldmemoryresource/cold_page_kidled.go b/pkg/koordlet/metricsadvisor/collectors/coldmemoryresource/cold_page_kidled.go index 173dba936..a3919e97e 100644 --- a/pkg/koordlet/metricsadvisor/collectors/coldmemoryresource/cold_page_kidled.go +++ b/pkg/koordlet/metricsadvisor/collectors/coldmemoryresource/cold_page_kidled.go @@ -64,12 +64,12 @@ func (k *kidledcoldPageCollector) Enabled() bool { kidledConfig := system.NewDefaultKidledConfig() err := system.SetKidledScanPeriodInSeconds(kidledConfig.ScanPeriodInseconds) if err != nil { - klog.V(4).Infof("cold page collector start kidled err:", err) + klog.V(4).Infof("cold page collector start kidled err: %v", err) return false } err = system.SetKidledUseHierarchy(kidledConfig.UseHierarchy) if err != nil { - klog.V(4).Infof("cold page collector start kidled err:", err) + klog.V(4).Infof("cold page collector start kidled err: %v", err) return false } system.SetIsStartColdMemory(true) diff --git a/pkg/koordlet/qosmanager/framework/pod_qos_control.go b/pkg/koordlet/qosmanager/framework/pod_qos_control.go index a8e682f35..fc2d9059d 100644 --- a/pkg/koordlet/qosmanager/framework/pod_qos_control.go +++ b/pkg/koordlet/qosmanager/framework/pod_qos_control.go @@ -61,7 +61,7 @@ func InjectQOSGreyCtrlPlugins(pod *corev1.Pod, policyType QOSPolicyType, policy klog.Warningf("running qos grey control plugin %v for pod %v failed", name, util.GetPodKey(pod)) } else if pluginInjected { klog.V(5).Infof("running qos grey control plugin %v for pod %v success, policy detail %v", - name, util.GetPodKey(pod)) + name, util.GetPodKey(pod), policy) injected = true } } diff --git a/pkg/koordlet/qosmanager/plugins/cpuevict/cpu_evict.go b/pkg/koordlet/qosmanager/plugins/cpuevict/cpu_evict.go index 23e0898bd..ffe5e5f91 100644 --- a/pkg/koordlet/qosmanager/plugins/cpuevict/cpu_evict.go +++ b/pkg/koordlet/qosmanager/plugins/cpuevict/cpu_evict.go @@ -218,7 +218,7 @@ func (c *cpuEvictor) calculateMilliRelease(thresholdConfig *slov1alpha1.Resource if milliRelease > 0 { klog.V(4).Infof("cpuEvict by ResourceSatisfaction start to evict, milliRelease: %v,"+ "current status (BEUsage:%v, BERequest:%v, BELimit:%v, BERealLimit:%v, BEAllocatable:%v)", - currentBECPUMilliUsage, currentBECPUMilliRequest, currentBECPUMilliLimit, currentBECPUMilliRealLimit, + milliRelease, currentBECPUMilliUsage, currentBECPUMilliRequest, currentBECPUMilliLimit, currentBECPUMilliRealLimit, beCPUMilliAllocatable) } return milliRelease @@ -305,7 +305,7 @@ func (c *cpuEvictor) killAndEvictBEPodsRelease(node *corev1.Node, bePodInfos []* killedPods = append(killedPods, bePod.pod) cpuMilliReleased = cpuMilliReleased + bePod.milliRequest - klog.V(5).Infof("cpuEvict pick pod %s/%s to evict", util.GetPodKey(bePod.pod)) + klog.V(5).Infof("cpuEvict pick pod %s to evict", util.GetPodKey(bePod.pod)) } c.evictor.EvictPodsIfNotEvicted(killedPods, node, resourceexecutor.EvictPodByBECPUSatisfaction, message) diff --git a/pkg/koordlet/qosmanager/plugins/cpusuppress/cpu_suppress.go b/pkg/koordlet/qosmanager/plugins/cpusuppress/cpu_suppress.go index e9046382c..3e6601801 100644 --- a/pkg/koordlet/qosmanager/plugins/cpusuppress/cpu_suppress.go +++ b/pkg/koordlet/qosmanager/plugins/cpusuppress/cpu_suppress.go @@ -453,7 +453,7 @@ func (r *CPUSuppress) recoverCPUSetForBECPUManager() { } resourceStatus, err := apiext.GetResourceStatus(podMeta.Pod.Annotations) if err != nil { - klog.Warningf("get resource status for pod %s failed, error %v", podMeta.Key()) + klog.Warningf("get resource status for pod %s failed, error %v", podMeta.Key(), err.Error()) continue } diff --git a/pkg/koordlet/runtimehooks/hooks/coresched/helper.go b/pkg/koordlet/runtimehooks/hooks/coresched/helper.go index f98e68ec0..ac9616009 100644 --- a/pkg/koordlet/runtimehooks/hooks/coresched/helper.go +++ b/pkg/koordlet/runtimehooks/hooks/coresched/helper.go @@ -126,8 +126,7 @@ func (p *Plugin) addCookie(pids []uint32, groupID string) (uint64, []uint32, err // TODO: refactor to resource updater. func (p *Plugin) assignCookie(pids, siblingPIDs []uint32, groupID string, targetCookieID uint64) ([]uint32, []uint32, error) { if len(pids) <= 0 { - klog.V(6).Infof("aborted to assign PIDs cookie for group %s, target cookie %v, no PID", - targetCookieID, groupID) + klog.V(6).Infof("aborted to assign PIDs cookie for group %v, target cookie %v, no PID", groupID, targetCookieID) return nil, nil, nil } pidsToAssign := NewPIDCache() @@ -225,7 +224,7 @@ func (p *Plugin) clearCookie(pids []uint32, groupID string, lastCookieID uint64) failedPIDs, err := p.cse.Clear(sysutil.CoreSchedScopeThreadGroup, pidsToClear.GetAllSorted()...) if err != nil { - klog.V(4).Infof("failed to clear cookie for group, last cookie %v, PID %v failed of %v, total %v, err: %s", + klog.V(4).Infof("failed to clear cookie for group %v, last cookie %v, PID %v failed of %v, total %v, err: %s", groupID, lastCookieID, len(failedPIDs), pidsToClear.GetAllSorted(), len(pids), err) pidsToClear.DeleteAny(failedPIDs...) } diff --git a/pkg/koordlet/runtimehooks/hooks/groupidentity/rule.go b/pkg/koordlet/runtimehooks/hooks/groupidentity/rule.go index 4f2b1c761..3d25138ce 100644 --- a/pkg/koordlet/runtimehooks/hooks/groupidentity/rule.go +++ b/pkg/koordlet/runtimehooks/hooks/groupidentity/rule.go @@ -212,7 +212,7 @@ func (b *bvtPlugin) ruleUpdateCb(target *statesinformer.CallbackTarget) error { kubeQOSParentDir := koordletutil.GetPodQoSRelativePath(kubeQOS) podCgroupDirs, err := koordletutil.GetCgroupPathsByTargetDepth(sysutil.CPUBVTWarpNsName, kubeQOSParentDir, koordletutil.PodCgroupPathRelativeDepth) if err != nil { - klog.Infof("get pod cgroup paths failed, qos %s, err: %w", kubeQOS, err) + klog.Infof("get pod cgroup paths failed, qos %s, err: %v", kubeQOS, err.Error()) continue } for _, cgroupDir := range podCgroupDirs { diff --git a/pkg/koordlet/runtimehooks/protocol/container_context.go b/pkg/koordlet/runtimehooks/protocol/container_context.go index 7ade6ac45..1d85ab009 100644 --- a/pkg/koordlet/runtimehooks/protocol/container_context.go +++ b/pkg/koordlet/runtimehooks/protocol/container_context.go @@ -92,7 +92,7 @@ func (c *ContainerRequest) FromNri(pod *api.PodSandbox, container *api.Container spec, err := apiext.GetExtendedResourceSpec(pod.GetAnnotations()) if err != nil { - klog.V(4).Infof("failed to get ExtendedResourceSpec from nri via annotation, container %s/%s, err: %s", + klog.V(4).Infof("failed to get ExtendedResourceSpec from nri via annotation, container %s/%s, name: %s, err: %s", c.PodMeta.Namespace, c.PodMeta.Name, c.ContainerMeta.Name, err) } if spec != nil && spec.Containers != nil { @@ -112,7 +112,7 @@ func (c *ContainerRequest) FromProxy(req *runtimeapi.ContainerResourceHookReques // retrieve ExtendedResources from pod annotations spec, err := apiext.GetExtendedResourceSpec(req.GetPodAnnotations()) if err != nil { - klog.V(4).Infof("failed to get ExtendedResourceSpec from proxy via annotation, container %s/%s, err: %s", + klog.V(4).Infof("failed to get ExtendedResourceSpec from proxy via annotation, container %s/%s, name: %s, err: %s", c.PodMeta.Namespace, c.PodMeta.Name, c.ContainerMeta.Name, err) } if spec != nil && spec.Containers != nil { @@ -166,7 +166,7 @@ func (c *ContainerRequest) FromReconciler(podMeta *statesinformer.PodMeta, conta // retrieve ExtendedResources from container spec and pod annotations (prefer container spec) specFromAnnotations, err := apiext.GetExtendedResourceSpec(podMeta.Pod.Annotations) if err != nil { - klog.V(4).Infof("failed to get ExtendedResourceSpec from reconciler via annotation, container %s/%s, err: %s", + klog.V(4).Infof("failed to get ExtendedResourceSpec from reconciler via annotation, container %s/%s, name: %s, err: %s", c.PodMeta.Namespace, c.PodMeta.Name, c.ContainerMeta.Name, err) } if specFromContainer != nil { diff --git a/pkg/koordlet/runtimehooks/rule/rule.go b/pkg/koordlet/runtimehooks/rule/rule.go index de680010d..90a0f0a45 100644 --- a/pkg/koordlet/runtimehooks/rule/rule.go +++ b/pkg/koordlet/runtimehooks/rule/rule.go @@ -65,7 +65,7 @@ func (r *Rule) runUpdateCallbacks(target *statesinformer.CallbackTarget) { for _, callbackFn := range r.callbacks { if err := callbackFn(target); err != nil { cbName := runtime.FuncForPC(reflect.ValueOf(callbackFn).Pointer()).Name() - klog.Warningf("executing %s callback function %s failed, error %v", r.name, cbName) + klog.Warningf("executing %s callback function %s failed, error %v", r.name, cbName, err.Error()) } } } diff --git a/pkg/koordlet/statesinformer/impl/callback_runner.go b/pkg/koordlet/statesinformer/impl/callback_runner.go index 7567002bc..0c30e83bc 100644 --- a/pkg/koordlet/statesinformer/impl/callback_runner.go +++ b/pkg/koordlet/statesinformer/impl/callback_runner.go @@ -117,7 +117,7 @@ func (s *callbackRunner) Start(stopCh <-chan struct{}) { case cbCtx := <-s.callbackChans[cbType]: cbObj := s.getObjByType(cbType, cbCtx) if cbObj == nil { - klog.Warningf("callback runner with type %v is not exist") + klog.Warningf("callback runner with type %T is not exist", cbObj) } else { s.runCallbacks(cbType, cbObj) } diff --git a/pkg/koordlet/statesinformer/impl/states_pods.go b/pkg/koordlet/statesinformer/impl/states_pods.go index 7287ff27e..7da62dbf1 100644 --- a/pkg/koordlet/statesinformer/impl/states_pods.go +++ b/pkg/koordlet/statesinformer/impl/states_pods.go @@ -117,7 +117,7 @@ func (s *podsInformer) Start(stopCh <-chan struct{}) { go s.syncKubeletLoop(s.config.KubeletSyncInterval, stopCh) go func() { if err := s.pleg.Run(stopCh); err != nil { - klog.Fatalf("Unable to run the pleg: ", err) + klog.Fatalf("Unable to run the pleg: %v", err.Error()) } }() diff --git a/pkg/koordlet/util/meminfo.go b/pkg/koordlet/util/meminfo.go index 7bdcd3fb9..1dcdc7bf3 100644 --- a/pkg/koordlet/util/meminfo.go +++ b/pkg/koordlet/util/meminfo.go @@ -176,7 +176,7 @@ func GetHugePagesInfo(nodeDir string) (map[uint64]*HugePagesInfo, error) { hugepageDir := system.GetNUMAHugepagesDir(nodeDir) hugeDirs, err := os.ReadDir(hugepageDir) if err != nil { - klog.Warningf("failed to read hugepage dir %s, err: %w", hugepageDir, err) + klog.Warningf("failed to read hugepage dir %s, err: %v", hugepageDir, err) return hugePagesInfo, err } diff --git a/pkg/koordlet/util/system/config.go b/pkg/koordlet/util/system/config.go index 45a3e4231..dc50f3ef6 100644 --- a/pkg/koordlet/util/system/config.go +++ b/pkg/koordlet/util/system/config.go @@ -69,7 +69,7 @@ func InitSupportConfigs() { initCgroupsVersion() HostSystemInfo = collectVersionInfo() if isResctrlSupported, err := IsSupportResctrl(); err != nil { - klog.Warningf("failed to check resctrl support status, use %d, err: %v", isResctrlSupported, err) + klog.Warningf("failed to check resctrl support status, use %v, err: %v", isResctrlSupported, err) } else { klog.V(4).Infof("resctrl supported: %v", isResctrlSupported) } diff --git a/pkg/util/httputil/reverseproxy.go b/pkg/util/httputil/reverseproxy.go index 05ab304c9..92e0c08c6 100644 --- a/pkg/util/httputil/reverseproxy.go +++ b/pkg/util/httputil/reverseproxy.go @@ -596,7 +596,7 @@ func (p *ReverseProxy) handleUpgradeResponse(rw http.ResponseWriter, req *http.R conn, brw, err := hj.Hijack() if err != nil { - p.getErrorHandler()(rw, req, fmt.Errorf("Hijack failed on protocol switch: %v", err)) + p.getErrorHandler()(rw, req, fmt.Errorf("hijack failed on protocol switch: %v", err)) return } defer conn.Close() diff --git a/pkg/util/metrics/expire_metric.go b/pkg/util/metrics/expire_metric.go index 53519fffa..17cb8ea61 100644 --- a/pkg/util/metrics/expire_metric.go +++ b/pkg/util/metrics/expire_metric.go @@ -253,7 +253,7 @@ func (e *metricGC) UpdateStatus(metricName string, labels prometheus.Labels) { err := e.updateStatus(time.Now().Unix(), metricName, labels) e.globalLock.RUnlock() if err != nil { - klog.Errorf("failed to update status for metric %s, err: %s", metricName) + klog.Errorf("failed to update status for metric %s, err: %s", metricName, err.Error()) } } @@ -271,7 +271,7 @@ func (e *metricGC) RemoveStatus(metricName string, labels prometheus.Labels) { err := e.removeStatus(metricName, labels) e.globalLock.RUnlock() if err != nil { - klog.Errorf("failed to remove status for metric %s, err: %s", metricName) + klog.Errorf("failed to remove status for metric %s, err: %s", metricName, err.Error()) } } diff --git a/pkg/webhook/api_debug_server.go b/pkg/webhook/api_debug_server.go index 820b6710c..c36e29bec 100644 --- a/pkg/webhook/api_debug_server.go +++ b/pkg/webhook/api_debug_server.go @@ -32,6 +32,6 @@ func RegisterDebugAPIProvider(name string, provider http.Handler) { func InstallDebugAPIHandler(server *webhook.Server) { for name, provider := range debugAPIProviderMap { server.Register(name, provider) - klog.Infof("Success register debug api handler, name:%v, tcpAddr:%v", name) + klog.Infof("Success register debug api handler, name:%v, tcpAddr:%s:%d", name, server.Host, server.Port) } } diff --git a/pkg/webhook/pod/mutating/extended_resource_spec.go b/pkg/webhook/pod/mutating/extended_resource_spec.go index 3a3c072cb..b50e8963e 100644 --- a/pkg/webhook/pod/mutating/extended_resource_spec.go +++ b/pkg/webhook/pod/mutating/extended_resource_spec.go @@ -67,7 +67,7 @@ func (h *PodMutatingHandler) mutateByExtendedResources(pod *corev1.Pod) error { } if reflect.DeepEqual(extendedResourceSpec, spec) { // if resource requirements not changed, just return - klog.V(6).Infof("extended resource spec of pod %s/%s unchanged, skip patch the annotation") + klog.V(6).Infof("extended resource spec of pod %s/%s unchanged, skip patch the annotation", pod.Namespace, pod.Name) return nil } From fbdc1e065fddca2b1e0242d64076455a64a592e8 Mon Sep 17 00:00:00 2001 From: wangjianyu Date: Tue, 9 Apr 2024 11:52:32 +0800 Subject: [PATCH 28/36] Revert "scheduler: pick vf by random (#1953)" (#1986) Signed-off-by: wangjianyu.wjy Co-authored-by: wangjianyu.wjy Signed-off-by: george --- pkg/scheduler/plugins/deviceshare/device_allocator.go | 8 +------- .../plugins/deviceshare/device_allocator_test.go | 6 ------ 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/pkg/scheduler/plugins/deviceshare/device_allocator.go b/pkg/scheduler/plugins/deviceshare/device_allocator.go index 0bf5d9304..99c791fbd 100644 --- a/pkg/scheduler/plugins/deviceshare/device_allocator.go +++ b/pkg/scheduler/plugins/deviceshare/device_allocator.go @@ -18,7 +18,6 @@ package deviceshare import ( "fmt" - "math/rand" "sort" corev1 "k8s.io/api/core/v1" @@ -34,10 +33,6 @@ import ( "github.com/koordinator-sh/koordinator/pkg/util/bitmask" ) -var ( - randIntnFn = rand.Intn -) - var deviceHandlers = map[schedulingv1alpha1.DeviceType]DeviceHandler{} var deviceAllocators = map[schedulingv1alpha1.DeviceType]DeviceAllocator{} @@ -489,11 +484,10 @@ func allocateVF(vfAllocation *VFAllocation, deviceInfos map[int]*schedulingv1alp if len(remainingVFs) == 0 { return nil } - // Here we sort the remaining vf just for test deterministic. In fact, we pick the vf by random to alleviating some unexpected vf duplicate allocation problem due to uncoordinated scheduling and node-side vf allocation components sort.Slice(remainingVFs, func(i, j int) bool { return remainingVFs[i].BusID < remainingVFs[j].BusID }) - vf := &remainingVFs[randIntnFn(len(remainingVFs))] + vf := &remainingVFs[0] return vf } diff --git a/pkg/scheduler/plugins/deviceshare/device_allocator_test.go b/pkg/scheduler/plugins/deviceshare/device_allocator_test.go index ea0198ef9..629fea82a 100644 --- a/pkg/scheduler/plugins/deviceshare/device_allocator_test.go +++ b/pkg/scheduler/plugins/deviceshare/device_allocator_test.go @@ -866,9 +866,6 @@ func TestAutopilotAllocator(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - randIntnFn = func(n int) int { - return 0 - } deviceCR := tt.deviceCR.DeepCopy() deviceCR.ResourceVersion = "1" koordFakeClient := koordfake.NewSimpleClientset() @@ -1706,9 +1703,6 @@ func TestAutopilotAllocatorWithExclusivePolicyAndRequiredScope(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - randIntnFn = func(n int) int { - return 0 - } deviceCR := tt.deviceCR.DeepCopy() deviceCR.ResourceVersion = "1" koordFakeClient := koordfake.NewSimpleClientset() From e4c83e665b94fc264623ab060e7866e28269bd68 Mon Sep 17 00:00:00 2001 From: lucming <2876757716@qq.com> Date: Tue, 9 Apr 2024 16:10:32 +0800 Subject: [PATCH 29/36] proposal: tc plugin for netqos (#1976) Signed-off-by: lucming <2876757716@qq.com> Signed-off-by: george --- docs/images/netqos-tc.jpg | Bin 0 -> 73944 bytes docs/images/tcplugin.png | Bin 0 -> 121405 bytes .../koordlet/20231208-support-netqos.md | 98 ++++++++++++++++-- 3 files changed, 88 insertions(+), 10 deletions(-) create mode 100644 docs/images/netqos-tc.jpg create mode 100644 docs/images/tcplugin.png diff --git a/docs/images/netqos-tc.jpg b/docs/images/netqos-tc.jpg new file mode 100644 index 0000000000000000000000000000000000000000..646002abbf8f7e8318c43b011a0089e108afe9c4 GIT binary patch literal 73944 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

AVfBC|=L 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 a!+*W1|1VF)e?w~i|Ih#F7NYuR`u_pvem92z literal 0 HcmV?d00001 diff --git a/docs/images/tcplugin.png b/docs/images/tcplugin.png new file mode 100644 index 0000000000000000000000000000000000000000..3cef4b6b2926c92d83e4913b9c0e39496725335f GIT binary patch literal 121405 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