Handle resource.Quantity changes in eviction thresholds

This commit is contained in:
Clayton Coleman 2016-05-18 10:27:59 -04:00
parent 5e4308f91d
commit e3c8c4c22b
No known key found for this signature in database
GPG Key ID: 3D16906B4F1C5CB3
4 changed files with 23 additions and 22 deletions

View File

@ -148,7 +148,7 @@ func parseThresholdStatement(statement string) (Threshold, error) {
return Threshold{
Signal: signal,
Operator: operator,
Value: quantity,
Value: &quantity,
}, nil
}
@ -213,14 +213,10 @@ func podUsage(podStats statsapi.PodStats) (api.ResourceList, error) {
// disk usage (if known)
// TODO: need to handle volumes
for _, fsStats := range []*statsapi.FsStats{container.Rootfs, container.Logs} {
if err := disk.Add(*diskUsage(fsStats)); err != nil {
return nil, err
}
disk.Add(*diskUsage(fsStats))
}
// memory usage (if known)
if err := memory.Add(*memoryUsage(container.Memory)); err != nil {
return nil, err
}
memory.Add(*memoryUsage(container.Memory))
}
return api.ResourceList{
api.ResourceMemory: memory,
@ -430,7 +426,7 @@ func makeSignalObservations(summaryProvider stats.SummaryProvider) (signalObserv
statsFunc := cachedStatsFunc(summary.Pods)
// build an evaluation context for current eviction signals
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
}
@ -446,7 +442,7 @@ func thresholdsMet(thresholds []Threshold, observations signalObservations) []Th
}
// determine if we have met the specified threshold
thresholdMet := false
thresholdResult := threshold.Value.Cmp(observed)
thresholdResult := threshold.Value.Cmp(*observed)
switch threshold.Operator {
case OpLessThan:
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
func hasThreshold(inputs []Threshold, item Threshold) bool {
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
}
}

View File

@ -30,6 +30,11 @@ import (
"k8s.io/kubernetes/pkg/types"
)
func quantityMustParse(value string) *resource.Quantity {
q := resource.MustParse(value)
return &q
}
func TestParseThresholdConfig(t *testing.T) {
gracePeriod, _ := time.ParseDuration("30s")
testCases := map[string]struct {
@ -55,12 +60,12 @@ func TestParseThresholdConfig(t *testing.T) {
{
Signal: SignalMemoryAvailable,
Operator: OpLessThan,
Value: resource.MustParse("150Mi"),
Value: quantityMustParse("150Mi"),
},
{
Signal: SignalMemoryAvailable,
Operator: OpLessThan,
Value: resource.MustParse("300Mi"),
Value: quantityMustParse("300Mi"),
GracePeriod: gracePeriod,
},
},
@ -145,7 +150,7 @@ func thresholdEqual(a Threshold, b Threshold) bool {
return a.GracePeriod == b.GracePeriod &&
a.Operator == b.Operator &&
a.Signal == b.Signal &&
a.Value.Cmp(b.Value) == 0
a.Value.Cmp(*b.Value) == 0
}
// TestOrderedByQoS ensures we order BestEffort < Burstable < Guaranteed
@ -348,7 +353,7 @@ func TestThresholdsMet(t *testing.T) {
hardThreshold := Threshold{
Signal: SignalMemoryAvailable,
Operator: OpLessThan,
Value: resource.MustParse("1Gi"),
Value: quantityMustParse("1Gi"),
}
testCases := map[string]struct {
thresholds []Threshold
@ -363,14 +368,14 @@ func TestThresholdsMet(t *testing.T) {
"threshold-met": {
thresholds: []Threshold{hardThreshold},
observations: signalObservations{
SignalMemoryAvailable: resource.MustParse("500Mi"),
SignalMemoryAvailable: quantityMustParse("500Mi"),
},
result: []Threshold{hardThreshold},
},
"threshold-not-met": {
thresholds: []Threshold{hardThreshold},
observations: signalObservations{
SignalMemoryAvailable: resource.MustParse("2Gi"),
SignalMemoryAvailable: quantityMustParse("2Gi"),
},
result: []Threshold{},
},
@ -387,7 +392,7 @@ func TestThresholdsFirstObservedAt(t *testing.T) {
hardThreshold := Threshold{
Signal: SignalMemoryAvailable,
Operator: OpLessThan,
Value: resource.MustParse("1Gi"),
Value: quantityMustParse("1Gi"),
}
now := unversioned.Now()
oldTime := unversioned.NewTime(now.Time.Add(-1 * time.Minute))
@ -435,12 +440,12 @@ func TestThresholdsMetGracePeriod(t *testing.T) {
hardThreshold := Threshold{
Signal: SignalMemoryAvailable,
Operator: OpLessThan,
Value: resource.MustParse("1Gi"),
Value: quantityMustParse("1Gi"),
}
softThreshold := Threshold{
Signal: SignalMemoryAvailable,
Operator: OpLessThan,
Value: resource.MustParse("2Gi"),
Value: quantityMustParse("2Gi"),
GracePeriod: 1 * time.Minute,
}
oldTime := unversioned.NewTime(now.Time.Add(-2 * time.Minute))

View File

@ -103,7 +103,7 @@ func TestMemoryPressure(t *testing.T) {
{
Signal: SignalMemoryAvailable,
Operator: OpLessThan,
Value: resource.MustParse("1Gi"),
Value: quantityMustParse("1Gi"),
},
},
}

View File

@ -55,7 +55,7 @@ type Threshold struct {
// Operator represents a relationship of a signal to a value.
Operator ThresholdOperator
// 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 time.Duration
}
@ -88,7 +88,7 @@ type statsFunc func(pod *api.Pod) (statsapi.PodStats, bool)
type rankFunc func(pods []*api.Pod, stats statsFunc)
// 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
type thresholdsObservedAt map[Threshold]time.Time