簡體   English   中英

如何在 ECS 中自動擴展服務器?

[英]How to autoscale Servers in ECS?

我最近開始使用 ECS。 我能夠在 ECR 中部署容器映像,並為具有 CPU/內存限制的容器創建任務定義。 我的用例是每個容器都將是一個長時間運行的應用程序(不需要網絡服務器,不需要端口映射)。 容器將根據需求 1 一次生成,並根據需求 1 一次刪除。

我能夠創建一個包含 N 個服務器實例的集群。 但我希望能夠讓服務器實例自動向上/向下擴展。 例如,如果集群中沒有足夠的 CPU/內存,我希望創建一個新實例。

如果有一個沒有運行容器的實例,我希望縮小/刪除該特定實例。 這是為了避免在其中運行任務的服務器實例自動縮減終止。

需要采取哪些步驟才能實現這一目標?

考慮到您已經創建了 ECS 集群,AWS 提供了有關使用 CloudWatch 警報擴展集群實例的說明。

假設您想根據內存預留擴展集群,在較高級別上,您需要執行以下操作:

  1. 為您的 Auto Scaling 組創建啟動配置。 這個
  2. 創建一個 Auto Scaling Group,以便集群的大小可以擴展和縮減。
  3. 如果內存預留超過 70%,則創建 CloudWatch 警報以擴展集群
  4. 如果內存預留低於 30%,則創建 CloudWatch 警報以縮減集群規模

因為它更像是我的專長,所以我編寫了一個示例CloudFormation模板,它應該可以幫助您開始大部分工作:

Parameters:
  MinInstances:
    Type: Number
  MaxInstances:
    Type: Number
  InstanceType:
    Type: String
    AllowedValues:
      - t2.nano
      - t2.micro
      - t2.small
      - t2.medium
      - t2.large
  VpcSubnetIds:
    Type: String

Mappings:
  EcsInstanceAmis:
    us-east-2:
      Ami: ami-1c002379
    us-east-1:
      Ami: ami-9eb4b1e5
    us-west-2:
      Ami: ami-1d668865
    us-west-1:
      Ami: ami-4a2c192a
    eu-west-2:
      Ami: ami-cb1101af
    eu-west-1:
      Ami: ami-8fcc32f6
    eu-central-1:
      Ami: ami-0460cb6b
    ap-northeast-1:
      Ami: ami-b743bed1
    ap-southeast-2:
      Ami: ami-c1a6bda2
    ap-southeast-1:
      Ami: ami-9d1f7efe
    ca-central-1:
      Ami: ami-b677c9d2

Resources:
  Cluster:
    Type: AWS::ECS::Cluster
  Role:
    Type: AWS::IAM::Role
    Properties:
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          -
            Effect: Allow
            Action:
              - sts:AssumeRole
            Principal:
              Service:
                - ec2.amazonaws.com    
  InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: /
      Roles:
        - !Ref Role    
  LaunchConfiguration:
    Type: AWS::AutoScaling::LaunchConfiguration
    Properties:
      ImageId: !FindInMap [EcsInstanceAmis, !Ref "AWS::Region", Ami]
      InstanceType: !Ref InstanceType
      IamInstanceProfile: !Ref InstanceProfile
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash
          echo ECS_CLUSTER=${Cluster} >> /etc/ecs/ecs.config  
  AutoScalingGroup:
    Type: AWS::AutoScaling::AutoScalingGroup
    Properties:
      MinSize: !Ref MinInstances
      MaxSize: !Ref MaxInstances
      LaunchConfigurationName: !Ref LaunchConfiguration
      HealthCheckGracePeriod: 300
      HealthCheckType: EC2
      VPCZoneIdentifier: !Split [",", !Ref VpcSubnetIds]
    ScaleUpPolicy:
      Type: AWS::AutoScaling::ScalingPolicy
      Properties:
        AdjustmentType: ChangeInCapacity
        AutoScalingGroupName: !Ref AutoScalingGroup
        Cooldown: '1'
        ScalingAdjustment: '1'
    MemoryReservationAlarmHigh:
      Type: AWS::CloudWatch::Alarm
      Properties:
        EvaluationPeriods: '2'
        Statistic: Average
        Threshold: '70'
        AlarmDescription: Alarm if Cluster Memory Reservation is to high
        Period: '60'
        AlarmActions:
        - Ref: ScaleUpPolicy
        Namespace: AWS/ECS
        Dimensions:
        - Name: ClusterName
          Value: !Ref Cluster
        ComparisonOperator: GreaterThanThreshold
        MetricName: MemoryReservation
    ScaleDownPolicy:
      Type: AWS::AutoScaling::ScalingPolicy
      Properties:
        AdjustmentType: ChangeInCapacity
        AutoScalingGroupName: !Ref AutoScalingGroup
        Cooldown: '1'
        ScalingAdjustment: '-1'
    MemoryReservationAlarmLow:
      Type: AWS::CloudWatch::Alarm
      Properties:
        EvaluationPeriods: '2'
        Statistic: Average
        Threshold: '30'
        AlarmDescription: Alarm if Cluster Memory Reservation is to Low
        Period: '60'
        AlarmActions:
        - Ref: ScaleDownPolicy
        Namespace: AWS/ECS
        Dimensions:
        - Name: ClusterName
          Value: !Ref Cluster
        ComparisonOperator: LessThanThreshold
        MetricName: MemoryReservation

這將創建一個 ECS 集群、一個啟動配置、一個 AutoScaling 組以及基於 ECS 內存預留的警報。

現在我們可以開始有趣的討論了。

為什么我們不能根據 CPU 利用率內存預留進行縱向擴展?

簡短的回答是你完全可以,你可能會為此付出很多。 EC2 有一個已知屬性,即在您創建實例時,您至少需要支付 1 小時的費用,因為部分實例小時數按完整小時數收費。 為什么這是相關的,假設您有多個警報。 假設您有一堆當前處於空閑狀態的服務,並且您填滿了集群。 CPU 警報會縮小集群規模,或者內存警報會擴大集群規模。 其中之一可能會將集群擴展到不再觸發警報的程度。 冷卻時間結束后,另一個警報將撤消其上一次操作,下一次冷卻后,該操作可能會重做。 因此,實例被創建然后在每隔一個冷卻時間重復銷毀。

想了想,我想到的策略是基於CPU利用率的ECS服務應用自動伸縮,基於集群的內存預留。 因此,如果一項服務正在運行,則會添加一個額外的任務來分擔負載。 這將慢慢填滿集群內存預留容量。 當內存已滿時,集群會向上擴展。 當服務冷卻時,服務將開始關閉任務。 隨着集群上的內存預留下降,集群將縮小。

根據您的任務定義,可能需要試驗 CloudWatch 警報的閾值。 這樣做的原因是,如果你把向上擴展的閾值設置得太高,它可能不會隨着內存的消耗而向上擴展,然后當自動縮放去放置另一個任務時,它會發現任何一個都沒有足夠的可用內存實例在集群中,因此無法放置另一個任務。

作為今年re:Invent會議的一部分,AWS 宣布了適用於 Amazon ECS 的集群自動擴展 配置了 Auto Scaling 的集群現在可以在需要時添加更多容量並刪除不需要的容量。 您可以在文檔中找到更多相關信息。

但是,根據您嘗試運行的內容, AWS Fargate可能是更好的選擇。 Fargate 允許您在不配置和管理底層基礎設施的情況下運行容器; 即,您不必處理任何 EC2 實例。 使用 Fargate,您可以調用 API 來運行您的容器,容器可以運行,然后一旦容器停止運行,就無需清理任何內容。 Fargate 按秒計費(最少 1 分鍾),並根據分配的 CPU 和內存量定價(有關詳細信息,請參見此處)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM