@@ -37,6 +37,7 @@ import (
3737 clocks "k8s.io/utils/clock"
3838
3939 "github.com/kubewharf/katalyst-api/pkg/apis/node/v1alpha1"
40+ apiconsts "github.com/kubewharf/katalyst-api/pkg/consts"
4041 "github.com/kubewharf/katalyst-api/pkg/plugins/registration"
4142 pluginapi "github.com/kubewharf/katalyst-api/pkg/protocol/evictionplugin/v1alpha1"
4243 endpointpkg "github.com/kubewharf/katalyst-core/pkg/agent/evictionmanager/endpoint"
@@ -46,6 +47,7 @@ import (
4647 "github.com/kubewharf/katalyst-core/pkg/agent/evictionmanager/plugin/resource"
4748 "github.com/kubewharf/katalyst-core/pkg/agent/evictionmanager/plugin/rootfs"
4849 "github.com/kubewharf/katalyst-core/pkg/agent/evictionmanager/podkiller"
50+ "github.com/kubewharf/katalyst-core/pkg/agent/evictionmanager/podnotifier"
4951 "github.com/kubewharf/katalyst-core/pkg/agent/evictionmanager/record"
5052 "github.com/kubewharf/katalyst-core/pkg/agent/evictionmanager/rule"
5153 "github.com/kubewharf/katalyst-core/pkg/client"
@@ -109,7 +111,8 @@ type EvictionManger struct {
109111 // easy to test the code.
110112 clock clocks.WithTickerAndDelayedExecution
111113
112- podKiller podkiller.PodKiller
114+ podNotifier podnotifier.PodNotifier
115+ podKiller podkiller.PodKiller
113116
114117 killQueue rule.EvictionQueue
115118 killStrategy rule.EvictionStrategy
@@ -236,6 +239,12 @@ func NewEvictionManager(genericClient *client.GenericClientSet, recorder events.
236239
237240 podKiller := podkiller .NewAsynchronizedPodKiller (killer , metaServer .PodFetcher , genericClient .KubeClient )
238241
242+ notifier , err := podnotifier .NewHostPathPodNotifier (conf , genericClient .KubeClient , metaServer , recorder , emitter )
243+ if err != nil {
244+ return nil , fmt .Errorf ("failed to create pod notifier: %v" , err )
245+ }
246+ podNotifier := podnotifier .NewSynchronizedPodNotifier (notifier )
247+
239248 cnrTaintReporter , err := control .NewGenericReporterPlugin (cnrTaintReporterPluginName , conf , emitter )
240249 if err != nil {
241250 return nil , fmt .Errorf ("failed to initialize cnr taint reporter plugin: %v" , err )
@@ -264,6 +273,7 @@ func NewEvictionManager(genericClient *client.GenericClientSet, recorder events.
264273 metaGetter : metaServer ,
265274 emitter : emitter ,
266275 podKiller : podKiller ,
276+ podNotifier : podNotifier ,
267277 cnrTaintReporter : cnrTaintReporter ,
268278 endpoints : make (map [string ]endpointpkg.Endpoint ),
269279 conf : conf ,
@@ -317,6 +327,7 @@ func (m *EvictionManger) Run(ctx context.Context) {
317327 general .RegisterHeartbeatCheck (reportTaintHealthCheckName , reportTaintToleration ,
318328 general .HealthzCheckStateNotReady , reportTaintToleration )
319329 m .podKiller .Start (ctx )
330+ m .podNotifier .Start (ctx )
320331 for _ , endpoint := range m .endpoints {
321332 endpoint .Start ()
322333 }
@@ -360,6 +371,11 @@ func (m *EvictionManger) sync(ctx context.Context) {
360371 }
361372
362373 errList := make ([]error , 0 )
374+ notifyErr := m .doNotify (collector .getSoftEvictPods ())
375+ if notifyErr != nil {
376+ errList = append (errList , notifyErr )
377+ }
378+
363379 evictErr := m .doEvict (collector .getSoftEvictPods (), collector .getForceEvictPods ())
364380 if evictErr != nil {
365381 errList = append (errList , evictErr )
@@ -430,8 +446,8 @@ func (m *EvictionManger) collectEvictionResult(ctx context.Context, pods []*v1.P
430446 records := m .getEvictionRecords (ctx , collector .currentCandidatePods )
431447
432448 for pluginName , threshold := range thresholdsMet {
433- if threshold .MetType != pluginapi .ThresholdMetType_HARD_MET {
434- general .Infof (" the type: %s of met threshold from plugin: %s isn't %s " , threshold . MetType . String (), pluginName , pluginapi . ThresholdMetType_HARD_MET . String () )
449+ if threshold .MetType == pluginapi .ThresholdMetType_NOT_MET {
450+ general .Infof ("resp from plugin: %s not met threshold " , pluginName )
435451 continue
436452 }
437453
@@ -453,13 +469,20 @@ func (m *EvictionManger) collectEvictionResult(ctx context.Context, pods []*v1.P
453469 }
454470 }
455471 }
472+
473+ topN := uint64 (0 )
474+ forceEvict := false
475+ if threshold .MetType == pluginapi .ThresholdMetType_HARD_MET {
476+ topN = 1
477+ forceEvict = true
478+ }
479+
456480 resp , err := m .endpoints [pluginName ].GetTopEvictionPods (context .Background (), & pluginapi.GetTopEvictionPodsRequest {
457481 ActivePods : activePods ,
458- TopN : 1 ,
482+ TopN : topN ,
459483 EvictionScope : threshold .EvictionScope ,
460484 CandidateEvictionRecords : candidateEvictionRecords ,
461485 })
462-
463486 m .endpointLock .RUnlock ()
464487 if err != nil {
465488 general .Errorf (" calling GetTopEvictionPods of plugin: %s failed with error: %v" , pluginName , err )
@@ -473,12 +496,38 @@ func (m *EvictionManger) collectEvictionResult(ctx context.Context, pods []*v1.P
473496 continue
474497 }
475498
476- collector .collectTopEvictionPods (dynamicConfig .DryRun , pluginName , threshold , resp )
499+ if forceEvict {
500+ collector .collectTopEvictionPods (dynamicConfig .DryRun , pluginName , threshold , resp )
501+ } else {
502+ collector .collectTopSoftEvictionPods (dynamicConfig .DryRun , pluginName , threshold , resp )
503+ }
504+
477505 }
478506
479507 return collector , errors .NewAggregate (errList )
480508}
481509
510+ func (m * EvictionManger ) doNotify (softEvictPods map [string ]* rule.RuledEvictPod ) error {
511+ errList := make ([]error , 0 )
512+
513+ for _ , pod := range softEvictPods {
514+ if pod == nil || pod .EvictPod .Pod == nil {
515+ continue
516+ }
517+
518+ if _ , ok := pod .EvictPod .Pod .Annotations [apiconsts .PodAnnotationSoftEvictNotificationKey ]; ! ok {
519+ continue
520+ }
521+
522+ err := m .podNotifier .NotifyPod (pod )
523+ if err != nil {
524+ errList = append (errList , err )
525+ }
526+ }
527+
528+ return errors .NewAggregate (errList )
529+ }
530+
482531func (m * EvictionManger ) doEvict (softEvictPods , forceEvictPods map [string ]* rule.RuledEvictPod ) error {
483532 softEvictPods = filterOutCandidatePodsWithForcePods (softEvictPods , forceEvictPods )
484533 bestSuitedCandidate := m .getEvictPodFromCandidates (softEvictPods )
@@ -637,6 +686,10 @@ func (m *EvictionManger) getEvictPodFromCandidates(candidateEvictPods map[string
637686 for _ , rp := range candidateEvictPods {
638687 // only killing pods that pass candidate validation
639688 if rp != nil && rp .Pod != nil && m .killStrategy .CandidateValidate (rp ) {
689+ // do NOT select soft evict pod with notification-enable as candidate
690+ if _ , ok := rp .Pod .Annotations [apiconsts .PodAnnotationSoftEvictNotificationKey ]; ok {
691+ continue
692+ }
640693 rpList = append (rpList , rp )
641694 }
642695 }
0 commit comments