mirror of
https://github.com/kubernetes-sigs/descheduler.git
synced 2026-01-28 06:29:29 +01:00
PodLifeTime: allow custom podStatusPhases
This commit is contained in:
40
README.md
40
README.md
@@ -261,18 +261,36 @@ strategies:
|
|||||||
|
|
||||||
### PodLifeTime
|
### PodLifeTime
|
||||||
|
|
||||||
This strategy evicts pods that are older than `.strategies.PodLifeTime.params.maxPodLifeTimeSeconds` The policy
|
This strategy evicts pods that are older than `maxPodLifeTimeSeconds`. The policy file should look like:
|
||||||
file should look like:
|
|
||||||
|
|
||||||
````
|
```
|
||||||
apiVersion: "descheduler/v1alpha1"
|
apiVersion: "descheduler/v1alpha1"
|
||||||
kind: "DeschedulerPolicy"
|
kind: "DeschedulerPolicy"
|
||||||
strategies:
|
strategies:
|
||||||
"PodLifeTime":
|
"PodLifeTime":
|
||||||
enabled: true
|
enabled: true
|
||||||
params:
|
params:
|
||||||
maxPodLifeTimeSeconds: 86400
|
podLifeTime:
|
||||||
````
|
maxPodLifeTimeSeconds: 86400
|
||||||
|
```
|
||||||
|
|
||||||
|
You can specify `podStatusPhases` to `only` evict pods with specific `StatusPhases`, currently this parameter is limited
|
||||||
|
to `Running` and `Pending`. E.g.
|
||||||
|
|
||||||
|
```
|
||||||
|
apiVersion: "descheduler/v1alpha1"
|
||||||
|
kind: "DeschedulerPolicy"
|
||||||
|
strategies:
|
||||||
|
"PodLifeTime":
|
||||||
|
enabled: true
|
||||||
|
params:
|
||||||
|
podLifeTime:
|
||||||
|
maxPodLifeTimeSeconds: 86400
|
||||||
|
podStatusPhases:
|
||||||
|
- "Pending"
|
||||||
|
```
|
||||||
|
|
||||||
|
Only `Pending` pods will get evicted in this example.
|
||||||
|
|
||||||
## Filter Pods
|
## Filter Pods
|
||||||
|
|
||||||
@@ -290,7 +308,8 @@ strategies:
|
|||||||
"PodLifeTime":
|
"PodLifeTime":
|
||||||
enabled: true
|
enabled: true
|
||||||
params:
|
params:
|
||||||
maxPodLifeTimeSeconds: 86400
|
podLifeTime:
|
||||||
|
maxPodLifeTimeSeconds: 86400
|
||||||
namespaces:
|
namespaces:
|
||||||
include:
|
include:
|
||||||
- "namespace1"
|
- "namespace1"
|
||||||
@@ -307,7 +326,8 @@ strategies:
|
|||||||
"PodLifeTime":
|
"PodLifeTime":
|
||||||
enabled: true
|
enabled: true
|
||||||
params:
|
params:
|
||||||
maxPodLifeTimeSeconds: 86400
|
podLifeTime:
|
||||||
|
maxPodLifeTimeSeconds: 86400
|
||||||
namespaces:
|
namespaces:
|
||||||
exclude:
|
exclude:
|
||||||
- "namespace1"
|
- "namespace1"
|
||||||
@@ -334,7 +354,8 @@ strategies:
|
|||||||
"PodLifeTime":
|
"PodLifeTime":
|
||||||
enabled: true
|
enabled: true
|
||||||
params:
|
params:
|
||||||
maxPodLifeTimeSeconds: 86400
|
podLifeTime:
|
||||||
|
maxPodLifeTimeSeconds: 86400
|
||||||
thresholdPriority: 10000
|
thresholdPriority: 10000
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -346,7 +367,8 @@ strategies:
|
|||||||
"PodLifeTime":
|
"PodLifeTime":
|
||||||
enabled: true
|
enabled: true
|
||||||
params:
|
params:
|
||||||
maxPodLifeTimeSeconds: 86400
|
podLifeTime:
|
||||||
|
maxPodLifeTimeSeconds: 86400
|
||||||
thresholdPriorityClassName: "priorityclass1"
|
thresholdPriorityClassName: "priorityclass1"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -17,4 +17,5 @@ strategies:
|
|||||||
"PodLifeTime":
|
"PodLifeTime":
|
||||||
enabled: true
|
enabled: true
|
||||||
params:
|
params:
|
||||||
maxPodLifeTimeSeconds: 604800 # 7 days
|
podLifeTime:
|
||||||
|
maxPodLifeTimeSeconds: 604800 # 7 days
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ type StrategyParameters struct {
|
|||||||
NodeResourceUtilizationThresholds *NodeResourceUtilizationThresholds
|
NodeResourceUtilizationThresholds *NodeResourceUtilizationThresholds
|
||||||
NodeAffinityType []string
|
NodeAffinityType []string
|
||||||
PodsHavingTooManyRestarts *PodsHavingTooManyRestarts
|
PodsHavingTooManyRestarts *PodsHavingTooManyRestarts
|
||||||
MaxPodLifeTimeSeconds *uint
|
PodLifeTime *PodLifeTime
|
||||||
RemoveDuplicates *RemoveDuplicates
|
RemoveDuplicates *RemoveDuplicates
|
||||||
Namespaces *Namespaces
|
Namespaces *Namespaces
|
||||||
ThresholdPriority *int32
|
ThresholdPriority *int32
|
||||||
@@ -91,3 +91,8 @@ type PodsHavingTooManyRestarts struct {
|
|||||||
type RemoveDuplicates struct {
|
type RemoveDuplicates struct {
|
||||||
ExcludeOwnerKinds []string
|
ExcludeOwnerKinds []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PodLifeTime struct {
|
||||||
|
MaxPodLifeTimeSeconds *uint
|
||||||
|
PodStatusPhases []string
|
||||||
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ type StrategyParameters struct {
|
|||||||
NodeResourceUtilizationThresholds *NodeResourceUtilizationThresholds `json:"nodeResourceUtilizationThresholds,omitempty"`
|
NodeResourceUtilizationThresholds *NodeResourceUtilizationThresholds `json:"nodeResourceUtilizationThresholds,omitempty"`
|
||||||
NodeAffinityType []string `json:"nodeAffinityType,omitempty"`
|
NodeAffinityType []string `json:"nodeAffinityType,omitempty"`
|
||||||
PodsHavingTooManyRestarts *PodsHavingTooManyRestarts `json:"podsHavingTooManyRestarts,omitempty"`
|
PodsHavingTooManyRestarts *PodsHavingTooManyRestarts `json:"podsHavingTooManyRestarts,omitempty"`
|
||||||
MaxPodLifeTimeSeconds *uint `json:"maxPodLifeTimeSeconds,omitempty"`
|
PodLifeTime *PodLifeTime `json:"podLifeTime,omitempty"`
|
||||||
RemoveDuplicates *RemoveDuplicates `json:"removeDuplicates,omitempty"`
|
RemoveDuplicates *RemoveDuplicates `json:"removeDuplicates,omitempty"`
|
||||||
Namespaces *Namespaces `json:"namespaces"`
|
Namespaces *Namespaces `json:"namespaces"`
|
||||||
ThresholdPriority *int32 `json:"thresholdPriority"`
|
ThresholdPriority *int32 `json:"thresholdPriority"`
|
||||||
@@ -89,3 +89,8 @@ type PodsHavingTooManyRestarts struct {
|
|||||||
type RemoveDuplicates struct {
|
type RemoveDuplicates struct {
|
||||||
ExcludeOwnerKinds []string `json:"excludeOwnerKinds,omitempty"`
|
ExcludeOwnerKinds []string `json:"excludeOwnerKinds,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PodLifeTime struct {
|
||||||
|
MaxPodLifeTimeSeconds *uint `json:"maxPodLifeTimeSeconds,omitempty"`
|
||||||
|
PodStatusPhases []string `json:"podStatusPhases,omitempty"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -75,6 +75,16 @@ func RegisterConversions(s *runtime.Scheme) error {
|
|||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := s.AddGeneratedConversionFunc((*PodLifeTime)(nil), (*api.PodLifeTime)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||||
|
return Convert_v1alpha1_PodLifeTime_To_api_PodLifeTime(a.(*PodLifeTime), b.(*api.PodLifeTime), scope)
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := s.AddGeneratedConversionFunc((*api.PodLifeTime)(nil), (*PodLifeTime)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||||
|
return Convert_api_PodLifeTime_To_v1alpha1_PodLifeTime(a.(*api.PodLifeTime), b.(*PodLifeTime), scope)
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if err := s.AddGeneratedConversionFunc((*PodsHavingTooManyRestarts)(nil), (*api.PodsHavingTooManyRestarts)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
if err := s.AddGeneratedConversionFunc((*PodsHavingTooManyRestarts)(nil), (*api.PodsHavingTooManyRestarts)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||||
return Convert_v1alpha1_PodsHavingTooManyRestarts_To_api_PodsHavingTooManyRestarts(a.(*PodsHavingTooManyRestarts), b.(*api.PodsHavingTooManyRestarts), scope)
|
return Convert_v1alpha1_PodsHavingTooManyRestarts_To_api_PodsHavingTooManyRestarts(a.(*PodsHavingTooManyRestarts), b.(*api.PodsHavingTooManyRestarts), scope)
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@@ -204,6 +214,28 @@ func Convert_api_NodeResourceUtilizationThresholds_To_v1alpha1_NodeResourceUtili
|
|||||||
return autoConvert_api_NodeResourceUtilizationThresholds_To_v1alpha1_NodeResourceUtilizationThresholds(in, out, s)
|
return autoConvert_api_NodeResourceUtilizationThresholds_To_v1alpha1_NodeResourceUtilizationThresholds(in, out, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func autoConvert_v1alpha1_PodLifeTime_To_api_PodLifeTime(in *PodLifeTime, out *api.PodLifeTime, s conversion.Scope) error {
|
||||||
|
out.MaxPodLifeTimeSeconds = (*uint)(unsafe.Pointer(in.MaxPodLifeTimeSeconds))
|
||||||
|
out.PodStatusPhases = *(*[]string)(unsafe.Pointer(&in.PodStatusPhases))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert_v1alpha1_PodLifeTime_To_api_PodLifeTime is an autogenerated conversion function.
|
||||||
|
func Convert_v1alpha1_PodLifeTime_To_api_PodLifeTime(in *PodLifeTime, out *api.PodLifeTime, s conversion.Scope) error {
|
||||||
|
return autoConvert_v1alpha1_PodLifeTime_To_api_PodLifeTime(in, out, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func autoConvert_api_PodLifeTime_To_v1alpha1_PodLifeTime(in *api.PodLifeTime, out *PodLifeTime, s conversion.Scope) error {
|
||||||
|
out.MaxPodLifeTimeSeconds = (*uint)(unsafe.Pointer(in.MaxPodLifeTimeSeconds))
|
||||||
|
out.PodStatusPhases = *(*[]string)(unsafe.Pointer(&in.PodStatusPhases))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert_api_PodLifeTime_To_v1alpha1_PodLifeTime is an autogenerated conversion function.
|
||||||
|
func Convert_api_PodLifeTime_To_v1alpha1_PodLifeTime(in *api.PodLifeTime, out *PodLifeTime, s conversion.Scope) error {
|
||||||
|
return autoConvert_api_PodLifeTime_To_v1alpha1_PodLifeTime(in, out, s)
|
||||||
|
}
|
||||||
|
|
||||||
func autoConvert_v1alpha1_PodsHavingTooManyRestarts_To_api_PodsHavingTooManyRestarts(in *PodsHavingTooManyRestarts, out *api.PodsHavingTooManyRestarts, s conversion.Scope) error {
|
func autoConvert_v1alpha1_PodsHavingTooManyRestarts_To_api_PodsHavingTooManyRestarts(in *PodsHavingTooManyRestarts, out *api.PodsHavingTooManyRestarts, s conversion.Scope) error {
|
||||||
out.PodRestartThreshold = in.PodRestartThreshold
|
out.PodRestartThreshold = in.PodRestartThreshold
|
||||||
out.IncludingInitContainers = in.IncludingInitContainers
|
out.IncludingInitContainers = in.IncludingInitContainers
|
||||||
@@ -250,7 +282,7 @@ func autoConvert_v1alpha1_StrategyParameters_To_api_StrategyParameters(in *Strat
|
|||||||
out.NodeResourceUtilizationThresholds = (*api.NodeResourceUtilizationThresholds)(unsafe.Pointer(in.NodeResourceUtilizationThresholds))
|
out.NodeResourceUtilizationThresholds = (*api.NodeResourceUtilizationThresholds)(unsafe.Pointer(in.NodeResourceUtilizationThresholds))
|
||||||
out.NodeAffinityType = *(*[]string)(unsafe.Pointer(&in.NodeAffinityType))
|
out.NodeAffinityType = *(*[]string)(unsafe.Pointer(&in.NodeAffinityType))
|
||||||
out.PodsHavingTooManyRestarts = (*api.PodsHavingTooManyRestarts)(unsafe.Pointer(in.PodsHavingTooManyRestarts))
|
out.PodsHavingTooManyRestarts = (*api.PodsHavingTooManyRestarts)(unsafe.Pointer(in.PodsHavingTooManyRestarts))
|
||||||
out.MaxPodLifeTimeSeconds = (*uint)(unsafe.Pointer(in.MaxPodLifeTimeSeconds))
|
out.PodLifeTime = (*api.PodLifeTime)(unsafe.Pointer(in.PodLifeTime))
|
||||||
out.RemoveDuplicates = (*api.RemoveDuplicates)(unsafe.Pointer(in.RemoveDuplicates))
|
out.RemoveDuplicates = (*api.RemoveDuplicates)(unsafe.Pointer(in.RemoveDuplicates))
|
||||||
out.Namespaces = (*api.Namespaces)(unsafe.Pointer(in.Namespaces))
|
out.Namespaces = (*api.Namespaces)(unsafe.Pointer(in.Namespaces))
|
||||||
out.ThresholdPriority = (*int32)(unsafe.Pointer(in.ThresholdPriority))
|
out.ThresholdPriority = (*int32)(unsafe.Pointer(in.ThresholdPriority))
|
||||||
@@ -267,7 +299,7 @@ func autoConvert_api_StrategyParameters_To_v1alpha1_StrategyParameters(in *api.S
|
|||||||
out.NodeResourceUtilizationThresholds = (*NodeResourceUtilizationThresholds)(unsafe.Pointer(in.NodeResourceUtilizationThresholds))
|
out.NodeResourceUtilizationThresholds = (*NodeResourceUtilizationThresholds)(unsafe.Pointer(in.NodeResourceUtilizationThresholds))
|
||||||
out.NodeAffinityType = *(*[]string)(unsafe.Pointer(&in.NodeAffinityType))
|
out.NodeAffinityType = *(*[]string)(unsafe.Pointer(&in.NodeAffinityType))
|
||||||
out.PodsHavingTooManyRestarts = (*PodsHavingTooManyRestarts)(unsafe.Pointer(in.PodsHavingTooManyRestarts))
|
out.PodsHavingTooManyRestarts = (*PodsHavingTooManyRestarts)(unsafe.Pointer(in.PodsHavingTooManyRestarts))
|
||||||
out.MaxPodLifeTimeSeconds = (*uint)(unsafe.Pointer(in.MaxPodLifeTimeSeconds))
|
out.PodLifeTime = (*PodLifeTime)(unsafe.Pointer(in.PodLifeTime))
|
||||||
out.RemoveDuplicates = (*RemoveDuplicates)(unsafe.Pointer(in.RemoveDuplicates))
|
out.RemoveDuplicates = (*RemoveDuplicates)(unsafe.Pointer(in.RemoveDuplicates))
|
||||||
out.Namespaces = (*Namespaces)(unsafe.Pointer(in.Namespaces))
|
out.Namespaces = (*Namespaces)(unsafe.Pointer(in.Namespaces))
|
||||||
out.ThresholdPriority = (*int32)(unsafe.Pointer(in.ThresholdPriority))
|
out.ThresholdPriority = (*int32)(unsafe.Pointer(in.ThresholdPriority))
|
||||||
|
|||||||
@@ -148,6 +148,32 @@ func (in *NodeResourceUtilizationThresholds) DeepCopy() *NodeResourceUtilization
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *PodLifeTime) DeepCopyInto(out *PodLifeTime) {
|
||||||
|
*out = *in
|
||||||
|
if in.MaxPodLifeTimeSeconds != nil {
|
||||||
|
in, out := &in.MaxPodLifeTimeSeconds, &out.MaxPodLifeTimeSeconds
|
||||||
|
*out = new(uint)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.PodStatusPhases != nil {
|
||||||
|
in, out := &in.PodStatusPhases, &out.PodStatusPhases
|
||||||
|
*out = make([]string, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodLifeTime.
|
||||||
|
func (in *PodLifeTime) DeepCopy() *PodLifeTime {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(PodLifeTime)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *PodsHavingTooManyRestarts) DeepCopyInto(out *PodsHavingTooManyRestarts) {
|
func (in *PodsHavingTooManyRestarts) DeepCopyInto(out *PodsHavingTooManyRestarts) {
|
||||||
*out = *in
|
*out = *in
|
||||||
@@ -247,10 +273,10 @@ func (in *StrategyParameters) DeepCopyInto(out *StrategyParameters) {
|
|||||||
*out = new(PodsHavingTooManyRestarts)
|
*out = new(PodsHavingTooManyRestarts)
|
||||||
**out = **in
|
**out = **in
|
||||||
}
|
}
|
||||||
if in.MaxPodLifeTimeSeconds != nil {
|
if in.PodLifeTime != nil {
|
||||||
in, out := &in.MaxPodLifeTimeSeconds, &out.MaxPodLifeTimeSeconds
|
in, out := &in.PodLifeTime, &out.PodLifeTime
|
||||||
*out = new(uint)
|
*out = new(PodLifeTime)
|
||||||
**out = **in
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
if in.RemoveDuplicates != nil {
|
if in.RemoveDuplicates != nil {
|
||||||
in, out := &in.RemoveDuplicates, &out.RemoveDuplicates
|
in, out := &in.RemoveDuplicates, &out.RemoveDuplicates
|
||||||
|
|||||||
@@ -148,6 +148,32 @@ func (in *NodeResourceUtilizationThresholds) DeepCopy() *NodeResourceUtilization
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *PodLifeTime) DeepCopyInto(out *PodLifeTime) {
|
||||||
|
*out = *in
|
||||||
|
if in.MaxPodLifeTimeSeconds != nil {
|
||||||
|
in, out := &in.MaxPodLifeTimeSeconds, &out.MaxPodLifeTimeSeconds
|
||||||
|
*out = new(uint)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.PodStatusPhases != nil {
|
||||||
|
in, out := &in.PodStatusPhases, &out.PodStatusPhases
|
||||||
|
*out = make([]string, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodLifeTime.
|
||||||
|
func (in *PodLifeTime) DeepCopy() *PodLifeTime {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(PodLifeTime)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *PodsHavingTooManyRestarts) DeepCopyInto(out *PodsHavingTooManyRestarts) {
|
func (in *PodsHavingTooManyRestarts) DeepCopyInto(out *PodsHavingTooManyRestarts) {
|
||||||
*out = *in
|
*out = *in
|
||||||
@@ -247,10 +273,10 @@ func (in *StrategyParameters) DeepCopyInto(out *StrategyParameters) {
|
|||||||
*out = new(PodsHavingTooManyRestarts)
|
*out = new(PodsHavingTooManyRestarts)
|
||||||
**out = **in
|
**out = **in
|
||||||
}
|
}
|
||||||
if in.MaxPodLifeTimeSeconds != nil {
|
if in.PodLifeTime != nil {
|
||||||
in, out := &in.MaxPodLifeTimeSeconds, &out.MaxPodLifeTimeSeconds
|
in, out := &in.PodLifeTime, &out.PodLifeTime
|
||||||
*out = new(uint)
|
*out = new(PodLifeTime)
|
||||||
**out = **in
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
if in.RemoveDuplicates != nil {
|
if in.RemoveDuplicates != nil {
|
||||||
in, out := &in.RemoveDuplicates, &out.RemoveDuplicates
|
in, out := &in.RemoveDuplicates, &out.RemoveDuplicates
|
||||||
|
|||||||
@@ -32,10 +32,18 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func validatePodLifeTimeParams(params *api.StrategyParameters) error {
|
func validatePodLifeTimeParams(params *api.StrategyParameters) error {
|
||||||
if params == nil || params.MaxPodLifeTimeSeconds == nil {
|
if params == nil || params.PodLifeTime == nil || params.PodLifeTime.MaxPodLifeTimeSeconds == nil {
|
||||||
return fmt.Errorf("MaxPodLifeTimeSeconds not set")
|
return fmt.Errorf("MaxPodLifeTimeSeconds not set")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if params.PodLifeTime.PodStatusPhases != nil {
|
||||||
|
for _, phase := range params.PodLifeTime.PodStatusPhases {
|
||||||
|
if phase != string(v1.PodPending) && phase != string(v1.PodRunning) {
|
||||||
|
return fmt.Errorf("only Pending and Running phases are supported in PodLifeTime")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// At most one of include/exclude can be set
|
// At most one of include/exclude can be set
|
||||||
if params.Namespaces != nil && 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")
|
return fmt.Errorf("only one of Include/Exclude namespaces can be set")
|
||||||
@@ -68,14 +76,26 @@ func PodLifeTime(ctx context.Context, client clientset.Interface, strategy api.D
|
|||||||
|
|
||||||
evictable := podEvictor.Evictable(evictions.WithPriorityThreshold(thresholdPriority))
|
evictable := podEvictor.Evictable(evictions.WithPriorityThreshold(thresholdPriority))
|
||||||
|
|
||||||
|
filter := evictable.IsEvictable
|
||||||
|
if strategy.Params.PodLifeTime.PodStatusPhases != nil {
|
||||||
|
filter = func(pod *v1.Pod) bool {
|
||||||
|
for _, phase := range strategy.Params.PodLifeTime.PodStatusPhases {
|
||||||
|
if string(pod.Status.Phase) == phase {
|
||||||
|
return evictable.IsEvictable(pod)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for _, node := range nodes {
|
for _, node := range nodes {
|
||||||
klog.V(1).InfoS("Processing node", "node", klog.KObj(node))
|
klog.V(1).InfoS("Processing node", "node", klog.KObj(node))
|
||||||
|
|
||||||
pods := listOldPodsOnNode(ctx, client, node, includedNamespaces, excludedNamespaces, *strategy.Params.MaxPodLifeTimeSeconds, evictable.IsEvictable)
|
pods := listOldPodsOnNode(ctx, client, node, includedNamespaces, excludedNamespaces, *strategy.Params.PodLifeTime.MaxPodLifeTimeSeconds, filter)
|
||||||
for _, pod := range pods {
|
for _, pod := range pods {
|
||||||
success, err := podEvictor.EvictPod(ctx, pod, node, "PodLifeTime")
|
success, err := podEvictor.EvictPod(ctx, pod, node, "PodLifeTime")
|
||||||
if success {
|
if success {
|
||||||
klog.V(1).InfoS("Evicted pod because it exceeded its lifetime", "pod", klog.KObj(pod), "maxPodLifeTime", *strategy.Params.MaxPodLifeTimeSeconds)
|
klog.V(1).InfoS("Evicted pod because it exceeded its lifetime", "pod", klog.KObj(pod), "maxPodLifeTime", *strategy.Params.PodLifeTime.MaxPodLifeTimeSeconds)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -85,6 +85,19 @@ func TestPodLifeTime(t *testing.T) {
|
|||||||
p5.ObjectMeta.OwnerReferences = ownerRef4
|
p5.ObjectMeta.OwnerReferences = ownerRef4
|
||||||
p6.ObjectMeta.OwnerReferences = ownerRef4
|
p6.ObjectMeta.OwnerReferences = ownerRef4
|
||||||
|
|
||||||
|
// Setup two old pods with different status phases
|
||||||
|
p9 := test.BuildTestPod("p9", 100, 0, node.Name, nil)
|
||||||
|
p9.Namespace = "dev"
|
||||||
|
p9.ObjectMeta.CreationTimestamp = olderPodCreationTime
|
||||||
|
p10 := test.BuildTestPod("p10", 100, 0, node.Name, nil)
|
||||||
|
p10.Namespace = "dev"
|
||||||
|
p10.ObjectMeta.CreationTimestamp = olderPodCreationTime
|
||||||
|
|
||||||
|
p9.Status.Phase = "Pending"
|
||||||
|
p10.Status.Phase = "Running"
|
||||||
|
p9.ObjectMeta.OwnerReferences = ownerRef1
|
||||||
|
p10.ObjectMeta.OwnerReferences = ownerRef1
|
||||||
|
|
||||||
var maxLifeTime uint = 600
|
var maxLifeTime uint = 600
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
description string
|
description string
|
||||||
@@ -98,7 +111,7 @@ func TestPodLifeTime(t *testing.T) {
|
|||||||
strategy: api.DeschedulerStrategy{
|
strategy: api.DeschedulerStrategy{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
Params: &api.StrategyParameters{
|
Params: &api.StrategyParameters{
|
||||||
MaxPodLifeTimeSeconds: &maxLifeTime,
|
PodLifeTime: &api.PodLifeTime{MaxPodLifeTimeSeconds: &maxLifeTime},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
maxPodsToEvictPerNode: 5,
|
maxPodsToEvictPerNode: 5,
|
||||||
@@ -110,7 +123,7 @@ func TestPodLifeTime(t *testing.T) {
|
|||||||
strategy: api.DeschedulerStrategy{
|
strategy: api.DeschedulerStrategy{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
Params: &api.StrategyParameters{
|
Params: &api.StrategyParameters{
|
||||||
MaxPodLifeTimeSeconds: &maxLifeTime,
|
PodLifeTime: &api.PodLifeTime{MaxPodLifeTimeSeconds: &maxLifeTime},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
maxPodsToEvictPerNode: 5,
|
maxPodsToEvictPerNode: 5,
|
||||||
@@ -122,7 +135,7 @@ func TestPodLifeTime(t *testing.T) {
|
|||||||
strategy: api.DeschedulerStrategy{
|
strategy: api.DeschedulerStrategy{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
Params: &api.StrategyParameters{
|
Params: &api.StrategyParameters{
|
||||||
MaxPodLifeTimeSeconds: &maxLifeTime,
|
PodLifeTime: &api.PodLifeTime{MaxPodLifeTimeSeconds: &maxLifeTime},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
maxPodsToEvictPerNode: 5,
|
maxPodsToEvictPerNode: 5,
|
||||||
@@ -134,13 +147,28 @@ func TestPodLifeTime(t *testing.T) {
|
|||||||
strategy: api.DeschedulerStrategy{
|
strategy: api.DeschedulerStrategy{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
Params: &api.StrategyParameters{
|
Params: &api.StrategyParameters{
|
||||||
MaxPodLifeTimeSeconds: &maxLifeTime,
|
PodLifeTime: &api.PodLifeTime{MaxPodLifeTimeSeconds: &maxLifeTime},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
maxPodsToEvictPerNode: 5,
|
maxPodsToEvictPerNode: 5,
|
||||||
pods: []v1.Pod{*p7, *p8},
|
pods: []v1.Pod{*p7, *p8},
|
||||||
expectedEvictedPodCount: 0,
|
expectedEvictedPodCount: 0,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
description: "Two old pods with different status phases. 1 should be evicted.",
|
||||||
|
strategy: api.DeschedulerStrategy{
|
||||||
|
Enabled: true,
|
||||||
|
Params: &api.StrategyParameters{
|
||||||
|
PodLifeTime: &api.PodLifeTime{
|
||||||
|
MaxPodLifeTimeSeconds: &maxLifeTime,
|
||||||
|
PodStatusPhases: []string{"Pending"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
maxPodsToEvictPerNode: 5,
|
||||||
|
pods: []v1.Pod{*p9, *p10},
|
||||||
|
expectedEvictedPodCount: 1,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ func runPodLifetimeStrategy(ctx context.Context, clientset clientset.Interface,
|
|||||||
deschedulerapi.DeschedulerStrategy{
|
deschedulerapi.DeschedulerStrategy{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
Params: &deschedulerapi.StrategyParameters{
|
Params: &deschedulerapi.StrategyParameters{
|
||||||
MaxPodLifeTimeSeconds: &maxPodLifeTimeSeconds,
|
PodLifeTime: &deschedulerapi.PodLifeTime{MaxPodLifeTimeSeconds: &maxPodLifeTimeSeconds},
|
||||||
Namespaces: namespaces,
|
Namespaces: namespaces,
|
||||||
ThresholdPriority: priority,
|
ThresholdPriority: priority,
|
||||||
ThresholdPriorityClassName: priorityClass,
|
ThresholdPriorityClassName: priorityClass,
|
||||||
|
|||||||
Reference in New Issue
Block a user