Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkg/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ type StrategyParameters struct {
PodsHavingTooManyRestarts *PodsHavingTooManyRestarts
MaxPodLifeTimeSeconds *uint
RemoveDuplicates *RemoveDuplicates
Namespaces Namespaces
Namespaces *Namespaces
ThresholdPriority *int32
ThresholdPriorityClassName string
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/api/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ type StrategyParameters struct {
PodsHavingTooManyRestarts *PodsHavingTooManyRestarts `json:"podsHavingTooManyRestarts,omitempty"`
MaxPodLifeTimeSeconds *uint `json:"maxPodLifeTimeSeconds,omitempty"`
RemoveDuplicates *RemoveDuplicates `json:"removeDuplicates,omitempty"`
Namespaces Namespaces `json:"namespaces"`
Namespaces *Namespaces `json:"namespaces"`
ThresholdPriority *int32 `json:"thresholdPriority"`
ThresholdPriorityClassName string `json:"thresholdPriorityClassName"`
}
Expand Down
8 changes: 2 additions & 6 deletions pkg/api/v1alpha1/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion pkg/api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion pkg/api/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 9 additions & 3 deletions pkg/descheduler/strategies/node_affinity.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func validatePodsViolatingNodeAffinityParams(params *api.StrategyParameters) err
return fmt.Errorf("NodeAffinityType is empty")
}
// At most one of include/exclude can be set
if len(params.Namespaces.Include) > 0 && len(params.Namespaces.Exclude) > 0 {
if params.Namespaces != nil && len(params.Namespaces.Include) > 0 && len(params.Namespaces.Exclude) > 0 {
return fmt.Errorf("only one of Include/Exclude namespaces can be set")
}
if params.ThresholdPriority != nil && params.ThresholdPriorityClassName != "" {
Expand All @@ -58,6 +58,12 @@ func RemovePodsViolatingNodeAffinity(ctx context.Context, client clientset.Inter
return
}

var includedNamespaces, excludedNamespaces []string
if strategy.Params.Namespaces != nil {
includedNamespaces = strategy.Params.Namespaces.Include
excludedNamespaces = strategy.Params.Namespaces.Exclude
}

for _, nodeAffinity := range strategy.Params.NodeAffinityType {
klog.V(2).Infof("Executing for nodeAffinityType: %v", nodeAffinity)

Expand All @@ -75,8 +81,8 @@ func RemovePodsViolatingNodeAffinity(ctx context.Context, client clientset.Inter
!nodeutil.PodFitsCurrentNode(pod, node) &&
nodeutil.PodFitsAnyNode(pod, nodes)
}),
podutil.WithNamespaces(strategy.Params.Namespaces.Include),
podutil.WithoutNamespaces(strategy.Params.Namespaces.Exclude),
podutil.WithNamespaces(includedNamespaces),
podutil.WithoutNamespaces(excludedNamespaces),
)
if err != nil {
klog.Errorf("failed to get pods from %v: %v", node.Name, err)
Expand Down
15 changes: 9 additions & 6 deletions pkg/descheduler/strategies/node_taint.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func validateRemovePodsViolatingNodeTaintsParams(params *api.StrategyParameters)
}

// At most one of include/exclude can be set
if len(params.Namespaces.Include) > 0 && len(params.Namespaces.Exclude) > 0 {
if params.Namespaces != nil && len(params.Namespaces.Include) > 0 && len(params.Namespaces.Exclude) > 0 {
return fmt.Errorf("only one of Include/Exclude namespaces can be set")
}
if params.ThresholdPriority != nil && params.ThresholdPriorityClassName != "" {
Expand All @@ -52,10 +52,13 @@ func RemovePodsViolatingNodeTaints(ctx context.Context, client clientset.Interfa
klog.V(1).Info(err)
return
}
var namespaces api.Namespaces
if strategy.Params != nil {
namespaces = strategy.Params.Namespaces

var includedNamespaces, excludedNamespaces []string
if strategy.Params != nil && strategy.Params.Namespaces != nil {
includedNamespaces = strategy.Params.Namespaces.Include
excludedNamespaces = strategy.Params.Namespaces.Exclude
}

thresholdPriority, err := utils.GetPriorityFromStrategyParams(ctx, client, strategy.Params)
if err != nil {
klog.V(1).Infof("failed to get threshold priority from strategy's params: %#v", err)
Expand All @@ -71,8 +74,8 @@ func RemovePodsViolatingNodeTaints(ctx context.Context, client clientset.Interfa
podutil.WithFilter(func(pod *v1.Pod) bool {
return podEvictor.IsEvictable(pod, thresholdPriority)
}),
podutil.WithNamespaces(namespaces.Include),
podutil.WithoutNamespaces(namespaces.Exclude),
podutil.WithNamespaces(includedNamespaces),
podutil.WithoutNamespaces(excludedNamespaces),
)
if err != nil {
//no pods evicted as error encountered retrieving evictable Pods
Expand Down
17 changes: 10 additions & 7 deletions pkg/descheduler/strategies/pod_antiaffinity.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (
podutil "sigs.k8s.io/descheduler/pkg/descheduler/pod"
"sigs.k8s.io/descheduler/pkg/utils"

"k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clientset "k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"
Expand All @@ -37,7 +37,7 @@ func validateRemovePodsViolatingInterPodAntiAffinityParams(params *api.StrategyP
}

// At most one of include/exclude can be set
if len(params.Namespaces.Include) > 0 && len(params.Namespaces.Exclude) > 0 {
if params.Namespaces != nil && len(params.Namespaces.Include) > 0 && len(params.Namespaces.Exclude) > 0 {
return fmt.Errorf("only one of Include/Exclude namespaces can be set")
}
if params.ThresholdPriority != nil && params.ThresholdPriorityClassName != "" {
Expand All @@ -53,10 +53,13 @@ func RemovePodsViolatingInterPodAntiAffinity(ctx context.Context, client clients
klog.V(1).Info(err)
return
}
var namespaces api.Namespaces
if strategy.Params != nil {
namespaces = strategy.Params.Namespaces

var includedNamespaces, excludedNamespaces []string
if strategy.Params != nil && strategy.Params.Namespaces != nil {
includedNamespaces = strategy.Params.Namespaces.Include
excludedNamespaces = strategy.Params.Namespaces.Exclude
}

thresholdPriority, err := utils.GetPriorityFromStrategyParams(ctx, client, strategy.Params)
if err != nil {
klog.V(1).Infof("failed to get threshold priority from strategy's params: %#v", err)
Expand All @@ -72,8 +75,8 @@ func RemovePodsViolatingInterPodAntiAffinity(ctx context.Context, client clients
podutil.WithFilter(func(pod *v1.Pod) bool {
return podEvictor.IsEvictable(pod, thresholdPriority)
}),
podutil.WithNamespaces(namespaces.Include),
podutil.WithoutNamespaces(namespaces.Exclude),
podutil.WithNamespaces(includedNamespaces),
podutil.WithoutNamespaces(excludedNamespaces),
)
if err != nil {
return
Expand Down
19 changes: 13 additions & 6 deletions pkg/descheduler/strategies/pod_lifetime.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func validatePodLifeTimeParams(params *api.StrategyParameters) error {
}

// At most one of include/exclude can be set
if len(params.Namespaces.Include) > 0 && len(params.Namespaces.Exclude) > 0 {
if params.Namespaces != nil && len(params.Namespaces.Include) > 0 && len(params.Namespaces.Exclude) > 0 {
return fmt.Errorf("only one of Include/Exclude namespaces can be set")
}
if params.ThresholdPriority != nil && params.ThresholdPriorityClassName != "" {
Expand All @@ -53,16 +53,23 @@ func PodLifeTime(ctx context.Context, client clientset.Interface, strategy api.D
klog.V(1).Info(err)
return
}

thresholdPriority, err := utils.GetPriorityFromStrategyParams(ctx, client, strategy.Params)
if err != nil {
klog.V(1).Infof("failed to get threshold priority from strategy's params: %#v", err)
return
}

var includedNamespaces, excludedNamespaces []string
if strategy.Params.Namespaces != nil {
includedNamespaces = strategy.Params.Namespaces.Include
excludedNamespaces = strategy.Params.Namespaces.Exclude
}

for _, node := range nodes {
klog.V(1).Infof("Processing node: %#v", node.Name)

pods := listOldPodsOnNode(ctx, client, node, strategy.Params, podEvictor, thresholdPriority)
pods := listOldPodsOnNode(ctx, client, node, includedNamespaces, excludedNamespaces, *strategy.Params.MaxPodLifeTimeSeconds, podEvictor, thresholdPriority)
for _, pod := range pods {
success, err := podEvictor.EvictPod(ctx, pod, node, "PodLifeTime")
if success {
Expand All @@ -78,16 +85,16 @@ func PodLifeTime(ctx context.Context, client clientset.Interface, strategy api.D
}
}

func listOldPodsOnNode(ctx context.Context, client clientset.Interface, node *v1.Node, params *api.StrategyParameters, podEvictor *evictions.PodEvictor, thresholdPriority int32) []*v1.Pod {
func listOldPodsOnNode(ctx context.Context, client clientset.Interface, node *v1.Node, includedNamespaces, excludedNamespaces []string, maxPodLifeTimeSeconds uint, podEvictor *evictions.PodEvictor, thresholdPriority int32) []*v1.Pod {
pods, err := podutil.ListPodsOnANode(
ctx,
client,
node,
podutil.WithFilter(func(pod *v1.Pod) bool {
return podEvictor.IsEvictable(pod, thresholdPriority)
}),
podutil.WithNamespaces(params.Namespaces.Include),
podutil.WithoutNamespaces(params.Namespaces.Exclude),
podutil.WithNamespaces(includedNamespaces),
podutil.WithoutNamespaces(excludedNamespaces),
)
if err != nil {
return nil
Expand All @@ -96,7 +103,7 @@ func listOldPodsOnNode(ctx context.Context, client clientset.Interface, node *v1
var oldPods []*v1.Pod
for _, pod := range pods {
podAgeSeconds := uint(v1meta.Now().Sub(pod.GetCreationTimestamp().Local()).Seconds())
if podAgeSeconds > *params.MaxPodLifeTimeSeconds {
if podAgeSeconds > maxPodLifeTimeSeconds {
oldPods = append(oldPods, pod)
}
}
Expand Down
13 changes: 10 additions & 3 deletions pkg/descheduler/strategies/toomanyrestarts.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func validateRemovePodsHavingTooManyRestartsParams(params *api.StrategyParameter
}

// At most one of include/exclude can be set
if len(params.Namespaces.Include) > 0 && len(params.Namespaces.Exclude) > 0 {
if params.Namespaces != nil && len(params.Namespaces.Include) > 0 && len(params.Namespaces.Exclude) > 0 {
return fmt.Errorf("only one of Include/Exclude namespaces can be set")
}
if params.ThresholdPriority != nil && params.ThresholdPriorityClassName != "" {
Expand All @@ -54,12 +54,19 @@ func RemovePodsHavingTooManyRestarts(ctx context.Context, client clientset.Inter
klog.V(1).Info(err)
return
}

thresholdPriority, err := utils.GetPriorityFromStrategyParams(ctx, client, strategy.Params)
if err != nil {
klog.V(1).Infof("failed to get threshold priority from strategy's params: %#v", err)
return
}

var includedNamespaces, excludedNamespaces []string
if strategy.Params.Namespaces != nil {
includedNamespaces = strategy.Params.Namespaces.Include
excludedNamespaces = strategy.Params.Namespaces.Exclude
}

for _, node := range nodes {
klog.V(1).Infof("Processing node: %s", node.Name)
pods, err := podutil.ListPodsOnANode(
Expand All @@ -69,8 +76,8 @@ func RemovePodsHavingTooManyRestarts(ctx context.Context, client clientset.Inter
podutil.WithFilter(func(pod *v1.Pod) bool {
return podEvictor.IsEvictable(pod, thresholdPriority)
}),
podutil.WithNamespaces(strategy.Params.Namespaces.Include),
podutil.WithoutNamespaces(strategy.Params.Namespaces.Exclude),
podutil.WithNamespaces(includedNamespaces),
podutil.WithoutNamespaces(excludedNamespaces),
)
if err != nil {
klog.Errorf("Error when list pods at node %s", node.Name)
Expand Down
13 changes: 7 additions & 6 deletions test/e2e/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ import (
"context"
"math"
"os"
"sigs.k8s.io/descheduler/pkg/utils"
"sort"
"strings"
"testing"
"time"

"sigs.k8s.io/descheduler/pkg/utils"

v1 "k8s.io/api/core/v1"
schedulingv1 "k8s.io/api/scheduling/v1"
"k8s.io/apimachinery/pkg/api/resource"
Expand Down Expand Up @@ -188,7 +189,7 @@ func TestLowNodeUtilization(t *testing.T) {
deleteRC(ctx, t, clientSet, rc)
}

func runPodLifetimeStrategy(ctx context.Context, clientset clientset.Interface, nodeInformer coreinformers.NodeInformer, namespaces deschedulerapi.Namespaces, priorityClass string, priority *int32) {
func runPodLifetimeStrategy(ctx context.Context, clientset clientset.Interface, nodeInformer coreinformers.NodeInformer, namespaces *deschedulerapi.Namespaces, priorityClass string, priority *int32) {
// Run descheduler.
evictionPolicyGroupVersion, err := eutils.SupportEviction(clientset)
if err != nil || len(evictionPolicyGroupVersion) == 0 {
Expand Down Expand Up @@ -286,7 +287,7 @@ func TestNamespaceConstraintsInclude(t *testing.T) {
t.Logf("Existing pods: %v", initialPodNames)

t.Logf("set the strategy to delete pods from %v namespace", rc.Namespace)
runPodLifetimeStrategy(ctx, clientSet, nodeInformer, deschedulerapi.Namespaces{
runPodLifetimeStrategy(ctx, clientSet, nodeInformer, &deschedulerapi.Namespaces{
Include: []string{rc.Namespace},
}, "", nil)

Expand Down Expand Up @@ -357,7 +358,7 @@ func TestNamespaceConstraintsExclude(t *testing.T) {
t.Logf("Existing pods: %v", initialPodNames)

t.Logf("set the strategy to delete pods from namespaces except the %v namespace", rc.Namespace)
runPodLifetimeStrategy(ctx, clientSet, nodeInformer, deschedulerapi.Namespaces{
runPodLifetimeStrategy(ctx, clientSet, nodeInformer, &deschedulerapi.Namespaces{
Exclude: []string{rc.Namespace},
}, "", nil)

Expand Down Expand Up @@ -461,10 +462,10 @@ func testPriority(t *testing.T, isPriorityClass bool) {

if isPriorityClass {
t.Logf("set the strategy to delete pods with priority lower than priority class %s", highPriorityClass.Name)
runPodLifetimeStrategy(ctx, clientSet, nodeInformer, deschedulerapi.Namespaces{}, highPriorityClass.Name, nil)
runPodLifetimeStrategy(ctx, clientSet, nodeInformer, nil, highPriorityClass.Name, nil)
} else {
t.Logf("set the strategy to delete pods with priority lower than %d", highPriority)
runPodLifetimeStrategy(ctx, clientSet, nodeInformer, deschedulerapi.Namespaces{}, "", &highPriority)
runPodLifetimeStrategy(ctx, clientSet, nodeInformer, nil, "", &highPriority)
}

t.Logf("Waiting 10s")
Expand Down