Amazon ECS не масштабирует экземпляры

Может ли кто-нибудь пролить свет на то, почему мой стек ECS не масштабирует новые экземпляры EC2?

Я настроил свой стек ECS с помощью Cloudformation. Начальная конфигурация работает нормально. Как только я запускаю свой стек, запускается процесс, который поддерживает нагрузку на процессор> 90%, так что сигнал тревоги горизонтального масштабирования может сработать в целях тестирования.

Я установил сигнал масштабирования для запуска политики масштабирования, когда ЦП> 15%, и масштаб в политике будет срабатывать, когда ЦП < 4%.

Сообщения журнала затем сообщают следующее:

Сообщение: служба ECSService-12BBO1EE3SRUF не смогла разместить задачу, поскольку ни один контейнерный экземпляр не выполнил все его требования. У ближайшего соответствующего экземпляра контейнера 149e8eea-a8bc-433f-abbb-9a49c3a3c5b5 недостаточно памяти. Для получения дополнительной информации см. Раздел "Устранение неполадок". Сообщение: Успешно установите желаемое количество на 2. Ожидание изменения, которое будет выполнено ecs. Причина: отслеживать состояние ЦП, превышающее 5% в состоянии тревоги. Сработала политика ALARM. ServiceScaleOutPolicy 155194fc-ee07-46ff-a822-018bd704602b

Похоже, что ECS пытается разместить больше задач в одном экземпляре, вместо того, чтобы уменьшать количество экземпляров и помещать новую задачу в новый экземпляр. Как заставить ECS масштабироваться до нового экземпляра и помещать новое задание в новый экземпляр?

Моя конфигурация масштабирования облачной информации выглядит так:

ECSAutoScalingGroup:
    Type: AWS::AutoScaling::AutoScalingGroup
    DependsOn: ECSALB
    Properties:
      VPCZoneIdentifier: !Ref 'SubnetId'
      LaunchConfigurationName: !Ref 'ContainerInstances'
      MinSize: !Ref 'DesiredCapacity'
      MaxSize: !Ref 'MaxSize'
      DesiredCapacity: !Ref 'DesiredCapacity'
      HealthCheckGracePeriod: 320
    CreationPolicy:
      ResourceSignal:
        Timeout: PT15M
    UpdatePolicy:
      AutoScalingReplacingUpdate:
        WillReplace: 'true'
      AutoScalingRollingUpdate:
        MinInstancesInService: '1'
        MaxBatchSize: '1'
        PauseTime: PT15M
        WaitOnResourceSignals: 'true'

ServiceScalingTarget:
    Type: AWS::ApplicationAutoScaling::ScalableTarget
    DependsOn: ECSService
    Properties:
      MaxCapacity: 3
      MinCapacity: 1
      ResourceId: !Join ['', [service/, !Ref 'ECSCluster', /, !GetAtt [ECSService, Name]]]
      RoleARN: !GetAtt [AutoscalingRole, Arn]
      ScalableDimension: ecs:service:DesiredCount
      ServiceNamespace: ecs

ServiceScaleOutPolicy:
    Type : "AWS::ApplicationAutoScaling::ScalingPolicy"
    Properties:
      PolicyName: ServiceScaleOutPolicy
      PolicyType: StepScaling
      ScalingTargetId: !Ref 'ServiceScalingTarget'
      StepScalingPolicyConfiguration:
          AdjustmentType: ChangeInCapacity
          Cooldown: 60
          MetricAggregationType: Average
          StepAdjustments:
          - MetricIntervalLowerBound: 0
            ScalingAdjustment: 1

  ServiceScaleInPolicy:
    Type : "AWS::ApplicationAutoScaling::ScalingPolicy"
    Properties:
      PolicyName: ServiceScaleInPolicy
      PolicyType: StepScaling
      ScalingTargetId: !Ref 'ServiceScalingTarget'
      StepScalingPolicyConfiguration:
          AdjustmentType: ChangeInCapacity
          Cooldown: 60
          MetricAggregationType: Average
          StepAdjustments:
          - MetricIntervalUpperBound: 0
            ScalingAdjustment: -1

  CPUScaleOutAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName: CPU utilization greater than 15%
      AlarmDescription: Alarm if cpu utilization greater than 15% of reserved cpu
      Namespace: AWS/ECS
      MetricName: CPUUtilization
      Dimensions:
      - Name: ClusterName
        Value: !Ref ECSCluster
      - Name: ServiceName
        Value: !GetAtt ECSService.Name
      Statistic: Maximum
      Period: '60'
      EvaluationPeriods: '1'
      Threshold: '15'
      ComparisonOperator: GreaterThanThreshold
      AlarmActions:
      - !Ref ServiceScaleOutPolicy

  CPUScaleInAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName: CPU utilization less than 4%
      AlarmDescription: Alarm if cpu utilization greater than 4% of reserved cpu
      Namespace: AWS/ECS
      MetricName: CPUUtilization
      Dimensions:
      - Name: ClusterName
        Value: !Ref ECSCluster
      - Name: ServiceName
        Value: !GetAtt ECSService.Name
      Statistic: Maximum
      Period: '60'
      EvaluationPeriods: '4'
      Threshold: '4'
      ComparisonOperator: LessThanThreshold
      AlarmActions:
        - !Ref ServiceScaleInPolicy
AutoscalingRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Effect: Allow
          Principal:
            Service: [application-autoscaling.amazonaws.com]
          Action: ['sts:AssumeRole']
      Path: /
      Policies:
      - PolicyName: service-autoscaling
        PolicyDocument:
          Statement:
          - Effect: Allow
            Action: ['application-autoscaling:*', 'cloudwatch:DescribeAlarms', 'cloudwatch:PutMetricAlarm',
              'ecs:DescribeServices', 'ecs:UpdateService']
            Resource: '*'

TaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      Family: !Join ['', [!Ref 'AWS::StackName', -frontend-task]]
      ContainerDefinitions:
        - Name: nginx-container
          Image: nginx:latest
          Cpu: '64'
          Memory: '150'
          Essential: 'true'
          Links:
            - "kestrel-container"
          MountPoints: 
            - SourceVolume: "volume-nginx-conf"
              ContainerPath: "/etc/nginx/conf.d/default.conf"
          LogConfiguration:
            LogDriver: awslogs
            Options:
              awslogs-group: !Ref 'CloudwatchLogsGroup'
              awslogs-region: !Ref 'AWS::Region'
              awslogs-stream-prefix: task-nginx-container
          PortMappings:
          - ContainerPort: 80
          - ContainerPort: 443

        - Name: kestrel-container
          Image: some-image
          Cpu: '940'
          Memory: '512'
          Essential: 'false'
          LogConfiguration:
            LogDriver: awslogs
            Options:
              awslogs-group: !Ref 'CloudwatchLogsGroup'
              awslogs-region: !Ref 'AWS::Region'
              awslogs-stream-prefix: task-kestrel-container
          PortMappings:
          - ContainerPort: 5443

      Volumes:
          - Host: 
              SourcePath: "/docker-volumes/nginx/nginx.conf"
            Name: "volume-nginx-conf"

1 ответ

Похоже, вы неправильно поняли автоматическое масштабирование службы и автоматическое масштабирование кластера. То, что вы сделали выше, - это автоматическое масштабирование службы на основе использования ЦП службы в ее собственном контейнере.

Что вы хотите сделать, так это автоматически масштабировать кластер ECS, добавляя новый экземпляр EC2, если общее использование памяти кластером достигло одного порога.

Ниже приведен фрагмент настройки автоматического масштабирования на уровне кластера, если объем памяти достиг 80%. Я не могу поделиться всей облачной информацией.

ECSInstanceAutoScalingGroup:
    Type: AWS::AutoScaling::AutoScalingGroup
    Properties:
      VPCZoneIdentifier:
      - 'Fn::ImportValue':
          !Sub '${VPCStackName}-SubnetPrivateA'
      - 'Fn::ImportValue':
          !Sub '${VPCStackName}-SubnetPrivateB'
      - 'Fn::ImportValue':
          !Sub '${VPCStackName}-SubnetPrivateC'
      LaunchConfigurationName: !Ref 'ECSInstanceLaunchConfiguration'
      MinSize: !Ref 'ECSInstanceCount'
      MaxSize: 6
      DesiredCapacity: !Ref 'ECSInstanceCount'
      MetricsCollection:
        - Granularity: 1Minute

ECSInstanceLaunchConfiguration:
  Type: AWS::AutoScaling::LaunchConfiguration
  Metadata:
    AWS::CloudFormation::Init:
      configSets:
        ConfigCluster:
        - Install
      Install:
        files:
          /home/ec2-user/.aws/config:
            content: !Sub |
              [default]
              region = ${AWS::Region}
            mode: '000755'
            owner: ec2-user
            group: root
          /etc/ecs/ecs.config:
            content: !Sub |
              ECS_CLUSTER=${ECSCluster}
              ECS_ENABLE_CONTAINER_METADATA=true
              ECS_ENGINE_TASK_CLEANUP_WAIT_DURATION=20m
              ECS_DISABLE_IMAGE_CLEANUP=false
              ECS_IMAGE_CLEANUP_INTERVAL=10m
              ECS_IMAGE_MINIMUM_CLEANUP_AGE=20m
            mode: '000755'
            owner: root
            group: root
  Properties:
    ImageId: !Ref ECSAMI
    InstanceType: !Ref 'ECSInstanceType'
    AssociatePublicIpAddress: 'false'
    IamInstanceProfile: !Ref ECSClusterRoleInstance
    SecurityGroups:
    - !Ref 'ECSInstanceSecurityGroup'

ECSScalingPolicy:
  Type: 'AWS::AutoScaling::ScalingPolicy'
  Properties:
    AutoScalingGroupName: !Ref ECSInstanceAutoScalingGroup
    PolicyType: TargetTrackingScaling
    TargetTrackingConfiguration:
      CustomizedMetricSpecification:
        MetricName: MemoryReservation
        Namespace: "AWS/ECS"
        Dimensions:
          - Name: ClusterName
            Value: !Sub "ecs-${EnvName}-${EnvNumber}"
        Statistic: Maximum
        Unit: Percent
      TargetValue: 80
      DisableScaleIn: false
Другие вопросы по тегам