Skip to content

Commit

Permalink
feat: evict pod only called api successed for cpu eviction
Browse files Browse the repository at this point in the history
Signed-off-by: j4ckstraw <j4ckstraw@foxmail.com>
  • Loading branch information
j4ckstraw committed Jan 5, 2024
1 parent 9ea29ff commit 336f4f9
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 10 deletions.
29 changes: 19 additions & 10 deletions pkg/koordlet/qosmanager/plugins/cpuevict/cpu_evict.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ type cpuEvictor struct {
metricCache metriccache.MetricCache
evictor *framework.Evictor
lastEvictTime time.Time
onlyEvictByAPI bool
}

func New(opt *framework.Options) framework.QOSStrategy {
Expand All @@ -68,6 +69,7 @@ func New(opt *framework.Options) framework.QOSStrategy {
statesInformer: opt.StatesInformer,
metricCache: opt.MetricCache,
lastEvictTime: time.Now(),
onlyEvictByAPI: opt.Config.OnlyEvictByAPI,
}
}

Expand Down Expand Up @@ -292,24 +294,31 @@ func (c *cpuEvictor) killAndEvictBEPodsRelease(node *corev1.Node, bePodInfos []*
node.Name, cpuNeedMilliRelease)

cpuMilliReleased := int64(0)
var killedPods []*corev1.Pod
hasKillPods := false
for _, bePod := range bePodInfos {
if cpuMilliReleased >= cpuNeedMilliRelease {
break
}

podKillMsg := fmt.Sprintf("%s, kill pod: %s", message, util.GetPodKey(bePod.pod))
helpers.KillContainers(bePod.pod, podKillMsg)

killedPods = append(killedPods, bePod.pod)
cpuMilliReleased = cpuMilliReleased + bePod.milliRequest
if c.onlyEvictByAPI {
if c.evictor.EvictPodIfNotEvicted(bePod.pod, node, resourceexecutor.EvictPodByBECPUSatisfaction, message) {
cpuMilliReleased = cpuMilliReleased + bePod.milliRequest
klog.V(5).Infof("cpuEvict pick pod %s to evict", util.GetPodKey(bePod.pod))
hasKillPods = true
} else {
klog.V(5).Infof("cpuEvict pick pod %s to evict, failed", util.GetPodKey(bePod.pod))
}
} else {
podKillMsg := fmt.Sprintf("%s, kill pod: %s", message, util.GetPodKey(bePod.pod))
helpers.KillContainers(bePod.pod, podKillMsg)

klog.V(5).Infof("cpuEvict pick pod %s/%s to evict", util.GetPodKey(bePod.pod))
cpuMilliReleased = cpuMilliReleased + bePod.milliRequest
klog.V(5).Infof("cpuEvict pick pod %s to evict", util.GetPodKey(bePod.pod))
hasKillPods = true
}
}

c.evictor.EvictPodsIfNotEvicted(killedPods, node, resourceexecutor.EvictPodByBECPUSatisfaction, message)

if len(killedPods) > 0 {
if hasKillPods {
c.lastEvictTime = time.Now()
}
klog.V(5).Infof("killAndEvictBEPodsRelease finished! cpuNeedMilliRelease(%d) cpuMilliReleased(%d)",
Expand Down
59 changes: 59 additions & 0 deletions pkg/koordlet/qosmanager/plugins/cpuevict/cpu_evict_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,65 @@ func Test_killAndEvictBEPodsRelease(t *testing.T) {

cpuEvictor.killAndEvictBEPodsRelease(node, podEvictInfosSorted, 18*1000)

getNotEvictObject, err := client.Tracker().Get(testutil.PodsResource, podEvictInfosSorted[2].pod.Namespace, podEvictInfosSorted[2].pod.Name)
assert.Nil(t, err, "get pod fail", err)
assert.IsType(t, &corev1.Pod{}, getNotEvictObject, "no need evict", podEvictInfosSorted[2].pod.Name)
assert.True(t, cpuEvictor.lastEvictTime.After(time.Now().Add(-5*time.Second)), "checkLastTime")
}

func Test_killAndEvictBEPodsReleaseWithEvictionAPIOnly(t *testing.T) {
podEvictInfosSorted := []*podEvictCPUInfo{
{
pod: mockBEPodForCPUEvict("pod_be_3_priority10", 16*1000, 10),
milliRequest: 16 * 1000,
},
{
pod: mockBEPodForCPUEvict("pod_be_2_priority100", 16*1000, 100),
milliRequest: 16 * 1000,
},
{
pod: mockBEPodForCPUEvict("pod_be_1_priority100", 16*1000, 100),
milliRequest: 16 * 1000,
},
}

ctl := gomock.NewController(t)
defer ctl.Finish()

fakeRecorder := &testutil.FakeRecorder{}
client := clientsetfake.NewSimpleClientset()

stop := make(chan struct{})
evictor := framework.NewEvictor(client, fakeRecorder, policyv1beta1.SchemeGroupVersion.Version)
evictor.Start(stop)
defer func() { stop <- struct{}{} }()

node := testutil.MockTestNode("100", "500G")
runtime.DockerHandler = handler.NewFakeRuntimeHandler()
// create pod
var containers []*critesting.FakeContainer
for _, podInfo := range podEvictInfosSorted {
pod := podInfo.pod
_, _ = client.CoreV1().Pods(pod.Namespace).Create(context.TODO(), pod, metav1.CreateOptions{})
for _, containerStatus := range pod.Status.ContainerStatuses {
_, containerId, _ := util.ParseContainerId(containerStatus.ContainerID)
fakeContainer := &critesting.FakeContainer{
SandboxID: string(pod.UID),
ContainerStatus: runtimeapi.ContainerStatus{Id: containerId},
}
containers = append(containers, fakeContainer)
}
}
runtime.DockerHandler.(*handler.FakeRuntimeHandler).SetFakeContainers(containers)

cpuEvictor := &cpuEvictor{
evictor: evictor,
onlyEvictByAPI: true,
lastEvictTime: time.Now().Add(-5 * time.Minute),
}

cpuEvictor.killAndEvictBEPodsRelease(node, podEvictInfosSorted, 18*1000)

getEvictObject, err := client.Tracker().Get(testutil.PodsResource, podEvictInfosSorted[0].pod.Namespace, podEvictInfosSorted[0].pod.Name)
assert.NotNil(t, getEvictObject, "evictPod Fail, err: %v", err)
assert.IsType(t, &policyv1beta1.Eviction{}, getEvictObject, "evictPod: %s Fail", podEvictInfosSorted[0].pod.Name)
Expand Down

0 comments on commit 336f4f9

Please sign in to comment.