mirror of
https://github.com/kubernetes-sigs/descheduler.git
synced 2026-01-26 21:31:18 +01:00
feature: use contextal logging for plugins
Signed-off-by: googs1025 <googs1025@gmail.com>
This commit is contained in:
@@ -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]
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user