332 lines
12 KiB
Diff
332 lines
12 KiB
Diff
|
|
From 15aafa185d19c34d02c6e7a459d997f3751b410d Mon Sep 17 00:00:00 2001
|
||
|
|
From: vegbir <yangjiaqi16@huawei.com>
|
||
|
|
Date: Thu, 21 Nov 2024 15:02:45 +0000
|
||
|
|
Subject: [PATCH] rubik: remove duplicate log
|
||
|
|
|
||
|
|
Signed-off-by: vegbir <yangjiaqi16@huawei.com>
|
||
|
|
---
|
||
|
|
pkg/core/trigger/common/type.go | 1 -
|
||
|
|
pkg/core/trigger/executor/resource.go | 12 ++++++------
|
||
|
|
pkg/core/trigger/template/base.go | 8 --------
|
||
|
|
pkg/core/typedef/containerinfo.go | 11 +++++------
|
||
|
|
pkg/core/typedef/rawpod.go | 14 ++++++--------
|
||
|
|
pkg/resource/analyze/analyzer.go | 9 +++++----
|
||
|
|
pkg/services/eviction/common/manager.go | 15 +++++++++++----
|
||
|
|
pkg/services/eviction/cpu/cpu.go | 19 ++++++++++---------
|
||
|
|
pkg/services/eviction/memory/memory.go | 13 +++++++------
|
||
|
|
9 files changed, 50 insertions(+), 52 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/pkg/core/trigger/common/type.go b/pkg/core/trigger/common/type.go
|
||
|
|
index 901ca0d..5bfa5eb 100644
|
||
|
|
--- a/pkg/core/trigger/common/type.go
|
||
|
|
+++ b/pkg/core/trigger/common/type.go
|
||
|
|
@@ -22,7 +22,6 @@ type (
|
||
|
|
|
||
|
|
const (
|
||
|
|
TARGETPODS Factor = iota
|
||
|
|
- DEPORTPOD
|
||
|
|
)
|
||
|
|
|
||
|
|
// Descriptor defines methods for describing triggers
|
||
|
|
diff --git a/pkg/core/trigger/executor/resource.go b/pkg/core/trigger/executor/resource.go
|
||
|
|
index 46731dd..2f28271 100644
|
||
|
|
--- a/pkg/core/trigger/executor/resource.go
|
||
|
|
+++ b/pkg/core/trigger/executor/resource.go
|
||
|
|
@@ -36,7 +36,7 @@ func MaxValueTransformer(cal analyze.Calculator) template.Transformation {
|
||
|
|
|
||
|
|
pods, ok := ctx.Value(common.TARGETPODS).(map[string]*typedef.PodInfo)
|
||
|
|
if !ok {
|
||
|
|
- return ctx, fmt.Errorf("failed to get target pods")
|
||
|
|
+ return ctx, fmt.Errorf("invalid target pod type")
|
||
|
|
}
|
||
|
|
|
||
|
|
for _, pod := range pods {
|
||
|
|
@@ -54,12 +54,12 @@ func MaxValueTransformer(cal analyze.Calculator) template.Transformation {
|
||
|
|
chosen = pod
|
||
|
|
}
|
||
|
|
}
|
||
|
|
-
|
||
|
|
- if chosen != nil {
|
||
|
|
- log.Infof("find the pod(%v) with the highest utilization(%v)", chosen.Name, maxValue)
|
||
|
|
- return context.WithValue(ctx, common.TARGETPODS, map[string]*typedef.PodInfo{chosen.Name: chosen}), nil
|
||
|
|
+ // If the object is successfully obtained, the object is returned, otherwise an empty object is returned
|
||
|
|
+ if chosen == nil {
|
||
|
|
+ return context.WithValue(ctx, common.TARGETPODS, map[string]*typedef.PodInfo{}), nil
|
||
|
|
}
|
||
|
|
- return context.Background(), fmt.Errorf("failed to find target pod")
|
||
|
|
+ log.Infof("find the pod(%v) with the highest utilization(%.2f%%)", chosen.Name, maxValue)
|
||
|
|
+ return context.WithValue(ctx, common.TARGETPODS, map[string]*typedef.PodInfo{chosen.Name: chosen}), nil
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
diff --git a/pkg/core/trigger/template/base.go b/pkg/core/trigger/template/base.go
|
||
|
|
index f627884..9ad61de 100644
|
||
|
|
--- a/pkg/core/trigger/template/base.go
|
||
|
|
+++ b/pkg/core/trigger/template/base.go
|
||
|
|
@@ -55,10 +55,6 @@ func transform(ctx context.Context, f Transformation) (context.Context, error) {
|
||
|
|
if f == nil {
|
||
|
|
return nil, fmt.Errorf("podFilter method is not implemented")
|
||
|
|
}
|
||
|
|
- // pods, ok := ctx.Value(common.TARGETPODS).(map[string]*typedef.PodInfo)
|
||
|
|
- // if !ok {
|
||
|
|
- // return ctx, fmt.Errorf("failed to get target pods")
|
||
|
|
- // }
|
||
|
|
ctx, err := f(ctx)
|
||
|
|
if err != nil {
|
||
|
|
return ctx, fmt.Errorf("failed to transform pod: %v", err)
|
||
|
|
@@ -70,10 +66,6 @@ func act(ctx context.Context, f Action) error {
|
||
|
|
if f == nil {
|
||
|
|
return fmt.Errorf("podAction method is not implemented")
|
||
|
|
}
|
||
|
|
- // pods, ok := ctx.Value(common.TARGETPODS).(map[string]*typedef.PodInfo)
|
||
|
|
- // if !ok {
|
||
|
|
- // return nil
|
||
|
|
- // }
|
||
|
|
return f(ctx)
|
||
|
|
}
|
||
|
|
|
||
|
|
diff --git a/pkg/core/typedef/containerinfo.go b/pkg/core/typedef/containerinfo.go
|
||
|
|
index 3c61f08..ee5686b 100644
|
||
|
|
--- a/pkg/core/typedef/containerinfo.go
|
||
|
|
+++ b/pkg/core/typedef/containerinfo.go
|
||
|
|
@@ -89,7 +89,7 @@ func NewContainerInfo(opts ...ConfigOpt) *ContainerInfo {
|
||
|
|
}
|
||
|
|
|
||
|
|
if err := fromRawContainer(ci, conf.rawCont); err != nil {
|
||
|
|
- fmt.Printf("failed to parse raw container: %v", err)
|
||
|
|
+ fmt.Printf("failed to parse raw container: %v\n", err)
|
||
|
|
}
|
||
|
|
fromNRIContainer(ci, conf.nriCont)
|
||
|
|
fromPodCgroupPath(ci, conf.podCgroupPath)
|
||
|
|
@@ -109,17 +109,16 @@ func fromRawContainer(ci *ContainerInfo, rawCont *RawContainer) error {
|
||
|
|
if rawCont == nil {
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
- requests, limits := rawCont.GetResourceMaps()
|
||
|
|
id, err := rawCont.GetRealContainerID()
|
||
|
|
if err != nil {
|
||
|
|
return fmt.Errorf("failed to parse container ID: %v", err)
|
||
|
|
}
|
||
|
|
- if id == "" {
|
||
|
|
- return fmt.Errorf("empty container id")
|
||
|
|
+ // Note that the running pod may have containers that are being deleted or created, and their ids are empty.
|
||
|
|
+ if id != "" {
|
||
|
|
+ ci.ID = id
|
||
|
|
}
|
||
|
|
-
|
||
|
|
ci.Name = rawCont.status.Name
|
||
|
|
- ci.ID = id
|
||
|
|
+ requests, limits := rawCont.GetResourceMaps()
|
||
|
|
ci.RequestResources = requests
|
||
|
|
ci.LimitResources = limits
|
||
|
|
return nil
|
||
|
|
diff --git a/pkg/core/typedef/rawpod.go b/pkg/core/typedef/rawpod.go
|
||
|
|
index ed11c6b..45dbd40 100644
|
||
|
|
--- a/pkg/core/typedef/rawpod.go
|
||
|
|
+++ b/pkg/core/typedef/rawpod.go
|
||
|
|
@@ -147,8 +147,8 @@ func (pod *RawPod) ExtractContainerInfos() map[string]*ContainerInfo {
|
||
|
|
WithRawContainer(rawContainer),
|
||
|
|
WithPodCgroup(pod.CgroupPath()),
|
||
|
|
)
|
||
|
|
+ // The empty ID means that the container is being deleted and no updates are needed.
|
||
|
|
if ci.ID == "" {
|
||
|
|
- fmt.Printf("failed to parse id from raw container\n")
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
idContainersMap[ci.ID] = ci
|
||
|
|
@@ -158,6 +158,10 @@ func (pod *RawPod) ExtractContainerInfos() map[string]*ContainerInfo {
|
||
|
|
|
||
|
|
// GetRealContainerID parses the containerID of k8s
|
||
|
|
func (cont *RawContainer) GetRealContainerID() (string, error) {
|
||
|
|
+ // Empty container ID means the container may be in the creation or deletion phase.
|
||
|
|
+ if cont.status.ContainerID == "" {
|
||
|
|
+ return "", nil
|
||
|
|
+ }
|
||
|
|
/*
|
||
|
|
Note:
|
||
|
|
An UNDEFINED container engine was used when the function was executed for the first time
|
||
|
|
@@ -175,13 +179,7 @@ func (cont *RawContainer) GetRealContainerID() (string, error) {
|
||
|
|
if !currentContainerEngines.Support(cont) {
|
||
|
|
return "", fmt.Errorf("unsupported container engine: %v", cont.status.ContainerID)
|
||
|
|
}
|
||
|
|
-
|
||
|
|
- cid := cont.status.ContainerID[len(currentContainerEngines.Prefix()):]
|
||
|
|
- // the container may be in the creation or deletion phase.
|
||
|
|
- if len(cid) == 0 {
|
||
|
|
- return "", nil
|
||
|
|
- }
|
||
|
|
- return cid, nil
|
||
|
|
+ return cont.status.ContainerID[len(currentContainerEngines.Prefix()):], nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// GetResourceMaps returns the number of requests and limits of CPU and memory resources
|
||
|
|
diff --git a/pkg/resource/analyze/analyzer.go b/pkg/resource/analyze/analyzer.go
|
||
|
|
index 5c85897..20dd7b0 100644
|
||
|
|
--- a/pkg/resource/analyze/analyzer.go
|
||
|
|
+++ b/pkg/resource/analyze/analyzer.go
|
||
|
|
@@ -14,6 +14,8 @@
|
||
|
|
package analyze
|
||
|
|
|
||
|
|
import (
|
||
|
|
+ "runtime"
|
||
|
|
+
|
||
|
|
v2 "github.com/google/cadvisor/info/v2"
|
||
|
|
|
||
|
|
"isula.org/rubik/pkg/common/log"
|
||
|
|
@@ -53,7 +55,7 @@ func (a *Analyzer) CPUCalculatorBuilder(reqOpt *common.GetOption) Calculator {
|
||
|
|
cpuUsageUs = float64(last.Cpu.Usage.Total-penultimate.Cpu.Usage.Total) / nanoToMicro
|
||
|
|
timeDeltaUs = float64(last.Timestamp.Sub(penultimate.Timestamp).Microseconds())
|
||
|
|
)
|
||
|
|
- return util.Div(cpuUsageUs, timeDeltaUs) * percentageRate
|
||
|
|
+ return util.Div(cpuUsageUs, timeDeltaUs) / float64(runtime.NumCPU()) * percentageRate
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -65,7 +67,6 @@ func (a *Analyzer) MemoryCalculatorBuilder(reqOpt *common.GetOption) Calculator
|
||
|
|
)
|
||
|
|
podStats := a.getPodStats("/"+pi.Path, reqOpt)
|
||
|
|
if len(podStats) < miniNum {
|
||
|
|
- log.Errorf("pod %v has no enough memory stats collected, skip it", pi.Name)
|
||
|
|
return -1
|
||
|
|
}
|
||
|
|
return float64(podStats[len(podStats)-1].Memory.Usage) / bytesToMb
|
||
|
|
@@ -75,12 +76,12 @@ func (a *Analyzer) MemoryCalculatorBuilder(reqOpt *common.GetOption) Calculator
|
||
|
|
func (a *Analyzer) getPodStats(cgroupPath string, reqOpt *common.GetOption) []*v2.ContainerStats {
|
||
|
|
infoMap, err := a.GetPodStats(cgroupPath, *reqOpt)
|
||
|
|
if err != nil {
|
||
|
|
- log.Errorf("failed to get cgroup information %v: %v", cgroupPath, err)
|
||
|
|
+ log.Warnf("failed to get cgroup information %v: %v", cgroupPath, err)
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
info, existed := infoMap[cgroupPath]
|
||
|
|
if !existed {
|
||
|
|
- log.Errorf("failed to get cgroup %v from cadvisor", cgroupPath)
|
||
|
|
+ log.Warnf("failed to get cgroup %v from cadvisor", cgroupPath)
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
return info.Stats
|
||
|
|
diff --git a/pkg/services/eviction/common/manager.go b/pkg/services/eviction/common/manager.go
|
||
|
|
index 4758c72..8a30e4b 100644
|
||
|
|
--- a/pkg/services/eviction/common/manager.go
|
||
|
|
+++ b/pkg/services/eviction/common/manager.go
|
||
|
|
@@ -74,7 +74,7 @@ func newCadvisorManager() (resource.Manager, error) {
|
||
|
|
|
||
|
|
// Controller is a controller for different resources
|
||
|
|
type Controller interface {
|
||
|
|
- Start(context.Context, func() error)
|
||
|
|
+ Start(context.Context, func(func() bool) error)
|
||
|
|
Config() interface{}
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -213,12 +213,19 @@ func (m *Manager) Terminate(api.Viewer) error {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
-func (m *Manager) alarm(typ string) func() error {
|
||
|
|
- return func() error {
|
||
|
|
+func (m *Manager) alarm(typ string) func(func() bool) error {
|
||
|
|
+ return func(needEvcit func() bool) error {
|
||
|
|
+ pods := m.viewer.ListPodsWithOptions(priority(false))
|
||
|
|
+ if len(pods) == 0 {
|
||
|
|
+ return nil
|
||
|
|
+ }
|
||
|
|
var (
|
||
|
|
errs error
|
||
|
|
- ctx = context.WithValue(context.Background(), common.TARGETPODS, m.viewer.ListPodsWithOptions(priority(false)))
|
||
|
|
+ ctx = context.WithValue(context.Background(), common.TARGETPODS, pods)
|
||
|
|
)
|
||
|
|
+ if !needEvcit() {
|
||
|
|
+ return nil
|
||
|
|
+ }
|
||
|
|
for _, t := range m.baseMetric.Triggers[typ] {
|
||
|
|
errs = util.AppendErr(errs, t.Activate(ctx))
|
||
|
|
}
|
||
|
|
diff --git a/pkg/services/eviction/cpu/cpu.go b/pkg/services/eviction/cpu/cpu.go
|
||
|
|
index b11d94b..1cdbe7d 100644
|
||
|
|
--- a/pkg/services/eviction/cpu/cpu.go
|
||
|
|
+++ b/pkg/services/eviction/cpu/cpu.go
|
||
|
|
@@ -62,17 +62,14 @@ func fromConfig(name string, f helper.ConfigHandler) (*Controller, error) {
|
||
|
|
}
|
||
|
|
|
||
|
|
// Start loop collects data and performs eviction
|
||
|
|
-func (c *Controller) Start(ctx context.Context, evictor func() error) {
|
||
|
|
+func (c *Controller) Start(ctx context.Context, evictor func(func() bool) error) {
|
||
|
|
wait.Until(
|
||
|
|
func() {
|
||
|
|
c.collect()
|
||
|
|
if atomic.LoadInt32(&c.block) == 1 {
|
||
|
|
return
|
||
|
|
}
|
||
|
|
- if !c.assertWithinLimit() {
|
||
|
|
- return
|
||
|
|
- }
|
||
|
|
- if err := evictor(); err != nil {
|
||
|
|
+ if err := evictor(c.assertWithinLimit); err != nil {
|
||
|
|
log.Errorf("failed to execute cpuevict %v", err)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
@@ -128,16 +125,20 @@ func (c *Controller) averageUsage() float64 {
|
||
|
|
c.RLock()
|
||
|
|
defer c.RUnlock()
|
||
|
|
if len(c.usages) < minUsageLen {
|
||
|
|
- log.Infof("failed to get node cpu usage at %v", time.Now().Format(format))
|
||
|
|
- return 0
|
||
|
|
+ log.Debugf("failed to get node cpu usage at %v", time.Now().Format(format))
|
||
|
|
+ return -1
|
||
|
|
}
|
||
|
|
util := quotaturbo.CalculateUtils(c.usages[0].cpuStats, c.usages[len(c.usages)-1].cpuStats)
|
||
|
|
- log.Debugf("get node cpu usage %v at %v", util, time.Now().Format(format))
|
||
|
|
return util
|
||
|
|
}
|
||
|
|
|
||
|
|
func (c *Controller) assertWithinLimit() bool {
|
||
|
|
- return c.averageUsage() >= float64(c.conf.Threshold)
|
||
|
|
+ util := c.averageUsage()
|
||
|
|
+ if util >= float64(c.conf.Threshold) {
|
||
|
|
+ log.Infof("CPU exceeded: %v%%", util)
|
||
|
|
+ return true
|
||
|
|
+ }
|
||
|
|
+ return false
|
||
|
|
}
|
||
|
|
|
||
|
|
// Config returns the configuration
|
||
|
|
diff --git a/pkg/services/eviction/memory/memory.go b/pkg/services/eviction/memory/memory.go
|
||
|
|
index 9aa82dc..5215a8a 100644
|
||
|
|
--- a/pkg/services/eviction/memory/memory.go
|
||
|
|
+++ b/pkg/services/eviction/memory/memory.go
|
||
|
|
@@ -51,16 +51,13 @@ func fromConfig(name string, f helper.ConfigHandler) (*Controller, error) {
|
||
|
|
}
|
||
|
|
|
||
|
|
// Start loop collects data and performs eviction
|
||
|
|
-func (c *Controller) Start(ctx context.Context, evictor func() error) {
|
||
|
|
+func (c *Controller) Start(ctx context.Context, evictor func(func() bool) error) {
|
||
|
|
wait.Until(
|
||
|
|
func() {
|
||
|
|
if atomic.LoadInt32(&c.block) == 1 {
|
||
|
|
return
|
||
|
|
}
|
||
|
|
- if !c.assertWithinLimit() {
|
||
|
|
- return
|
||
|
|
- }
|
||
|
|
- if err := evictor(); err != nil {
|
||
|
|
+ if err := evictor(c.assertWithinLimit); err != nil {
|
||
|
|
log.Errorf("failed to execute memory evict %v", err)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
@@ -86,7 +83,11 @@ func (c *Controller) assertWithinLimit() bool {
|
||
|
|
log.Errorf("failed to get memory util at %v: %v", time.Now().Format(format), err)
|
||
|
|
return false
|
||
|
|
}
|
||
|
|
- return v.UsedPercent >= float64(c.conf.Threshold)
|
||
|
|
+ if v.UsedPercent >= float64(c.conf.Threshold) {
|
||
|
|
+ log.Infof("Memory exceeded: %v%%", v.UsedPercent)
|
||
|
|
+ return true
|
||
|
|
+ }
|
||
|
|
+ return false
|
||
|
|
}
|
||
|
|
|
||
|
|
// Config returns the configuration
|
||
|
|
--
|
||
|
|
2.45.0
|
||
|
|
|