1
0
mirror of https://github.com/kubernetes-sigs/descheduler.git synced 2026-01-25 20:59:28 +01:00

feature: use contextal logging for plugins

Signed-off-by: googs1025 <googs1025@gmail.com>
This commit is contained in:
googs1025
2025-03-24 20:04:51 +08:00
parent 9f918371a2
commit 33894afe2b
15 changed files with 140 additions and 88 deletions

View File

@@ -29,9 +29,9 @@ import (
"sigs.k8s.io/descheduler/pkg/utils"
)
func evictionConstraintsForFailedBarePods(evictFailedBarePods bool) []constraint {
func evictionConstraintsForFailedBarePods(logger klog.Logger, evictFailedBarePods bool) []constraint {
if evictFailedBarePods {
klog.V(1).InfoS("Warning: EvictFailedBarePods is set to True. This could cause eviction of pods without ownerReferences.")
logger.V(1).Info("Warning: EvictFailedBarePods is set to True. This could cause eviction of pods without ownerReferences.")
return []constraint{
func(pod *v1.Pod) error {
ownerRefList := podutil.OwnerRef(pod)
@@ -52,7 +52,7 @@ func evictionConstraintsForFailedBarePods(evictFailedBarePods bool) []constraint
}
}
func evictionConstraintsForSystemCriticalPods(evictSystemCriticalPods bool, priorityThreshold *api.PriorityThreshold, handle frameworktypes.Handle) ([]constraint, error) {
func evictionConstraintsForSystemCriticalPods(logger klog.Logger, evictSystemCriticalPods bool, priorityThreshold *api.PriorityThreshold, handle frameworktypes.Handle) ([]constraint, error) {
var constraints []constraint
if !evictSystemCriticalPods {
@@ -66,7 +66,7 @@ func evictionConstraintsForSystemCriticalPods(evictSystemCriticalPods bool, prio
if priorityThreshold != nil && (priorityThreshold.Value != nil || len(priorityThreshold.Name) > 0) {
thresholdPriority, err := utils.GetPriorityValueFromPriorityThreshold(context.TODO(), handle.ClientSet(), priorityThreshold)
if err != nil {
klog.Errorf("failed to get priority threshold: %v", err)
logger.Error(err, "failed to get priority threshold")
return nil, err
}
constraints = append(constraints, func(pod *v1.Pod) error {
@@ -77,7 +77,7 @@ func evictionConstraintsForSystemCriticalPods(evictSystemCriticalPods bool, prio
})
}
} else {
klog.V(1).InfoS("Warning: EvictSystemCriticalPods is set to True. This could cause eviction of Kubernetes system pods.")
logger.V(1).Info("Warning: EvictSystemCriticalPods is set to True. This could cause eviction of Kubernetes system pods.")
}
return constraints, nil
@@ -126,11 +126,11 @@ func evictionConstraintsForPvcPods(ignorePvcPods bool) []constraint {
return nil
}
func evictionConstraintsForLabelSelector(labelSelector *metav1.LabelSelector) ([]constraint, error) {
func evictionConstraintsForLabelSelector(logger klog.Logger, labelSelector *metav1.LabelSelector) ([]constraint, error) {
if labelSelector != nil {
selector, err := metav1.LabelSelectorAsSelector(labelSelector)
if err != nil {
klog.Error(err, "could not get selector from label selector")
logger.Error(err, "could not get selector from label selector")
return nil, err
}
if !selector.Empty() {
@@ -147,12 +147,12 @@ func evictionConstraintsForLabelSelector(labelSelector *metav1.LabelSelector) ([
return nil, nil
}
func evictionConstraintsForMinReplicas(minReplicas uint, handle frameworktypes.Handle) ([]constraint, error) {
func evictionConstraintsForMinReplicas(logger klog.Logger, minReplicas uint, handle frameworktypes.Handle) ([]constraint, error) {
if minReplicas > 1 {
indexName := "metadata.ownerReferences"
indexer, err := getPodIndexerByOwnerRefs(indexName, handle)
if err != nil {
klog.Error(err, "could not get pod indexer by ownerRefs")
logger.Error(err, "could not get pod indexer by ownerRefs")
return nil, err
}
return []constraint{
@@ -161,7 +161,7 @@ func evictionConstraintsForMinReplicas(minReplicas uint, handle frameworktypes.H
return nil
}
if len(pod.OwnerReferences) > 1 {
klog.V(5).InfoS("pod has multiple owner references which is not supported for minReplicas check", "size", len(pod.OwnerReferences), "pod", klog.KObj(pod))
logger.V(5).Info("pod has multiple owner references which is not supported for minReplicas check", "size", len(pod.OwnerReferences), "pod", klog.KObj(pod))
return nil
}
ownerRef := pod.OwnerReferences[0]

View File

@@ -45,6 +45,7 @@ type constraint func(pod *v1.Pod) error
// This plugin is only meant to customize other actions (extension points) of the evictor,
// like filtering, sorting, and other ones that might be relevant in the future
type DefaultEvictor struct {
logger klog.Logger
args *DefaultEvictorArgs
constraints []constraint
handle frameworktypes.Handle
@@ -68,23 +69,25 @@ func New(ctx context.Context, args runtime.Object, handle frameworktypes.Handle)
if !ok {
return nil, fmt.Errorf("want args to be of type defaultEvictorFilterArgs, got %T", args)
}
logger := klog.FromContext(ctx).WithValues("plugin", PluginName)
ev := &DefaultEvictor{
logger: logger,
handle: handle,
args: defaultEvictorArgs,
}
// add constraints
err := ev.addAllConstraints(handle)
err := ev.addAllConstraints(logger, handle)
if err != nil {
return nil, err
}
return ev, nil
}
func (d *DefaultEvictor) addAllConstraints(handle frameworktypes.Handle) error {
func (d *DefaultEvictor) addAllConstraints(logger klog.Logger, handle frameworktypes.Handle) error {
args := d.args
d.constraints = append(d.constraints, evictionConstraintsForFailedBarePods(args.EvictFailedBarePods)...)
if constraints, err := evictionConstraintsForSystemCriticalPods(args.EvictSystemCriticalPods, args.PriorityThreshold, handle); err != nil {
d.constraints = append(d.constraints, evictionConstraintsForFailedBarePods(logger, args.EvictFailedBarePods)...)
if constraints, err := evictionConstraintsForSystemCriticalPods(logger, args.EvictSystemCriticalPods, args.PriorityThreshold, handle); err != nil {
return err
} else {
d.constraints = append(d.constraints, constraints...)
@@ -92,12 +95,12 @@ func (d *DefaultEvictor) addAllConstraints(handle frameworktypes.Handle) error {
d.constraints = append(d.constraints, evictionConstraintsForLocalStoragePods(args.EvictLocalStoragePods)...)
d.constraints = append(d.constraints, evictionConstraintsForDaemonSetPods(args.EvictDaemonSetPods)...)
d.constraints = append(d.constraints, evictionConstraintsForPvcPods(args.IgnorePvcPods)...)
if constraints, err := evictionConstraintsForLabelSelector(args.LabelSelector); err != nil {
if constraints, err := evictionConstraintsForLabelSelector(logger, args.LabelSelector); err != nil {
return err
} else {
d.constraints = append(d.constraints, constraints...)
}
if constraints, err := evictionConstraintsForMinReplicas(args.MinReplicas, handle); err != nil {
if constraints, err := evictionConstraintsForMinReplicas(logger, args.MinReplicas, handle); err != nil {
return err
} else {
d.constraints = append(d.constraints, constraints...)
@@ -113,14 +116,15 @@ func (d *DefaultEvictor) Name() string {
}
func (d *DefaultEvictor) PreEvictionFilter(pod *v1.Pod) bool {
logger := d.logger.WithValues("ExtensionPoint", frameworktypes.PreEvictionFilterExtensionPoint)
if d.args.NodeFit {
nodes, err := nodeutil.ReadyNodes(context.TODO(), d.handle.ClientSet(), d.handle.SharedInformerFactory().Core().V1().Nodes().Lister(), d.args.NodeSelector)
if err != nil {
klog.ErrorS(err, "unable to list ready nodes", "pod", klog.KObj(pod))
logger.Error(err, "unable to list ready nodes", "pod", klog.KObj(pod))
return false
}
if !nodeutil.PodFitsAnyOtherNode(d.handle.GetPodsAssignedToNodeFunc(), pod, nodes) {
klog.InfoS("pod does not fit on any other node because of nodeSelector(s), Taint(s), or nodes marked as unschedulable", "pod", klog.KObj(pod))
logger.Info("pod does not fit on any other node because of nodeSelector(s), Taint(s), or nodes marked as unschedulable", "pod", klog.KObj(pod))
return false
}
return true
@@ -129,6 +133,7 @@ func (d *DefaultEvictor) PreEvictionFilter(pod *v1.Pod) bool {
}
func (d *DefaultEvictor) Filter(pod *v1.Pod) bool {
logger := d.logger.WithValues("ExtensionPoint", frameworktypes.FilterExtensionPoint)
checkErrs := []error{}
if HaveEvictAnnotation(pod) {
@@ -154,7 +159,7 @@ func (d *DefaultEvictor) Filter(pod *v1.Pod) bool {
}
if len(checkErrs) > 0 {
klog.V(4).InfoS("Pod fails the following checks", "pod", klog.KObj(pod), "checks", utilerrors.NewAggregate(checkErrs).Error())
logger.V(4).Info("Pod fails the following checks", "pod", klog.KObj(pod), "checks", utilerrors.NewAggregate(checkErrs).Error())
return false
}

View File

@@ -46,6 +46,7 @@ var _ fwtypes.DeschedulePlugin = &Example{}
// Example is our plugin (implementing the DeschedulePlugin interface). This
// plugin will evict pods that match a regex and are older than a certain age.
type Example struct {
logger klog.Logger
handle fwtypes.Handle
args *ExampleArgs
podFilter podutil.FilterFunc
@@ -61,6 +62,7 @@ func New(ctx context.Context, args runtime.Object, handle fwtypes.Handle) (fwtyp
if !ok {
return nil, fmt.Errorf("args must be of type ExampleArgs, got %T", args)
}
logger := klog.FromContext(ctx).WithValues("plugin", PluginName)
// we can use the included and excluded namespaces to filter the pods we want
// to evict.
@@ -90,6 +92,7 @@ func New(ctx context.Context, args runtime.Object, handle fwtypes.Handle) (fwtyp
}
return &Example{
logger: logger,
handle: handle,
podFilter: podFilter,
args: exampleArgs,
@@ -107,7 +110,7 @@ func (d *Example) Name() string {
// of nodes we need to process.
func (d *Example) Deschedule(ctx context.Context, nodes []*v1.Node) *fwtypes.Status {
var podsToEvict []*v1.Pod
logger := klog.FromContext(ctx)
logger := klog.FromContext(klog.NewContext(ctx, d.logger)).WithValues("ExtensionPoint", fwtypes.DescheduleExtensionPoint)
logger.Info("Example plugin starting descheduling")
re, err := regexp.Compile(d.args.Regex)

View File

@@ -44,6 +44,7 @@ var _ frameworktypes.BalancePlugin = &HighNodeUtilization{}
// can schedule according to its plugin. Note that CPU/Memory requests are used
// to calculate nodes' utilization and not the actual resource usage.
type HighNodeUtilization struct {
logger klog.Logger
handle frameworktypes.Handle
args *HighNodeUtilizationArgs
podFilter func(pod *v1.Pod) bool
@@ -64,6 +65,7 @@ func NewHighNodeUtilization(
genericArgs,
)
}
logger := klog.FromContext(ctx).WithValues("plugin", HighNodeUtilizationPluginName)
// this plugins worries only about thresholds but the nodeplugins
// package was made to take two thresholds into account, one for low
@@ -113,6 +115,7 @@ func NewHighNodeUtilization(
)
return &HighNodeUtilization{
logger: logger,
handle: handle,
args: args,
resourceNames: resourceNames,
@@ -135,6 +138,8 @@ func (h *HighNodeUtilization) Name() string {
// utilized nodes. The goal here is to concentrate pods in fewer nodes so that
// less nodes are used.
func (h *HighNodeUtilization) Balance(ctx context.Context, nodes []*v1.Node) *frameworktypes.Status {
logger := klog.FromContext(klog.NewContext(ctx, h.logger)).WithValues("ExtensionPoint", frameworktypes.BalanceExtensionPoint)
if err := h.usageClient.sync(ctx, nodes); err != nil {
return &frameworktypes.Status{
Err: fmt.Errorf("error getting node usage: %v", err),
@@ -165,7 +170,7 @@ func (h *HighNodeUtilization) Balance(ctx context.Context, nodes []*v1.Node) *fr
// schedulable nodes.
func(nodeName string, usage, threshold api.ResourceThresholds) bool {
if nodeutil.IsNodeUnschedulable(nodesMap[nodeName]) {
klog.V(2).InfoS(
logger.V(2).Info(
"Node is unschedulable",
"node", klog.KObj(nodesMap[nodeName]),
)
@@ -184,7 +189,7 @@ func (h *HighNodeUtilization) Balance(ctx context.Context, nodes []*v1.Node) *fr
category := []string{"underutilized", "overutilized"}
for i := range nodeGroups {
for nodeName := range nodeGroups[i] {
klog.InfoS(
logger.Info(
"Node has been classified",
"category", category[i],
"node", klog.KObj(nodesMap[nodeName]),
@@ -208,18 +213,18 @@ func (h *HighNodeUtilization) Balance(ctx context.Context, nodes []*v1.Node) *fr
lowNodes, schedulableNodes := nodeInfos[0], nodeInfos[1]
klog.V(1).InfoS("Criteria for a node below target utilization", h.criteria...)
klog.V(1).InfoS("Number of underutilized nodes", "totalNumber", len(lowNodes))
logger.V(1).Info("Criteria for a node below target utilization", h.criteria...)
logger.V(1).Info("Number of underutilized nodes", "totalNumber", len(lowNodes))
if len(lowNodes) == 0 {
klog.V(1).InfoS(
logger.V(1).Info(
"No node is underutilized, nothing to do here, you might tune your thresholds further",
)
return nil
}
if len(lowNodes) <= h.args.NumberOfNodes {
klog.V(1).InfoS(
logger.V(1).Info(
"Number of nodes underutilized is less or equal than NumberOfNodes, nothing to do here",
"underutilizedNodes", len(lowNodes),
"numberOfNodes", h.args.NumberOfNodes,
@@ -228,12 +233,12 @@ func (h *HighNodeUtilization) Balance(ctx context.Context, nodes []*v1.Node) *fr
}
if len(lowNodes) == len(nodes) {
klog.V(1).InfoS("All nodes are underutilized, nothing to do here")
logger.V(1).Info("All nodes are underutilized, nothing to do here")
return nil
}
if len(schedulableNodes) == 0 {
klog.V(1).InfoS("No node is available to schedule the pods, nothing to do here")
logger.V(1).Info("No node is available to schedule the pods, nothing to do here")
return nil
}

View File

@@ -43,6 +43,7 @@ var _ frameworktypes.BalancePlugin = &LowNodeUtilization{}
// nodes. Note that CPU/Memory requests are used to calculate nodes'
// utilization and not the actual resource usage.
type LowNodeUtilization struct {
logger klog.Logger
handle frameworktypes.Handle
args *LowNodeUtilizationArgs
podFilter func(pod *v1.Pod) bool
@@ -66,6 +67,7 @@ func NewLowNodeUtilization(
genericArgs,
)
}
logger := klog.FromContext(ctx).WithValues("plugin", LowNodeUtilizationPluginName)
// resourceNames holds a list of resources for which the user has
// provided thresholds for. extendedResourceNames holds those as well
@@ -115,6 +117,7 @@ func NewLowNodeUtilization(
}
return &LowNodeUtilization{
logger: logger,
handle: handle,
args: args,
underCriteria: thresholdsToKeysAndValues(args.Thresholds),
@@ -135,6 +138,8 @@ func (l *LowNodeUtilization) Name() string {
// utilized nodes to under utilized nodes. The goal here is to evenly
// distribute pods across nodes.
func (l *LowNodeUtilization) Balance(ctx context.Context, nodes []*v1.Node) *frameworktypes.Status {
logger := klog.FromContext(klog.NewContext(ctx, l.logger)).WithValues("ExtensionPoint", frameworktypes.BalanceExtensionPoint)
if err := l.usageClient.sync(ctx, nodes); err != nil {
return &frameworktypes.Status{
Err: fmt.Errorf("error getting node usage: %v", err),
@@ -182,7 +187,7 @@ func (l *LowNodeUtilization) Balance(ctx context.Context, nodes []*v1.Node) *fra
// underutilized but aren't schedulable are ignored.
func(nodeName string, usage, threshold api.ResourceThresholds) bool {
if nodeutil.IsNodeUnschedulable(nodesMap[nodeName]) {
klog.V(2).InfoS(
logger.V(2).Info(
"Node is unschedulable, thus not considered as underutilized",
"node", klog.KObj(nodesMap[nodeName]),
)
@@ -207,7 +212,7 @@ func (l *LowNodeUtilization) Balance(ctx context.Context, nodes []*v1.Node) *fra
for nodeName := range nodeGroups[i] {
classifiedNodes[nodeName] = true
klog.InfoS(
logger.Info(
"Node has been classified",
"category", categories[i],
"node", klog.KObj(nodesMap[nodeName]),
@@ -233,7 +238,7 @@ func (l *LowNodeUtilization) Balance(ctx context.Context, nodes []*v1.Node) *fra
// log nodes that are appropriately utilized.
for nodeName := range nodesMap {
if !classifiedNodes[nodeName] {
klog.InfoS(
logger.Info(
"Node is appropriately utilized",
"node", klog.KObj(nodesMap[nodeName]),
"usage", nodesUsageMap[nodeName],
@@ -245,20 +250,20 @@ func (l *LowNodeUtilization) Balance(ctx context.Context, nodes []*v1.Node) *fra
lowNodes, highNodes := nodeInfos[0], nodeInfos[1]
// log messages for nodes with low and high utilization
klog.V(1).InfoS("Criteria for a node under utilization", l.underCriteria...)
klog.V(1).InfoS("Number of underutilized nodes", "totalNumber", len(lowNodes))
klog.V(1).InfoS("Criteria for a node above target utilization", l.overCriteria...)
klog.V(1).InfoS("Number of overutilized nodes", "totalNumber", len(highNodes))
logger.V(1).Info("Criteria for a node under utilization", l.underCriteria...)
logger.V(1).Info("Number of underutilized nodes", "totalNumber", len(lowNodes))
logger.V(1).Info("Criteria for a node above target utilization", l.overCriteria...)
logger.V(1).Info("Number of overutilized nodes", "totalNumber", len(highNodes))
if len(lowNodes) == 0 {
klog.V(1).InfoS(
logger.V(1).Info(
"No node is underutilized, nothing to do here, you might tune your thresholds further",
)
return nil
}
if len(lowNodes) <= l.args.NumberOfNodes {
klog.V(1).InfoS(
logger.V(1).Info(
"Number of nodes underutilized is less or equal than NumberOfNodes, nothing to do here",
"underutilizedNodes", len(lowNodes),
"numberOfNodes", l.args.NumberOfNodes,
@@ -267,12 +272,12 @@ func (l *LowNodeUtilization) Balance(ctx context.Context, nodes []*v1.Node) *fra
}
if len(lowNodes) == len(nodes) {
klog.V(1).InfoS("All nodes are underutilized, nothing to do here")
logger.V(1).Info("All nodes are underutilized, nothing to do here")
return nil
}
if len(highNodes) == 0 {
klog.V(1).InfoS("All nodes are under target utilization, nothing to do here")
logger.V(1).Info("All nodes are under target utilization, nothing to do here")
return nil
}

View File

@@ -176,13 +176,14 @@ func evictPodsFromSourceNodes(
usageClient usageClient,
maxNoOfPodsToEvictPerNode *uint,
) {
logger := klog.FromContext(ctx)
available, err := assessAvailableResourceInNodes(destinationNodes, resourceNames)
if err != nil {
klog.ErrorS(err, "unable to assess available resources in nodes")
logger.Error(err, "unable to assess available resources in nodes")
return
}
klog.V(1).InfoS("Total capacity to be moved", usageToKeysAndValues(available)...)
logger.V(1).Info("Total capacity to be moved", usageToKeysAndValues(available)...)
destinationTaints := make(map[string][]v1.Taint, len(destinationNodes))
for _, node := range destinationNodes {
@@ -190,14 +191,14 @@ func evictPodsFromSourceNodes(
}
for _, node := range sourceNodes {
klog.V(3).InfoS(
logger.V(3).Info(
"Evicting pods from node",
"node", klog.KObj(node.node),
"usage", node.usage,
)
nonRemovablePods, removablePods := classifyPods(node.allPods, podFilter)
klog.V(2).InfoS(
logger.V(2).Info(
"Pods on node",
"node", klog.KObj(node.node),
"allPods", len(node.allPods),
@@ -206,14 +207,14 @@ func evictPodsFromSourceNodes(
)
if len(removablePods) == 0 {
klog.V(1).InfoS(
logger.V(1).Info(
"No removable pods on node, try next node",
"node", klog.KObj(node.node),
)
continue
}
klog.V(1).InfoS(
logger.V(1).Info(
"Evicting pods based on priority, if they have same priority, they'll be evicted based on QoS tiers",
)
@@ -260,6 +261,7 @@ func evictPods(
usageClient usageClient,
maxNoOfPodsToEvictPerNode *uint,
) error {
logger := klog.FromContext(ctx)
// preemptive check to see if we should continue evicting pods.
if !continueEviction(nodeInfo, totalAvailableUsage) {
return nil
@@ -274,7 +276,7 @@ func evictPods(
var evictionCounter uint = 0
for _, pod := range inputPods {
if maxNoOfPodsToEvictPerNode != nil && evictionCounter >= *maxNoOfPodsToEvictPerNode {
klog.V(3).InfoS(
logger.V(3).Info(
"Max number of evictions per node per plugin reached",
"limit", *maxNoOfPodsToEvictPerNode,
)
@@ -282,7 +284,7 @@ func evictPods(
}
if !utils.PodToleratesTaints(pod, destinationTaints) {
klog.V(3).InfoS(
logger.V(3).Info(
"Skipping eviction for pod, doesn't tolerate node taint",
"pod", klog.KObj(pod),
)
@@ -297,7 +299,7 @@ func evictPods(
WithoutNamespaces(excludedNamespaces).
BuildFilterFunc()
if err != nil {
klog.ErrorS(err, "could not build preEvictionFilter with namespace exclusion")
logger.Error(err, "could not build preEvictionFilter with namespace exclusion")
continue
}
@@ -311,9 +313,8 @@ func evictPods(
podUsage, err := usageClient.podUsage(pod)
if err != nil {
if _, ok := err.(*notSupportedError); !ok {
klog.Errorf(
"unable to get pod usage for %v/%v: %v",
pod.Namespace, pod.Name, err,
logger.Error(err,
"unable to get pod usage", "pod", klog.KObj(pod),
)
continue
}
@@ -325,18 +326,18 @@ func evictPods(
case *evictions.EvictionNodeLimitError, *evictions.EvictionTotalLimitError:
return err
default:
klog.Errorf("eviction failed: %v", err)
logger.Error(err, "eviction failed")
continue
}
}
if maxNoOfPodsToEvictPerNode == nil && unconstrainedResourceEviction {
klog.V(3).InfoS("Currently, only a single pod eviction is allowed")
logger.V(3).Info("Currently, only a single pod eviction is allowed")
break
}
evictionCounter++
klog.V(3).InfoS("Evicted pods", "pod", klog.KObj(pod))
logger.V(3).Info("Evicted pods", "pod", klog.KObj(pod))
if unconstrainedResourceEviction {
continue
}
@@ -345,7 +346,7 @@ func evictPods(
keysAndValues := []any{"node", nodeInfo.node.Name}
keysAndValues = append(keysAndValues, usageToKeysAndValues(nodeInfo.usage)...)
klog.V(3).InfoS("Updated node usage", keysAndValues...)
logger.V(3).Info("Updated node usage", keysAndValues...)
// make sure we should continue evicting pods.
if !continueEviction(nodeInfo, totalAvailableUsage) {

View File

@@ -264,12 +264,13 @@ func (client *prometheusUsageClient) podUsage(pod *v1.Pod) (map[v1.ResourceName]
}
func NodeUsageFromPrometheusMetrics(ctx context.Context, promClient promapi.Client, promQuery string) (map[string]map[v1.ResourceName]*resource.Quantity, error) {
logger := klog.FromContext(ctx)
results, warnings, err := promv1.NewAPI(promClient).Query(ctx, promQuery, time.Now())
if err != nil {
return nil, fmt.Errorf("unable to capture prometheus metrics: %v", err)
}
if len(warnings) > 0 {
klog.Infof("prometheus metrics warnings: %v", warnings)
logger.Info("prometheus metrics warnings: %v", warnings)
}
if results.Type() != model.ValVector {

View File

@@ -38,6 +38,7 @@ var _ frameworktypes.DeschedulePlugin = &PodLifeTime{}
// PodLifeTime evicts pods on the node that violate the max pod lifetime threshold
type PodLifeTime struct {
logger klog.Logger
handle frameworktypes.Handle
args *PodLifeTimeArgs
podFilter podutil.FilterFunc
@@ -49,6 +50,7 @@ func New(ctx context.Context, args runtime.Object, handle frameworktypes.Handle)
if !ok {
return nil, fmt.Errorf("want args to be of type PodLifeTimeArgs, got %T", args)
}
logger := klog.FromContext(ctx).WithValues("plugin", PluginName)
var includedNamespaces, excludedNamespaces sets.Set[string]
if podLifeTimeArgs.Namespaces != nil {
@@ -115,6 +117,7 @@ func New(ctx context.Context, args runtime.Object, handle frameworktypes.Handle)
}
return &PodLifeTime{
logger: logger,
handle: handle,
podFilter: podFilter,
args: podLifeTimeArgs,
@@ -130,9 +133,9 @@ func (d *PodLifeTime) Name() string {
func (d *PodLifeTime) Deschedule(ctx context.Context, nodes []*v1.Node) *frameworktypes.Status {
podsToEvict := make([]*v1.Pod, 0)
nodeMap := make(map[string]*v1.Node, len(nodes))
logger := klog.FromContext(klog.NewContext(ctx, d.logger)).WithValues("ExtensionPoint", frameworktypes.DescheduleExtensionPoint)
for _, node := range nodes {
klog.V(2).InfoS("Processing node", "node", klog.KObj(node))
logger.V(2).Info("Processing node", "node", klog.KObj(node))
pods, err := podutil.ListAllPodsOnANode(node.Name, d.handle.GetPodsAssignedToNodeFunc(), d.podFilter)
if err != nil {
// no pods evicted as error encountered retrieving evictable Pods
@@ -161,7 +164,7 @@ loop:
case *evictions.EvictionTotalLimitError:
return nil
default:
klog.Errorf("eviction failed: %v", err)
logger.Error(err, "eviction failed")
}
}

View File

@@ -45,6 +45,7 @@ const PluginName = "RemoveDuplicates"
// As of now, this plugin won't evict daemonsets, mirror pods, critical pods and pods with local storages.
type RemoveDuplicates struct {
logger klog.Logger
handle frameworktypes.Handle
args *RemoveDuplicatesArgs
podFilter podutil.FilterFunc
@@ -67,6 +68,7 @@ func New(ctx context.Context, args runtime.Object, handle frameworktypes.Handle)
if !ok {
return nil, fmt.Errorf("want args to be of type RemoveDuplicatesArgs, got %T", args)
}
logger := klog.FromContext(ctx).WithValues("plugin", PluginName)
var includedNamespaces, excludedNamespaces sets.Set[string]
if removeDuplicatesArgs.Namespaces != nil {
@@ -85,6 +87,7 @@ func New(ctx context.Context, args runtime.Object, handle frameworktypes.Handle)
}
return &RemoveDuplicates{
logger: logger,
handle: handle,
args: removeDuplicatesArgs,
podFilter: podFilter,
@@ -102,12 +105,13 @@ func (r *RemoveDuplicates) Balance(ctx context.Context, nodes []*v1.Node) *frame
ownerKeyOccurence := make(map[podOwner]int32)
nodeCount := 0
nodeMap := make(map[string]*v1.Node)
logger := klog.FromContext(klog.NewContext(ctx, r.logger)).WithValues("ExtensionPoint", frameworktypes.BalanceExtensionPoint)
for _, node := range nodes {
klog.V(2).InfoS("Processing node", "node", klog.KObj(node))
logger.V(2).Info("Processing node", "node", klog.KObj(node))
pods, err := podutil.ListPodsOnANode(node.Name, r.handle.GetPodsAssignedToNodeFunc(), r.podFilter)
if err != nil {
klog.ErrorS(err, "Error listing evictable pods on node", "node", klog.KObj(node))
logger.Error(err, "Error listing evictable pods on node", "node", klog.KObj(node))
continue
}
nodeMap[node.Name] = node
@@ -163,7 +167,7 @@ func (r *RemoveDuplicates) Balance(ctx context.Context, nodes []*v1.Node) *frame
for _, keys := range existing {
if reflect.DeepEqual(keys, podContainerKeys) {
matched = true
klog.V(3).InfoS("Duplicate found", "pod", klog.KObj(pod))
logger.V(3).Info("Duplicate found", "pod", klog.KObj(pod))
for _, ownerRef := range ownerRefList {
ownerKey := podOwner{
namespace: pod.ObjectMeta.Namespace,
@@ -195,16 +199,16 @@ func (r *RemoveDuplicates) Balance(ctx context.Context, nodes []*v1.Node) *frame
targetNodes := getTargetNodes(podNodes, nodes)
klog.V(2).InfoS("Adjusting feasible nodes", "owner", ownerKey, "from", nodeCount, "to", len(targetNodes))
logger.V(2).Info("Adjusting feasible nodes", "owner", ownerKey, "from", nodeCount, "to", len(targetNodes))
if len(targetNodes) < 2 {
klog.V(1).InfoS("Less than two feasible nodes for duplicates to land, skipping eviction", "owner", ownerKey)
logger.V(1).Info("Less than two feasible nodes for duplicates to land, skipping eviction", "owner", ownerKey)
continue
}
upperAvg := int(math.Ceil(float64(ownerKeyOccurence[ownerKey]) / float64(len(targetNodes))))
loop:
for nodeName, pods := range podNodes {
klog.V(2).InfoS("Average occurrence per node", "node", klog.KObj(nodeMap[nodeName]), "ownerKey", ownerKey, "avg", upperAvg)
logger.V(2).Info("Average occurrence per node", "node", klog.KObj(nodeMap[nodeName]), "ownerKey", ownerKey, "avg", upperAvg)
// list of duplicated pods does not contain the original referential pod
if len(pods)+1 > upperAvg {
// It's assumed all duplicated pods are in the same priority class
@@ -220,7 +224,7 @@ func (r *RemoveDuplicates) Balance(ctx context.Context, nodes []*v1.Node) *frame
case *evictions.EvictionTotalLimitError:
return nil
default:
klog.Errorf("eviction failed: %v", err)
logger.Error(err, "eviction failed")
}
}
}

View File

@@ -36,6 +36,7 @@ const PluginName = "RemoveFailedPods"
// RemoveFailedPods evicts pods in failed status phase that match the given args criteria
type RemoveFailedPods struct {
logger klog.Logger
handle frameworktypes.Handle
args *RemoveFailedPodsArgs
podFilter podutil.FilterFunc
@@ -49,6 +50,7 @@ func New(ctx context.Context, args runtime.Object, handle frameworktypes.Handle)
if !ok {
return nil, fmt.Errorf("want args to be of type RemoveFailedPodsArgs, got %T", args)
}
logger := klog.FromContext(ctx).WithValues("plugin", PluginName)
var includedNamespaces, excludedNamespaces sets.Set[string]
if failedPodsArgs.Namespaces != nil {
@@ -71,7 +73,7 @@ func New(ctx context.Context, args runtime.Object, handle frameworktypes.Handle)
podFilter = podutil.WrapFilterFuncs(podFilter, func(pod *v1.Pod) bool {
if err := validateCanEvict(pod, failedPodsArgs); err != nil {
klog.V(4).InfoS(fmt.Sprintf("ignoring pod for eviction due to: %s", err.Error()), "pod", klog.KObj(pod))
logger.Error(fmt.Errorf("ignoring pod for eviction due to: %s", err.Error()), "pod", klog.KObj(pod))
return false
}
@@ -79,6 +81,7 @@ func New(ctx context.Context, args runtime.Object, handle frameworktypes.Handle)
})
return &RemoveFailedPods{
logger: logger,
handle: handle,
podFilter: podFilter,
args: failedPodsArgs,
@@ -92,8 +95,9 @@ func (d *RemoveFailedPods) Name() string {
// Deschedule extension point implementation for the plugin
func (d *RemoveFailedPods) Deschedule(ctx context.Context, nodes []*v1.Node) *frameworktypes.Status {
logger := klog.FromContext(klog.NewContext(ctx, d.logger)).WithValues("ExtensionPoint", frameworktypes.DescheduleExtensionPoint)
for _, node := range nodes {
klog.V(2).InfoS("Processing node", "node", klog.KObj(node))
logger.V(2).Info("Processing node", "node", klog.KObj(node))
pods, err := podutil.ListAllPodsOnANode(node.Name, d.handle.GetPodsAssignedToNodeFunc(), d.podFilter)
if err != nil {
// no pods evicted as error encountered retrieving evictable Pods
@@ -114,7 +118,7 @@ func (d *RemoveFailedPods) Deschedule(ctx context.Context, nodes []*v1.Node) *fr
case *evictions.EvictionTotalLimitError:
return nil
default:
klog.Errorf("eviction failed: %v", err)
logger.Error(err, "eviction failed")
}
}
}

View File

@@ -37,6 +37,7 @@ const PluginName = "RemovePodsHavingTooManyRestarts"
// There are too many cases leading this issue: Volume mount failed, app error due to nodes' different settings.
// As of now, this strategy won't evict daemonsets, mirror pods, critical pods and pods with local storages.
type RemovePodsHavingTooManyRestarts struct {
logger klog.Logger
handle frameworktypes.Handle
args *RemovePodsHavingTooManyRestartsArgs
podFilter podutil.FilterFunc
@@ -50,6 +51,7 @@ func New(ctx context.Context, args runtime.Object, handle frameworktypes.Handle)
if !ok {
return nil, fmt.Errorf("want args to be of type RemovePodsHavingTooManyRestartsArgs, got %T", args)
}
logger := klog.FromContext(ctx).WithValues("plugin", PluginName)
var includedNamespaces, excludedNamespaces sets.Set[string]
if tooManyRestartsArgs.Namespaces != nil {
@@ -70,7 +72,7 @@ func New(ctx context.Context, args runtime.Object, handle frameworktypes.Handle)
podFilter = podutil.WrapFilterFuncs(podFilter, func(pod *v1.Pod) bool {
if err := validateCanEvict(pod, tooManyRestartsArgs); err != nil {
klog.V(4).InfoS(fmt.Sprintf("ignoring pod for eviction due to: %s", err.Error()), "pod", klog.KObj(pod))
logger.Error(fmt.Errorf("ignoring pod for eviction due to: %s", err.Error()), "pod", klog.KObj(pod))
return false
}
return true
@@ -100,6 +102,7 @@ func New(ctx context.Context, args runtime.Object, handle frameworktypes.Handle)
}
return &RemovePodsHavingTooManyRestarts{
logger: logger,
handle: handle,
args: tooManyRestartsArgs,
podFilter: podFilter,
@@ -113,8 +116,9 @@ func (d *RemovePodsHavingTooManyRestarts) Name() string {
// Deschedule extension point implementation for the plugin
func (d *RemovePodsHavingTooManyRestarts) Deschedule(ctx context.Context, nodes []*v1.Node) *frameworktypes.Status {
logger := klog.FromContext(klog.NewContext(ctx, d.logger)).WithValues("ExtensionPoint", frameworktypes.DescheduleExtensionPoint)
for _, node := range nodes {
klog.V(2).InfoS("Processing node", "node", klog.KObj(node))
logger.V(2).Info("Processing node", "node", klog.KObj(node))
pods, err := podutil.ListAllPodsOnANode(node.Name, d.handle.GetPodsAssignedToNodeFunc(), d.podFilter)
if err != nil {
// no pods evicted as error encountered retrieving evictable Pods
@@ -144,7 +148,7 @@ func (d *RemovePodsHavingTooManyRestarts) Deschedule(ctx context.Context, nodes
case *evictions.EvictionTotalLimitError:
return nil
default:
klog.Errorf("eviction failed: %v", err)
logger.Error(err, "eviction failed")
}
}
}

View File

@@ -35,6 +35,7 @@ const PluginName = "RemovePodsViolatingInterPodAntiAffinity"
// RemovePodsViolatingInterPodAntiAffinity evicts pods on the node which violate inter pod anti affinity
type RemovePodsViolatingInterPodAntiAffinity struct {
logger klog.Logger
handle frameworktypes.Handle
args *RemovePodsViolatingInterPodAntiAffinityArgs
podFilter podutil.FilterFunc
@@ -48,6 +49,7 @@ func New(ctx context.Context, args runtime.Object, handle frameworktypes.Handle)
if !ok {
return nil, fmt.Errorf("want args to be of type RemovePodsViolatingInterPodAntiAffinityArgs, got %T", args)
}
logger := klog.FromContext(ctx).WithValues("plugin", PluginName)
var includedNamespaces, excludedNamespaces sets.Set[string]
if interPodAntiAffinityArgs.Namespaces != nil {
@@ -65,6 +67,7 @@ func New(ctx context.Context, args runtime.Object, handle frameworktypes.Handle)
}
return &RemovePodsViolatingInterPodAntiAffinity{
logger: logger,
handle: handle,
podFilter: podFilter,
args: interPodAntiAffinityArgs,
@@ -77,6 +80,7 @@ func (d *RemovePodsViolatingInterPodAntiAffinity) Name() string {
}
func (d *RemovePodsViolatingInterPodAntiAffinity) Deschedule(ctx context.Context, nodes []*v1.Node) *frameworktypes.Status {
logger := klog.FromContext(klog.NewContext(ctx, d.logger)).WithValues("ExtensionPoint", frameworktypes.DescheduleExtensionPoint)
pods, err := podutil.ListPodsOnNodes(nodes, d.handle.GetPodsAssignedToNodeFunc(), d.podFilter)
if err != nil {
return &frameworktypes.Status{
@@ -90,7 +94,7 @@ func (d *RemovePodsViolatingInterPodAntiAffinity) Deschedule(ctx context.Context
loop:
for _, node := range nodes {
klog.V(2).InfoS("Processing node", "node", klog.KObj(node))
logger.V(2).Info("Processing node", "node", klog.KObj(node))
pods := podsOnANode[node.Name]
// sort the evict-able Pods based on priority, if there are multiple pods with same priority, they are sorted based on QoS tiers.
podutil.SortPodsBasedOnPriorityLowToHigh(pods)
@@ -115,7 +119,7 @@ loop:
case *evictions.EvictionTotalLimitError:
return nil
default:
klog.Errorf("eviction failed: %v", err)
logger.Error(err, "eviction failed")
}
}
}

View File

@@ -33,6 +33,7 @@ const PluginName = "RemovePodsViolatingNodeAffinity"
// RemovePodsViolatingNodeAffinity evicts pods on the node which violate node affinity
type RemovePodsViolatingNodeAffinity struct {
logger klog.Logger
handle frameworktypes.Handle
args *RemovePodsViolatingNodeAffinityArgs
podFilter podutil.FilterFunc
@@ -46,6 +47,7 @@ func New(ctx context.Context, args runtime.Object, handle frameworktypes.Handle)
if !ok {
return nil, fmt.Errorf("want args to be of type RemovePodsViolatingNodeAffinityArgs, got %T", args)
}
logger := klog.FromContext(ctx).WithValues("plugin", PluginName)
var includedNamespaces, excludedNamespaces sets.Set[string]
if nodeAffinityArgs.Namespaces != nil {
@@ -65,6 +67,7 @@ func New(ctx context.Context, args runtime.Object, handle frameworktypes.Handle)
}
return &RemovePodsViolatingNodeAffinity{
logger: logger,
handle: handle,
podFilter: podFilter,
args: nodeAffinityArgs,
@@ -77,8 +80,9 @@ func (d *RemovePodsViolatingNodeAffinity) Name() string {
}
func (d *RemovePodsViolatingNodeAffinity) Deschedule(ctx context.Context, nodes []*v1.Node) *frameworktypes.Status {
logger := klog.FromContext(klog.NewContext(ctx, d.logger)).WithValues("ExtensionPoint", frameworktypes.DescheduleExtensionPoint)
for _, nodeAffinity := range d.args.NodeAffinityType {
klog.V(2).InfoS("Executing for nodeAffinityType", "nodeAffinity", nodeAffinity)
logger.V(2).Info("Executing for nodeAffinityType", "nodeAffinity", nodeAffinity)
var err *frameworktypes.Status = nil
// The pods that we'll evict must be evictable. For example, the current number of replicas
@@ -106,7 +110,7 @@ func (d *RemovePodsViolatingNodeAffinity) Deschedule(ctx context.Context, nodes
}
err = d.processNodes(ctx, nodes, filterFunc)
default:
klog.ErrorS(nil, "Invalid nodeAffinityType", "nodeAffinity", nodeAffinity)
logger.Error(nil, "Invalid nodeAffinityType", "nodeAffinity", nodeAffinity)
}
if err != nil {
@@ -118,7 +122,7 @@ func (d *RemovePodsViolatingNodeAffinity) Deschedule(ctx context.Context, nodes
func (d *RemovePodsViolatingNodeAffinity) processNodes(ctx context.Context, nodes []*v1.Node, filterFunc func(*v1.Pod, *v1.Node, []*v1.Node) bool) *frameworktypes.Status {
for _, node := range nodes {
klog.V(2).InfoS("Processing node", "node", klog.KObj(node))
d.logger.V(2).Info("Processing node", "node", klog.KObj(node))
// Potentially evictable pods
pods, err := podutil.ListPodsOnANode(
@@ -136,7 +140,7 @@ func (d *RemovePodsViolatingNodeAffinity) processNodes(ctx context.Context, node
loop:
for _, pod := range pods {
klog.V(1).InfoS("Evicting pod", "pod", klog.KObj(pod))
d.logger.V(1).Info("Evicting pod", "pod", klog.KObj(pod))
err := d.handle.Evictor().Evict(ctx, pod, evictions.EvictOptions{StrategyName: PluginName})
if err == nil {
continue
@@ -147,7 +151,7 @@ func (d *RemovePodsViolatingNodeAffinity) processNodes(ctx context.Context, node
case *evictions.EvictionTotalLimitError:
return nil
default:
klog.Errorf("eviction failed: %v", err)
d.logger.Error(err, "eviction failed")
}
}
}

View File

@@ -35,6 +35,7 @@ const PluginName = "RemovePodsViolatingNodeTaints"
// RemovePodsViolatingNodeTaints evicts pods on the node which violate NoSchedule Taints on nodes
type RemovePodsViolatingNodeTaints struct {
logger klog.Logger
handle frameworktypes.Handle
args *RemovePodsViolatingNodeTaintsArgs
taintFilterFnc func(taint *v1.Taint) bool
@@ -49,6 +50,7 @@ func New(ctx context.Context, args runtime.Object, handle frameworktypes.Handle)
if !ok {
return nil, fmt.Errorf("want args to be of type RemovePodsViolatingNodeTaintsArgs, got %T", args)
}
logger := klog.FromContext(ctx).WithValues("plugin", PluginName)
var includedNamespaces, excludedNamespaces sets.Set[string]
if nodeTaintsArgs.Namespaces != nil {
@@ -90,6 +92,7 @@ func New(ctx context.Context, args runtime.Object, handle frameworktypes.Handle)
}
return &RemovePodsViolatingNodeTaints{
logger: logger,
handle: handle,
podFilter: podFilter,
args: nodeTaintsArgs,
@@ -104,9 +107,10 @@ func (d *RemovePodsViolatingNodeTaints) Name() string {
// Deschedule extension point implementation for the plugin
func (d *RemovePodsViolatingNodeTaints) Deschedule(ctx context.Context, nodes []*v1.Node) *frameworktypes.Status {
logger := klog.FromContext(klog.NewContext(ctx, d.logger)).WithValues("ExtensionPoint", frameworktypes.DescheduleExtensionPoint)
for _, node := range nodes {
klog.V(1).InfoS("Processing node", "node", klog.KObj(node))
pods, err := podutil.ListPodsOnANode(node.Name, d.handle.GetPodsAssignedToNodeFunc(), d.podFilter)
logger.V(1).Info("Processing node", "node", klog.KObj(node))
if err != nil {
// no pods evicted as error encountered retrieving evictable Pods
return &frameworktypes.Status{
@@ -121,7 +125,7 @@ func (d *RemovePodsViolatingNodeTaints) Deschedule(ctx context.Context, nodes []
node.Spec.Taints,
d.taintFilterFnc,
) {
klog.V(2).InfoS("Not all taints with NoSchedule effect are tolerated after update for pod on node", "pod", klog.KObj(pods[i]), "node", klog.KObj(node))
logger.V(2).Info("Not all taints with NoSchedule effect are tolerated after update for pod on node", "pod", klog.KObj(pods[i]), "node", klog.KObj(node))
err := d.handle.Evictor().Evict(ctx, pods[i], evictions.EvictOptions{StrategyName: PluginName})
if err == nil {
continue
@@ -132,7 +136,7 @@ func (d *RemovePodsViolatingNodeTaints) Deschedule(ctx context.Context, nodes []
case *evictions.EvictionTotalLimitError:
return nil
default:
klog.Errorf("eviction failed: %v", err)
logger.Error(err, "eviction failed")
}
}
}

View File

@@ -66,6 +66,7 @@ type topologySpreadConstraint struct {
// RemovePodsViolatingTopologySpreadConstraint evicts pods which violate their topology spread constraints
type RemovePodsViolatingTopologySpreadConstraint struct {
logger klog.Logger
handle frameworktypes.Handle
args *RemovePodsViolatingTopologySpreadConstraintArgs
podFilter podutil.FilterFunc
@@ -79,6 +80,7 @@ func New(ctx context.Context, args runtime.Object, handle frameworktypes.Handle)
if !ok {
return nil, fmt.Errorf("want args to be of type RemovePodsViolatingTopologySpreadConstraintArgs, got %T", args)
}
logger := klog.FromContext(ctx).WithValues("plugin", PluginName)
var includedNamespaces, excludedNamespaces sets.Set[string]
if pluginArgs.Namespaces != nil {
@@ -97,6 +99,7 @@ func New(ctx context.Context, args runtime.Object, handle frameworktypes.Handle)
}
return &RemovePodsViolatingTopologySpreadConstraint{
logger: logger,
handle: handle,
podFilter: podFilter,
args: pluginArgs,
@@ -110,6 +113,8 @@ func (d *RemovePodsViolatingTopologySpreadConstraint) Name() string {
// nolint: gocyclo
func (d *RemovePodsViolatingTopologySpreadConstraint) Balance(ctx context.Context, nodes []*v1.Node) *frameworktypes.Status {
logger := klog.FromContext(klog.NewContext(ctx, d.logger)).WithValues("ExtensionPoint", frameworktypes.BalanceExtensionPoint)
nodeMap := make(map[string]*v1.Node, len(nodes))
for _, node := range nodes {
nodeMap[node.Name] = node
@@ -127,7 +132,7 @@ func (d *RemovePodsViolatingTopologySpreadConstraint) Balance(ctx context.Contex
// iterate through all topoPairs for this topologyKey and diff currentPods -minPods <=maxSkew
// if diff > maxSkew, add this pod in the current bucket for eviction
klog.V(1).Info("Processing namespaces for topology spread constraints")
logger.V(1).Info("Processing namespaces for topology spread constraints")
podsForEviction := make(map[*v1.Pod]struct{})
pods, err := podutil.ListPodsOnNodes(nodes, d.handle.GetPodsAssignedToNodeFunc(), d.podFilter)
@@ -143,7 +148,7 @@ func (d *RemovePodsViolatingTopologySpreadConstraint) Balance(ctx context.Contex
// 1. for each namespace...
for namespace := range namespacedPods {
klog.V(4).InfoS("Processing namespace for topology spread constraints", "namespace", namespace)
logger.V(4).Info("Processing namespace for topology spread constraints", "namespace", namespace)
// ...where there is a topology constraint
var namespaceTopologySpreadConstraints []topologySpreadConstraint
@@ -156,7 +161,7 @@ func (d *RemovePodsViolatingTopologySpreadConstraint) Balance(ctx context.Contex
namespaceTopologySpreadConstraint, err := newTopologySpreadConstraint(constraint, pod)
if err != nil {
klog.ErrorS(err, "cannot process topology spread constraint")
logger.Error(err, "cannot process topology spread constraint")
continue
}
@@ -216,7 +221,7 @@ func (d *RemovePodsViolatingTopologySpreadConstraint) Balance(ctx context.Contex
sumPods++
}
if topologyIsBalanced(constraintTopologies, tsc) {
klog.V(2).InfoS("Skipping topology constraint because it is already balanced", "constraint", tsc)
logger.V(2).Info("Skipping topology constraint because it is already balanced", "constraint", tsc)
continue
}
d.balanceDomains(podsForEviction, tsc, constraintTopologies, sumPods, nodes)
@@ -243,7 +248,7 @@ func (d *RemovePodsViolatingTopologySpreadConstraint) Balance(ctx context.Contex
case *evictions.EvictionTotalLimitError:
return nil
default:
klog.Errorf("eviction failed: %v", err)
logger.Error(err, "eviction failed")
}
}
}
@@ -368,7 +373,7 @@ func (d *RemovePodsViolatingTopologySpreadConstraint) balanceDomains(
// So, a better selection heuristic could improve performance.
if topologyBalanceNodeFit && !node.PodFitsAnyOtherNode(getPodsAssignedToNode, aboveToEvict[k], nodesBelowIdealAvg) {
klog.V(2).InfoS("ignoring pod for eviction as it does not fit on any other node", "pod", klog.KObj(aboveToEvict[k]))
d.logger.V(2).Info("ignoring pod for eviction as it does not fit on any other node", "pod", klog.KObj(aboveToEvict[k]))
continue
}