mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 21:47:07 +00:00
Handle resource.Quantity changes in eviction thresholds
This commit is contained in:
parent
5e4308f91d
commit
e3c8c4c22b
@ -148,7 +148,7 @@ func parseThresholdStatement(statement string) (Threshold, error) {
|
|||||||
return Threshold{
|
return Threshold{
|
||||||
Signal: signal,
|
Signal: signal,
|
||||||
Operator: operator,
|
Operator: operator,
|
||||||
Value: quantity,
|
Value: &quantity,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,14 +213,10 @@ func podUsage(podStats statsapi.PodStats) (api.ResourceList, error) {
|
|||||||
// disk usage (if known)
|
// disk usage (if known)
|
||||||
// TODO: need to handle volumes
|
// TODO: need to handle volumes
|
||||||
for _, fsStats := range []*statsapi.FsStats{container.Rootfs, container.Logs} {
|
for _, fsStats := range []*statsapi.FsStats{container.Rootfs, container.Logs} {
|
||||||
if err := disk.Add(*diskUsage(fsStats)); err != nil {
|
disk.Add(*diskUsage(fsStats))
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// memory usage (if known)
|
// memory usage (if known)
|
||||||
if err := memory.Add(*memoryUsage(container.Memory)); err != nil {
|
memory.Add(*memoryUsage(container.Memory))
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return api.ResourceList{
|
return api.ResourceList{
|
||||||
api.ResourceMemory: memory,
|
api.ResourceMemory: memory,
|
||||||
@ -430,7 +426,7 @@ func makeSignalObservations(summaryProvider stats.SummaryProvider) (signalObserv
|
|||||||
statsFunc := cachedStatsFunc(summary.Pods)
|
statsFunc := cachedStatsFunc(summary.Pods)
|
||||||
// build an evaluation context for current eviction signals
|
// build an evaluation context for current eviction signals
|
||||||
result := signalObservations{}
|
result := signalObservations{}
|
||||||
result[SignalMemoryAvailable] = *resource.NewQuantity(int64(*summary.Node.Memory.AvailableBytes), resource.BinarySI)
|
result[SignalMemoryAvailable] = resource.NewQuantity(int64(*summary.Node.Memory.AvailableBytes), resource.BinarySI)
|
||||||
return result, statsFunc, nil
|
return result, statsFunc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,7 +442,7 @@ func thresholdsMet(thresholds []Threshold, observations signalObservations) []Th
|
|||||||
}
|
}
|
||||||
// determine if we have met the specified threshold
|
// determine if we have met the specified threshold
|
||||||
thresholdMet := false
|
thresholdMet := false
|
||||||
thresholdResult := threshold.Value.Cmp(observed)
|
thresholdResult := threshold.Value.Cmp(*observed)
|
||||||
switch threshold.Operator {
|
switch threshold.Operator {
|
||||||
case OpLessThan:
|
case OpLessThan:
|
||||||
thresholdMet = thresholdResult > 0
|
thresholdMet = thresholdResult > 0
|
||||||
@ -538,7 +534,7 @@ func hasNodeCondition(inputs []api.NodeConditionType, item api.NodeConditionType
|
|||||||
// hasThreshold returns true if the node condition is in the input list
|
// hasThreshold returns true if the node condition is in the input list
|
||||||
func hasThreshold(inputs []Threshold, item Threshold) bool {
|
func hasThreshold(inputs []Threshold, item Threshold) bool {
|
||||||
for _, input := range inputs {
|
for _, input := range inputs {
|
||||||
if input.GracePeriod == item.GracePeriod && input.Operator == item.Operator && input.Signal == item.Signal && input.Value.Cmp(item.Value) == 0 {
|
if input.GracePeriod == item.GracePeriod && input.Operator == item.Operator && input.Signal == item.Signal && input.Value.Cmp(*item.Value) == 0 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,11 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/types"
|
"k8s.io/kubernetes/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func quantityMustParse(value string) *resource.Quantity {
|
||||||
|
q := resource.MustParse(value)
|
||||||
|
return &q
|
||||||
|
}
|
||||||
|
|
||||||
func TestParseThresholdConfig(t *testing.T) {
|
func TestParseThresholdConfig(t *testing.T) {
|
||||||
gracePeriod, _ := time.ParseDuration("30s")
|
gracePeriod, _ := time.ParseDuration("30s")
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
@ -55,12 +60,12 @@ func TestParseThresholdConfig(t *testing.T) {
|
|||||||
{
|
{
|
||||||
Signal: SignalMemoryAvailable,
|
Signal: SignalMemoryAvailable,
|
||||||
Operator: OpLessThan,
|
Operator: OpLessThan,
|
||||||
Value: resource.MustParse("150Mi"),
|
Value: quantityMustParse("150Mi"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Signal: SignalMemoryAvailable,
|
Signal: SignalMemoryAvailable,
|
||||||
Operator: OpLessThan,
|
Operator: OpLessThan,
|
||||||
Value: resource.MustParse("300Mi"),
|
Value: quantityMustParse("300Mi"),
|
||||||
GracePeriod: gracePeriod,
|
GracePeriod: gracePeriod,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -145,7 +150,7 @@ func thresholdEqual(a Threshold, b Threshold) bool {
|
|||||||
return a.GracePeriod == b.GracePeriod &&
|
return a.GracePeriod == b.GracePeriod &&
|
||||||
a.Operator == b.Operator &&
|
a.Operator == b.Operator &&
|
||||||
a.Signal == b.Signal &&
|
a.Signal == b.Signal &&
|
||||||
a.Value.Cmp(b.Value) == 0
|
a.Value.Cmp(*b.Value) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestOrderedByQoS ensures we order BestEffort < Burstable < Guaranteed
|
// TestOrderedByQoS ensures we order BestEffort < Burstable < Guaranteed
|
||||||
@ -348,7 +353,7 @@ func TestThresholdsMet(t *testing.T) {
|
|||||||
hardThreshold := Threshold{
|
hardThreshold := Threshold{
|
||||||
Signal: SignalMemoryAvailable,
|
Signal: SignalMemoryAvailable,
|
||||||
Operator: OpLessThan,
|
Operator: OpLessThan,
|
||||||
Value: resource.MustParse("1Gi"),
|
Value: quantityMustParse("1Gi"),
|
||||||
}
|
}
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
thresholds []Threshold
|
thresholds []Threshold
|
||||||
@ -363,14 +368,14 @@ func TestThresholdsMet(t *testing.T) {
|
|||||||
"threshold-met": {
|
"threshold-met": {
|
||||||
thresholds: []Threshold{hardThreshold},
|
thresholds: []Threshold{hardThreshold},
|
||||||
observations: signalObservations{
|
observations: signalObservations{
|
||||||
SignalMemoryAvailable: resource.MustParse("500Mi"),
|
SignalMemoryAvailable: quantityMustParse("500Mi"),
|
||||||
},
|
},
|
||||||
result: []Threshold{hardThreshold},
|
result: []Threshold{hardThreshold},
|
||||||
},
|
},
|
||||||
"threshold-not-met": {
|
"threshold-not-met": {
|
||||||
thresholds: []Threshold{hardThreshold},
|
thresholds: []Threshold{hardThreshold},
|
||||||
observations: signalObservations{
|
observations: signalObservations{
|
||||||
SignalMemoryAvailable: resource.MustParse("2Gi"),
|
SignalMemoryAvailable: quantityMustParse("2Gi"),
|
||||||
},
|
},
|
||||||
result: []Threshold{},
|
result: []Threshold{},
|
||||||
},
|
},
|
||||||
@ -387,7 +392,7 @@ func TestThresholdsFirstObservedAt(t *testing.T) {
|
|||||||
hardThreshold := Threshold{
|
hardThreshold := Threshold{
|
||||||
Signal: SignalMemoryAvailable,
|
Signal: SignalMemoryAvailable,
|
||||||
Operator: OpLessThan,
|
Operator: OpLessThan,
|
||||||
Value: resource.MustParse("1Gi"),
|
Value: quantityMustParse("1Gi"),
|
||||||
}
|
}
|
||||||
now := unversioned.Now()
|
now := unversioned.Now()
|
||||||
oldTime := unversioned.NewTime(now.Time.Add(-1 * time.Minute))
|
oldTime := unversioned.NewTime(now.Time.Add(-1 * time.Minute))
|
||||||
@ -435,12 +440,12 @@ func TestThresholdsMetGracePeriod(t *testing.T) {
|
|||||||
hardThreshold := Threshold{
|
hardThreshold := Threshold{
|
||||||
Signal: SignalMemoryAvailable,
|
Signal: SignalMemoryAvailable,
|
||||||
Operator: OpLessThan,
|
Operator: OpLessThan,
|
||||||
Value: resource.MustParse("1Gi"),
|
Value: quantityMustParse("1Gi"),
|
||||||
}
|
}
|
||||||
softThreshold := Threshold{
|
softThreshold := Threshold{
|
||||||
Signal: SignalMemoryAvailable,
|
Signal: SignalMemoryAvailable,
|
||||||
Operator: OpLessThan,
|
Operator: OpLessThan,
|
||||||
Value: resource.MustParse("2Gi"),
|
Value: quantityMustParse("2Gi"),
|
||||||
GracePeriod: 1 * time.Minute,
|
GracePeriod: 1 * time.Minute,
|
||||||
}
|
}
|
||||||
oldTime := unversioned.NewTime(now.Time.Add(-2 * time.Minute))
|
oldTime := unversioned.NewTime(now.Time.Add(-2 * time.Minute))
|
||||||
|
@ -103,7 +103,7 @@ func TestMemoryPressure(t *testing.T) {
|
|||||||
{
|
{
|
||||||
Signal: SignalMemoryAvailable,
|
Signal: SignalMemoryAvailable,
|
||||||
Operator: OpLessThan,
|
Operator: OpLessThan,
|
||||||
Value: resource.MustParse("1Gi"),
|
Value: quantityMustParse("1Gi"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ type Threshold struct {
|
|||||||
// Operator represents a relationship of a signal to a value.
|
// Operator represents a relationship of a signal to a value.
|
||||||
Operator ThresholdOperator
|
Operator ThresholdOperator
|
||||||
// value is a quantity associated with the signal that is evaluated against the specified operator.
|
// value is a quantity associated with the signal that is evaluated against the specified operator.
|
||||||
Value resource.Quantity
|
Value *resource.Quantity
|
||||||
// GracePeriod represents the amount of time that a threshold must be met before eviction is triggered.
|
// GracePeriod represents the amount of time that a threshold must be met before eviction is triggered.
|
||||||
GracePeriod time.Duration
|
GracePeriod time.Duration
|
||||||
}
|
}
|
||||||
@ -88,7 +88,7 @@ type statsFunc func(pod *api.Pod) (statsapi.PodStats, bool)
|
|||||||
type rankFunc func(pods []*api.Pod, stats statsFunc)
|
type rankFunc func(pods []*api.Pod, stats statsFunc)
|
||||||
|
|
||||||
// signalObservations maps a signal to an observed quantity
|
// signalObservations maps a signal to an observed quantity
|
||||||
type signalObservations map[Signal]resource.Quantity
|
type signalObservations map[Signal]*resource.Quantity
|
||||||
|
|
||||||
// thresholdsObservedAt maps a threshold to a time that it was observed
|
// thresholdsObservedAt maps a threshold to a time that it was observed
|
||||||
type thresholdsObservedAt map[Threshold]time.Time
|
type thresholdsObservedAt map[Threshold]time.Time
|
||||||
|
Loading…
Reference in New Issue
Block a user