Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
d94c7dd7
Unverified
Commit
d94c7dd7
authored
Jul 03, 2019
by
Kubernetes Prow Robot
Committed by
GitHub
Jul 03, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #79708 from josephburnett/release-1.14
Cherry pick #79035 to 1.14 (Fix HPA feedback from writing status.replicas to spec.replicas)
parents
2cc51009
d881d48b
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
19 additions
and
18 deletions
+19
-18
horizontal.go
pkg/controller/podautoscaler/horizontal.go
+14
-13
replica_calculator.go
pkg/controller/podautoscaler/replica_calculator.go
+4
-4
replica_calculator_test.go
pkg/controller/podautoscaler/replica_calculator_test.go
+1
-1
No files found.
pkg/controller/podautoscaler/horizontal.go
View file @
d94c7dd7
...
...
@@ -23,7 +23,7 @@ import (
autoscalingv1
"k8s.io/api/autoscaling/v1"
autoscalingv2
"k8s.io/api/autoscaling/v2beta2"
"k8s.io/api/core/v1"
v1
"k8s.io/api/core/v1"
apiequality
"k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/errors"
apimeta
"k8s.io/apimachinery/pkg/api/meta"
...
...
@@ -235,7 +235,8 @@ func (a *HorizontalController) processNextWorkItem() bool {
func
(
a
*
HorizontalController
)
computeReplicasForMetrics
(
hpa
*
autoscalingv2
.
HorizontalPodAutoscaler
,
scale
*
autoscalingv1
.
Scale
,
metricSpecs
[]
autoscalingv2
.
MetricSpec
)
(
replicas
int32
,
metric
string
,
statuses
[]
autoscalingv2
.
MetricStatus
,
timestamp
time
.
Time
,
err
error
)
{
currentReplicas
:=
scale
.
Status
.
Replicas
specReplicas
:=
scale
.
Spec
.
Replicas
statusReplicas
:=
scale
.
Status
.
Replicas
statuses
=
make
([]
autoscalingv2
.
MetricStatus
,
len
(
metricSpecs
))
...
...
@@ -267,7 +268,7 @@ func (a *HorizontalController) computeReplicasForMetrics(hpa *autoscalingv2.Hori
setCondition
(
hpa
,
autoscalingv2
.
ScalingActive
,
v1
.
ConditionFalse
,
"FailedGetObjectMetric"
,
"the HPA was unable to compute the replica count: %v"
,
err
)
return
0
,
""
,
nil
,
time
.
Time
{},
fmt
.
Errorf
(
"failed to get object metric value: %v"
,
err
)
}
replicaCountProposal
,
timestampProposal
,
metricNameProposal
,
err
=
a
.
computeStatusForObjectMetric
(
current
Replicas
,
metricSpec
,
hpa
,
selector
,
&
statuses
[
i
],
metricSelector
)
replicaCountProposal
,
timestampProposal
,
metricNameProposal
,
err
=
a
.
computeStatusForObjectMetric
(
specReplicas
,
status
Replicas
,
metricSpec
,
hpa
,
selector
,
&
statuses
[
i
],
metricSelector
)
if
err
!=
nil
{
return
0
,
""
,
nil
,
time
.
Time
{},
fmt
.
Errorf
(
"failed to get object metric value: %v"
,
err
)
}
...
...
@@ -278,17 +279,17 @@ func (a *HorizontalController) computeReplicasForMetrics(hpa *autoscalingv2.Hori
setCondition
(
hpa
,
autoscalingv2
.
ScalingActive
,
v1
.
ConditionFalse
,
"FailedGetPodsMetric"
,
"the HPA was unable to compute the replica count: %v"
,
err
)
return
0
,
""
,
nil
,
time
.
Time
{},
fmt
.
Errorf
(
"failed to get pods metric value: %v"
,
err
)
}
replicaCountProposal
,
timestampProposal
,
metricNameProposal
,
err
=
a
.
computeStatusForPodsMetric
(
current
Replicas
,
metricSpec
,
hpa
,
selector
,
&
statuses
[
i
],
metricSelector
)
replicaCountProposal
,
timestampProposal
,
metricNameProposal
,
err
=
a
.
computeStatusForPodsMetric
(
spec
Replicas
,
metricSpec
,
hpa
,
selector
,
&
statuses
[
i
],
metricSelector
)
if
err
!=
nil
{
return
0
,
""
,
nil
,
time
.
Time
{},
fmt
.
Errorf
(
"failed to get object metric value: %v"
,
err
)
}
case
autoscalingv2
.
ResourceMetricSourceType
:
replicaCountProposal
,
timestampProposal
,
metricNameProposal
,
err
=
a
.
computeStatusForResourceMetric
(
current
Replicas
,
metricSpec
,
hpa
,
selector
,
&
statuses
[
i
])
replicaCountProposal
,
timestampProposal
,
metricNameProposal
,
err
=
a
.
computeStatusForResourceMetric
(
spec
Replicas
,
metricSpec
,
hpa
,
selector
,
&
statuses
[
i
])
if
err
!=
nil
{
return
0
,
""
,
nil
,
time
.
Time
{},
err
}
case
autoscalingv2
.
ExternalMetricSourceType
:
replicaCountProposal
,
timestampProposal
,
metricNameProposal
,
err
=
a
.
computeStatusForExternalMetric
(
current
Replicas
,
metricSpec
,
hpa
,
selector
,
&
statuses
[
i
])
replicaCountProposal
,
timestampProposal
,
metricNameProposal
,
err
=
a
.
computeStatusForExternalMetric
(
specReplicas
,
status
Replicas
,
metricSpec
,
hpa
,
selector
,
&
statuses
[
i
])
if
err
!=
nil
{
return
0
,
""
,
nil
,
time
.
Time
{},
err
}
...
...
@@ -326,9 +327,9 @@ func (a *HorizontalController) reconcileKey(key string) (deleted bool, err error
}
// computeStatusForObjectMetric computes the desired number of replicas for the specified metric of type ObjectMetricSourceType.
func
(
a
*
HorizontalController
)
computeStatusForObjectMetric
(
current
Replicas
int32
,
metricSpec
autoscalingv2
.
MetricSpec
,
hpa
*
autoscalingv2
.
HorizontalPodAutoscaler
,
selector
labels
.
Selector
,
status
*
autoscalingv2
.
MetricStatus
,
metricSelector
labels
.
Selector
)
(
int32
,
time
.
Time
,
string
,
error
)
{
func
(
a
*
HorizontalController
)
computeStatusForObjectMetric
(
specReplicas
,
status
Replicas
int32
,
metricSpec
autoscalingv2
.
MetricSpec
,
hpa
*
autoscalingv2
.
HorizontalPodAutoscaler
,
selector
labels
.
Selector
,
status
*
autoscalingv2
.
MetricStatus
,
metricSelector
labels
.
Selector
)
(
int32
,
time
.
Time
,
string
,
error
)
{
if
metricSpec
.
Object
.
Target
.
Type
==
autoscalingv2
.
ValueMetricType
{
replicaCountProposal
,
utilizationProposal
,
timestampProposal
,
err
:=
a
.
replicaCalc
.
GetObjectMetricReplicas
(
current
Replicas
,
metricSpec
.
Object
.
Target
.
Value
.
MilliValue
(),
metricSpec
.
Object
.
Metric
.
Name
,
hpa
.
Namespace
,
&
metricSpec
.
Object
.
DescribedObject
,
selector
,
metricSelector
)
replicaCountProposal
,
utilizationProposal
,
timestampProposal
,
err
:=
a
.
replicaCalc
.
GetObjectMetricReplicas
(
spec
Replicas
,
metricSpec
.
Object
.
Target
.
Value
.
MilliValue
(),
metricSpec
.
Object
.
Metric
.
Name
,
hpa
.
Namespace
,
&
metricSpec
.
Object
.
DescribedObject
,
selector
,
metricSelector
)
if
err
!=
nil
{
a
.
eventRecorder
.
Event
(
hpa
,
v1
.
EventTypeWarning
,
"FailedGetObjectMetric"
,
err
.
Error
())
setCondition
(
hpa
,
autoscalingv2
.
ScalingActive
,
v1
.
ConditionFalse
,
"FailedGetObjectMetric"
,
"the HPA was unable to compute the replica count: %v"
,
err
)
...
...
@@ -349,7 +350,7 @@ func (a *HorizontalController) computeStatusForObjectMetric(currentReplicas int3
}
return
replicaCountProposal
,
timestampProposal
,
fmt
.
Sprintf
(
"%s metric %s"
,
metricSpec
.
Object
.
DescribedObject
.
Kind
,
metricSpec
.
Object
.
Metric
.
Name
),
nil
}
else
if
metricSpec
.
Object
.
Target
.
Type
==
autoscalingv2
.
AverageValueMetricType
{
replicaCountProposal
,
utilizationProposal
,
timestampProposal
,
err
:=
a
.
replicaCalc
.
GetObjectPerPodMetricReplicas
(
current
Replicas
,
metricSpec
.
Object
.
Target
.
AverageValue
.
MilliValue
(),
metricSpec
.
Object
.
Metric
.
Name
,
hpa
.
Namespace
,
&
metricSpec
.
Object
.
DescribedObject
,
metricSelector
)
replicaCountProposal
,
utilizationProposal
,
timestampProposal
,
err
:=
a
.
replicaCalc
.
GetObjectPerPodMetricReplicas
(
status
Replicas
,
metricSpec
.
Object
.
Target
.
AverageValue
.
MilliValue
(),
metricSpec
.
Object
.
Metric
.
Name
,
hpa
.
Namespace
,
&
metricSpec
.
Object
.
DescribedObject
,
metricSelector
)
if
err
!=
nil
{
a
.
eventRecorder
.
Event
(
hpa
,
v1
.
EventTypeWarning
,
"FailedGetObjectMetric"
,
err
.
Error
())
setCondition
(
hpa
,
autoscalingv2
.
ScalingActive
,
v1
.
ConditionFalse
,
"FailedGetObjectMetric"
,
"the HPA was unable to compute the replica count: %v"
,
err
)
...
...
@@ -452,9 +453,9 @@ func (a *HorizontalController) computeStatusForResourceMetric(currentReplicas in
}
// computeStatusForExternalMetric computes the desired number of replicas for the specified metric of type ExternalMetricSourceType.
func
(
a
*
HorizontalController
)
computeStatusForExternalMetric
(
current
Replicas
int32
,
metricSpec
autoscalingv2
.
MetricSpec
,
hpa
*
autoscalingv2
.
HorizontalPodAutoscaler
,
selector
labels
.
Selector
,
status
*
autoscalingv2
.
MetricStatus
)
(
int32
,
time
.
Time
,
string
,
error
)
{
func
(
a
*
HorizontalController
)
computeStatusForExternalMetric
(
specReplicas
,
status
Replicas
int32
,
metricSpec
autoscalingv2
.
MetricSpec
,
hpa
*
autoscalingv2
.
HorizontalPodAutoscaler
,
selector
labels
.
Selector
,
status
*
autoscalingv2
.
MetricStatus
)
(
int32
,
time
.
Time
,
string
,
error
)
{
if
metricSpec
.
External
.
Target
.
AverageValue
!=
nil
{
replicaCountProposal
,
utilizationProposal
,
timestampProposal
,
err
:=
a
.
replicaCalc
.
GetExternalPerPodMetricReplicas
(
current
Replicas
,
metricSpec
.
External
.
Target
.
AverageValue
.
MilliValue
(),
metricSpec
.
External
.
Metric
.
Name
,
hpa
.
Namespace
,
metricSpec
.
External
.
Metric
.
Selector
)
replicaCountProposal
,
utilizationProposal
,
timestampProposal
,
err
:=
a
.
replicaCalc
.
GetExternalPerPodMetricReplicas
(
status
Replicas
,
metricSpec
.
External
.
Target
.
AverageValue
.
MilliValue
(),
metricSpec
.
External
.
Metric
.
Name
,
hpa
.
Namespace
,
metricSpec
.
External
.
Metric
.
Selector
)
if
err
!=
nil
{
a
.
eventRecorder
.
Event
(
hpa
,
v1
.
EventTypeWarning
,
"FailedGetExternalMetric"
,
err
.
Error
())
setCondition
(
hpa
,
autoscalingv2
.
ScalingActive
,
v1
.
ConditionFalse
,
"FailedGetExternalMetric"
,
"the HPA was unable to compute the replica count: %v"
,
err
)
...
...
@@ -475,7 +476,7 @@ func (a *HorizontalController) computeStatusForExternalMetric(currentReplicas in
return
replicaCountProposal
,
timestampProposal
,
fmt
.
Sprintf
(
"external metric %s(%+v)"
,
metricSpec
.
External
.
Metric
.
Name
,
metricSpec
.
External
.
Metric
.
Selector
),
nil
}
if
metricSpec
.
External
.
Target
.
Value
!=
nil
{
replicaCountProposal
,
utilizationProposal
,
timestampProposal
,
err
:=
a
.
replicaCalc
.
GetExternalMetricReplicas
(
current
Replicas
,
metricSpec
.
External
.
Target
.
Value
.
MilliValue
(),
metricSpec
.
External
.
Metric
.
Name
,
hpa
.
Namespace
,
metricSpec
.
External
.
Metric
.
Selector
,
selector
)
replicaCountProposal
,
utilizationProposal
,
timestampProposal
,
err
:=
a
.
replicaCalc
.
GetExternalMetricReplicas
(
spec
Replicas
,
metricSpec
.
External
.
Target
.
Value
.
MilliValue
(),
metricSpec
.
External
.
Metric
.
Name
,
hpa
.
Namespace
,
metricSpec
.
External
.
Metric
.
Selector
,
selector
)
if
err
!=
nil
{
a
.
eventRecorder
.
Event
(
hpa
,
v1
.
EventTypeWarning
,
"FailedGetExternalMetric"
,
err
.
Error
())
setCondition
(
hpa
,
autoscalingv2
.
ScalingActive
,
v1
.
ConditionFalse
,
"FailedGetExternalMetric"
,
"the HPA was unable to compute the replica count: %v"
,
err
)
...
...
@@ -550,7 +551,7 @@ func (a *HorizontalController) reconcileAutoscaler(hpav1Shared *autoscalingv1.Ho
return
fmt
.
Errorf
(
"failed to query scale subresource for %s: %v"
,
reference
,
err
)
}
setCondition
(
hpa
,
autoscalingv2
.
AbleToScale
,
v1
.
ConditionTrue
,
"SucceededGetScale"
,
"the HPA controller was able to get the target's current scale"
)
currentReplicas
:=
scale
.
S
tatus
.
Replicas
currentReplicas
:=
scale
.
S
pec
.
Replicas
a
.
recordInitialRecommendation
(
currentReplicas
,
key
)
var
metricStatuses
[]
autoscalingv2
.
MetricStatus
...
...
pkg/controller/podautoscaler/replica_calculator.go
View file @
d94c7dd7
...
...
@@ -22,7 +22,7 @@ import (
"time"
autoscaling
"k8s.io/api/autoscaling/v2beta2"
"k8s.io/api/core/v1"
v1
"k8s.io/api/core/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/sets"
...
...
@@ -333,7 +333,7 @@ func (c *ReplicaCalculator) GetExternalMetricReplicas(currentReplicas int32, tar
// GetExternalPerPodMetricReplicas calculates the desired replica count based on a
// target metric value per pod (as a milli-value) for the external metric in the
// given namespace, and the current replica count.
func
(
c
*
ReplicaCalculator
)
GetExternalPerPodMetricReplicas
(
current
Replicas
int32
,
targetUtilizationPerPod
int64
,
metricName
,
namespace
string
,
metricSelector
*
metav1
.
LabelSelector
)
(
replicaCount
int32
,
utilization
int64
,
timestamp
time
.
Time
,
err
error
)
{
func
(
c
*
ReplicaCalculator
)
GetExternalPerPodMetricReplicas
(
status
Replicas
int32
,
targetUtilizationPerPod
int64
,
metricName
,
namespace
string
,
metricSelector
*
metav1
.
LabelSelector
)
(
replicaCount
int32
,
utilization
int64
,
timestamp
time
.
Time
,
err
error
)
{
metricLabelSelector
,
err
:=
metav1
.
LabelSelectorAsSelector
(
metricSelector
)
if
err
!=
nil
{
return
0
,
0
,
time
.
Time
{},
err
...
...
@@ -347,13 +347,13 @@ func (c *ReplicaCalculator) GetExternalPerPodMetricReplicas(currentReplicas int3
utilization
=
utilization
+
val
}
replicaCount
=
current
Replicas
replicaCount
=
status
Replicas
usageRatio
:=
float64
(
utilization
)
/
(
float64
(
targetUtilizationPerPod
)
*
float64
(
replicaCount
))
if
math
.
Abs
(
1.0
-
usageRatio
)
>
c
.
tolerance
{
// update number of replicas if the change is large enough
replicaCount
=
int32
(
math
.
Ceil
(
float64
(
utilization
)
/
float64
(
targetUtilizationPerPod
)))
}
utilization
=
int64
(
math
.
Ceil
(
float64
(
utilization
)
/
float64
(
current
Replicas
)))
utilization
=
int64
(
math
.
Ceil
(
float64
(
utilization
)
/
float64
(
status
Replicas
)))
return
replicaCount
,
utilization
,
timestamp
,
nil
}
...
...
pkg/controller/podautoscaler/replica_calculator_test.go
View file @
d94c7dd7
...
...
@@ -23,7 +23,7 @@ import (
"time"
autoscalingv2
"k8s.io/api/autoscaling/v2beta2"
"k8s.io/api/core/v1"
v1
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta/testrestmapper"
"k8s.io/apimachinery/pkg/api/resource"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment