`scale{Up,Down}Adjustment` to add/remove constant number of replicas on scaling (#315)

* `scale{Up,Down}Adjustment` to add/remove constant number of replicas on scaling

Ref #305

* Bump chart version
This commit is contained in:
Yusuke Kuoka 2021-02-16 17:16:26 +09:00 committed by GitHub
parent 35d047db01
commit 434823bcb3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 61 additions and 5 deletions

View File

@ -126,6 +126,16 @@ type MetricSpec struct {
// to determine how many pods should be removed. // to determine how many pods should be removed.
// +optional // +optional
ScaleDownFactor string `json:"scaleDownFactor,omitempty"` ScaleDownFactor string `json:"scaleDownFactor,omitempty"`
// ScaleUpAdjustment is the number of runners added on scale-up.
// You can only specify either ScaleUpFactor or ScaleUpAdjustment.
// +optional
ScaleUpAdjustment int `json:"scaleUpAdjustment,omitempty"`
// ScaleDownAdjustment is the number of runners removed on scale-down.
// You can only specify either ScaleDownFactor or ScaleDownAdjustment.
// +optional
ScaleDownAdjustment int `json:"scaleDownAdjustment,omitempty"`
} }
type HorizontalRunnerAutoscalerStatus struct { type HorizontalRunnerAutoscalerStatus struct {

View File

@ -15,7 +15,7 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes # This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version. # to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/) # Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.4.0 version: 0.5.0
home: https://github.com/summerwind/actions-runner-controller home: https://github.com/summerwind/actions-runner-controller

View File

@ -78,6 +78,11 @@ spec:
items: items:
type: string type: string
type: array type: array
scaleDownAdjustment:
description: ScaleDownAdjustment is the number of runners removed
on scale-down. You can only specify either ScaleDownFactor or
ScaleDownAdjustment.
type: integer
scaleDownFactor: scaleDownFactor:
description: ScaleDownFactor is the multiplicative factor applied description: ScaleDownFactor is the multiplicative factor applied
to the current number of runners used to determine how many to the current number of runners used to determine how many
@ -87,6 +92,10 @@ spec:
description: ScaleDownThreshold is the percentage of busy runners description: ScaleDownThreshold is the percentage of busy runners
less than which will trigger the hpa to scale the runners down. less than which will trigger the hpa to scale the runners down.
type: string type: string
scaleUpAdjustment:
description: ScaleUpAdjustment is the number of runners added
on scale-up. You can only specify either ScaleUpFactor or ScaleUpAdjustment.
type: integer
scaleUpFactor: scaleUpFactor:
description: ScaleUpFactor is the multiplicative factor applied description: ScaleUpFactor is the multiplicative factor applied
to the current number of runners used to determine how many to the current number of runners used to determine how many

View File

@ -78,6 +78,11 @@ spec:
items: items:
type: string type: string
type: array type: array
scaleDownAdjustment:
description: ScaleDownAdjustment is the number of runners removed
on scale-down. You can only specify either ScaleDownFactor or
ScaleDownAdjustment.
type: integer
scaleDownFactor: scaleDownFactor:
description: ScaleDownFactor is the multiplicative factor applied description: ScaleDownFactor is the multiplicative factor applied
to the current number of runners used to determine how many to the current number of runners used to determine how many
@ -87,6 +92,10 @@ spec:
description: ScaleDownThreshold is the percentage of busy runners description: ScaleDownThreshold is the percentage of busy runners
less than which will trigger the hpa to scale the runners down. less than which will trigger the hpa to scale the runners down.
type: string type: string
scaleUpAdjustment:
description: ScaleUpAdjustment is the number of runners added
on scale-up. You can only specify either ScaleUpFactor or ScaleUpAdjustment.
type: integer
scaleUpFactor: scaleUpFactor:
description: ScaleUpFactor is the multiplicative factor applied description: ScaleUpFactor is the multiplicative factor applied
to the current number of runners used to determine how many to the current number of runners used to determine how many

View File

@ -222,14 +222,34 @@ func (r *HorizontalRunnerAutoscalerReconciler) calculateReplicasByPercentageRunn
scaleDownThreshold = sdt scaleDownThreshold = sdt
} }
scaleUpAdjustment := metrics.ScaleUpAdjustment
if scaleUpAdjustment != 0 {
if metrics.ScaleUpAdjustment < 0 {
return nil, errors.New("validating autoscaling metrics: spec.autoscaling.metrics[].scaleUpAdjustment cannot be lower than 0")
}
if metrics.ScaleUpFactor != "" { if metrics.ScaleUpFactor != "" {
return nil, errors.New("validating autoscaling metrics: spec.autoscaling.metrics[]: scaleUpAdjustment and scaleUpFactor cannot be specified together")
}
} else if metrics.ScaleUpFactor != "" {
suf, err := strconv.ParseFloat(metrics.ScaleUpFactor, 64) suf, err := strconv.ParseFloat(metrics.ScaleUpFactor, 64)
if err != nil { if err != nil {
return nil, errors.New("validating autoscaling metrics: spec.autoscaling.metrics[].scaleUpFactor cannot be parsed into a float64") return nil, errors.New("validating autoscaling metrics: spec.autoscaling.metrics[].scaleUpFactor cannot be parsed into a float64")
} }
scaleUpFactor = suf scaleUpFactor = suf
} }
scaleDownAdjustment := metrics.ScaleDownAdjustment
if scaleDownAdjustment != 0 {
if metrics.ScaleDownAdjustment < 0 {
return nil, errors.New("validating autoscaling metrics: spec.autoscaling.metrics[].scaleDownAdjustment cannot be lower than 0")
}
if metrics.ScaleDownFactor != "" { if metrics.ScaleDownFactor != "" {
return nil, errors.New("validating autoscaling metrics: spec.autoscaling.metrics[]: scaleDownAdjustment and scaleDownFactor cannot be specified together")
}
} else if metrics.ScaleDownFactor != "" {
sdf, err := strconv.ParseFloat(metrics.ScaleDownFactor, 64) sdf, err := strconv.ParseFloat(metrics.ScaleDownFactor, 64)
if err != nil { if err != nil {
return nil, errors.New("validating autoscaling metrics: spec.autoscaling.metrics[].scaleDownFactor cannot be parsed into a float64") return nil, errors.New("validating autoscaling metrics: spec.autoscaling.metrics[].scaleDownFactor cannot be parsed into a float64")
@ -273,9 +293,17 @@ func (r *HorizontalRunnerAutoscalerReconciler) calculateReplicasByPercentageRunn
var desiredReplicas int var desiredReplicas int
fractionBusy := float64(numRunnersBusy) / float64(numRunners) fractionBusy := float64(numRunnersBusy) / float64(numRunners)
if fractionBusy >= scaleUpThreshold { if fractionBusy >= scaleUpThreshold {
if scaleUpAdjustment > 0 {
desiredReplicas = numRunners + scaleUpAdjustment
} else {
desiredReplicas = int(math.Ceil(float64(numRunners) * scaleUpFactor)) desiredReplicas = int(math.Ceil(float64(numRunners) * scaleUpFactor))
}
} else if fractionBusy < scaleDownThreshold { } else if fractionBusy < scaleDownThreshold {
if scaleDownAdjustment > 0 {
desiredReplicas = numRunners - scaleDownAdjustment
} else {
desiredReplicas = int(float64(numRunners) * scaleDownFactor) desiredReplicas = int(float64(numRunners) * scaleDownFactor)
}
} else { } else {
desiredReplicas = *rd.Spec.Replicas desiredReplicas = *rd.Spec.Replicas
} }