mirror of https://github.com/docker/compose.git
Merge pull request #817 from docker/scalescale
Configure autoscaling parameters
This commit is contained in:
commit
34a7466571
|
@ -17,6 +17,7 @@
|
||||||
package ecs
|
package ecs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
applicationautoscaling2 "github.com/aws/aws-sdk-go/service/applicationautoscaling"
|
applicationautoscaling2 "github.com/aws/aws-sdk-go/service/applicationautoscaling"
|
||||||
|
@ -26,13 +27,37 @@ import (
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (b *ecsAPIService) createAutoscalingPolicy(project *types.Project, resources awsResources, template *cloudformation.Template, service types.ServiceConfig) {
|
type autoscalingConfig struct {
|
||||||
|
Memory int `json:"memory,omitempty"`
|
||||||
|
CPU int `json:"cpu,omitempty"`
|
||||||
|
Min int `json:"min,omitempty"`
|
||||||
|
Max int `json:"max,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *ecsAPIService) createAutoscalingPolicy(project *types.Project, resources awsResources, template *cloudformation.Template, service types.ServiceConfig) error {
|
||||||
if service.Deploy == nil {
|
if service.Deploy == nil {
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
v, ok := service.Deploy.Extensions[extensionAutoScaling]
|
v, ok := service.Deploy.Extensions[extensionAutoScaling]
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
marshalled, err := json.Marshal(v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var config autoscalingConfig
|
||||||
|
err = json.Unmarshal(marshalled, &config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.Memory != 0 && config.CPU != 0 {
|
||||||
|
return fmt.Errorf("%s can't be set with both cpu and memory targets", extensionAutoScaling)
|
||||||
|
}
|
||||||
|
if config.Max == 0 {
|
||||||
|
return fmt.Errorf("%s MUST define max replicas", extensionAutoScaling)
|
||||||
}
|
}
|
||||||
|
|
||||||
role := fmt.Sprintf("%sAutoScalingRole", normalizeResourceName(service.Name))
|
role := fmt.Sprintf("%sAutoScalingRole", normalizeResourceName(service.Name))
|
||||||
|
@ -66,8 +91,8 @@ func (b *ecsAPIService) createAutoscalingPolicy(project *types.Project, resource
|
||||||
|
|
||||||
target := fmt.Sprintf("%sScalableTarget", normalizeResourceName(service.Name))
|
target := fmt.Sprintf("%sScalableTarget", normalizeResourceName(service.Name))
|
||||||
template.Resources[target] = &applicationautoscaling.ScalableTarget{
|
template.Resources[target] = &applicationautoscaling.ScalableTarget{
|
||||||
MaxCapacity: 10,
|
MaxCapacity: config.Max,
|
||||||
MinCapacity: 0,
|
MinCapacity: config.Min,
|
||||||
ResourceId: resourceID,
|
ResourceId: resourceID,
|
||||||
RoleARN: cloudformation.GetAtt(role, "Arn"),
|
RoleARN: cloudformation.GetAtt(role, "Arn"),
|
||||||
ScalableDimension: applicationautoscaling2.ScalableDimensionEcsServiceDesiredCount,
|
ScalableDimension: applicationautoscaling2.ScalableDimensionEcsServiceDesiredCount,
|
||||||
|
@ -75,6 +100,15 @@ func (b *ecsAPIService) createAutoscalingPolicy(project *types.Project, resource
|
||||||
AWSCloudFormationDependsOn: []string{serviceResourceName(service.Name)},
|
AWSCloudFormationDependsOn: []string{serviceResourceName(service.Name)},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
metric = applicationautoscaling2.MetricTypeEcsserviceAverageCpuutilization
|
||||||
|
targetPercent = config.CPU
|
||||||
|
)
|
||||||
|
if config.Memory != 0 {
|
||||||
|
metric = applicationautoscaling2.MetricTypeEcsserviceAverageMemoryUtilization
|
||||||
|
targetPercent = config.Memory
|
||||||
|
}
|
||||||
|
|
||||||
policy := fmt.Sprintf("%sScalingPolicy", normalizeResourceName(service.Name))
|
policy := fmt.Sprintf("%sScalingPolicy", normalizeResourceName(service.Name))
|
||||||
template.Resources[policy] = &applicationautoscaling.ScalingPolicy{
|
template.Resources[policy] = &applicationautoscaling.ScalingPolicy{
|
||||||
PolicyType: "TargetTrackingScaling",
|
PolicyType: "TargetTrackingScaling",
|
||||||
|
@ -83,11 +117,12 @@ func (b *ecsAPIService) createAutoscalingPolicy(project *types.Project, resource
|
||||||
StepScalingPolicyConfiguration: nil,
|
StepScalingPolicyConfiguration: nil,
|
||||||
TargetTrackingScalingPolicyConfiguration: &applicationautoscaling.ScalingPolicy_TargetTrackingScalingPolicyConfiguration{
|
TargetTrackingScalingPolicyConfiguration: &applicationautoscaling.ScalingPolicy_TargetTrackingScalingPolicyConfiguration{
|
||||||
PredefinedMetricSpecification: &applicationautoscaling.ScalingPolicy_PredefinedMetricSpecification{
|
PredefinedMetricSpecification: &applicationautoscaling.ScalingPolicy_PredefinedMetricSpecification{
|
||||||
PredefinedMetricType: applicationautoscaling2.MetricTypeEcsserviceAverageCpuutilization,
|
PredefinedMetricType: metric,
|
||||||
},
|
},
|
||||||
ScaleOutCooldown: 60,
|
ScaleOutCooldown: 60,
|
||||||
ScaleInCooldown: 60,
|
ScaleInCooldown: 60,
|
||||||
TargetValue: float64(v.(int)),
|
TargetValue: float64(targetPercent),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,13 +29,15 @@ services:
|
||||||
foo:
|
foo:
|
||||||
image: hello_world
|
image: hello_world
|
||||||
deploy:
|
deploy:
|
||||||
x-aws-autoscaling: 75
|
x-aws-autoscaling:
|
||||||
|
cpu: 75
|
||||||
|
max: 10
|
||||||
`, useDefaultVPC)
|
`, useDefaultVPC)
|
||||||
target := template.Resources["FooScalableTarget"].(*autoscaling.ScalableTarget)
|
target := template.Resources["FooScalableTarget"].(*autoscaling.ScalableTarget)
|
||||||
assert.Check(t, target != nil)
|
assert.Check(t, target != nil)
|
||||||
|
assert.Check(t, target.MaxCapacity == 10) //nolint:staticcheck
|
||||||
|
|
||||||
policy := template.Resources["FooScalingPolicy"].(*autoscaling.ScalingPolicy)
|
policy := template.Resources["FooScalingPolicy"].(*autoscaling.ScalingPolicy)
|
||||||
if policy == nil || policy.TargetTrackingScalingPolicyConfiguration == nil {
|
assert.Check(t, policy != nil)
|
||||||
t.Fail()
|
assert.Check(t, policy.TargetTrackingScalingPolicyConfiguration.TargetValue == float64(75)) //nolint:staticcheck
|
||||||
}
|
|
||||||
assert.Check(t, policy.TargetTrackingScalingPolicyConfiguration.TargetValue == float64(75))
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,10 @@ func (b *ecsAPIService) convert(ctx context.Context, project *types.Project) (*c
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
b.createAutoscalingPolicy(project, resources, template, service)
|
err = b.createAutoscalingPolicy(project, resources, template, service)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = b.createCapacityProvider(ctx, project, template, resources)
|
err = b.createCapacityProvider(ctx, project, template, resources)
|
||||||
|
|
Loading…
Reference in New Issue