【问题标题】:ECS cluster without Autoscaling没有 Autoscaling 的 ECS 集群
【发布时间】:2020-02-07 13:38:34
【问题描述】:

我需要在不使用自动缩放的情况下创建 ECS 集群

这是因为专用主机 (DH) Tenancy=Host 不受 ASG 支持。 DH 主要是为了节省成本,在某些情况下,即使我们不能使用 ASG,节省也是值得的。

我知道这可以使用 使用 Lambda 备份的自定义资源 或使用 Troposphere 循环实例来完成。 p>

但如果以任何相同或任何其他方法的示例开始,将不胜感激。

下面是我的 appsec.yaml 模板文件:

AWSTemplateFormatVersion: 2010-09-09
Description: Provision Platform Container Service

Parameters:
  PlatformCluster:
    Type: String
  PlatformClusterNotifications:
    Type: String
  PlatformClusterLifecycleNotification:
    Type: String
  Product:
    Type: String
  Environment:
    Type: String
  CDRevisionLoc: 
    Type: String
  ClusterIdentifier:
    Type: Number
  ClusterMinSize:
    Type: Number
  ClusterMaxSize:
    Type: Number
  ClusterSubnets: 
    Type: List<AWS::EC2::Subnet::Id>    
  NodeImageId: 
    Type: AWS::EC2::Image::Id
  NodeOSVolumeSize: 
    Type: Number
    MinValue: 8
  NodeInstanceRole:
    Type: String
  NodeInstanceProfile: 
    Type: String
  NodeKeyName:
    Type: AWS::EC2::KeyPair::KeyName
  NodeInstanceType:
    Type: String
  NodeSecurityGroups:
    Type: List<AWS::EC2::SecurityGroup::Id>
  HanoverSchedule: 
    Type: String 

Mappings:
  InstanceStoreDevices:
    "i3.2xlarge":
      DEVS: "/dev/nvme0n1"
    "i3.4xlarge":
      DEVS: "/dev/nvme0n1 /dev/nvme1n1"
    "i3.8xlarge":
      DEVS: "/dev/nvme0n1 /dev/nvme1n1 /dev/nvme2n1 /dev/nvme3n1"
    "m5d.2xlarge":
      DEVS: "/dev/nvme1n1"
    "m5d.4xlarge":
      DEVS: "/dev/nvme1n1 /dev/nvme2n1"
    "c5d.2xlarge":
      DEVS: "/dev/nvme1n1"
    "c5d.4xlarge":
      DEVS: "/dev/nvme1n1"
    "c5d.9xlarge":
      DEVS: "/dev/nvme1n1"

Resources:  
  PlatformClusterLaunchConfiguration:
    Type: AWS::AutoScaling::LaunchConfiguration
    Metadata:
      AWS::CloudFormation::Init:
        configSets:
          all: [install_cfn, update_ecs_agent, faro_self_install]
        install_cfn:
          files:
            /etc/cfn/cfn-hup.conf:
              content: !Sub |
                [main]
                stack=${AWS::StackId}
                region=${AWS::Region}
                interval=5
              mode: '000400'
              owner: root
              group: root
            /etc/cfn/hooks.d/cfn-auto-reloader.conf:
              content: !Sub |
                [cfn-auto-reloader-hook]
                runas=root
                triggers=post.update
                path=Resources.PlatformClusterLaunchConfiguration.Metadata.AWS::CloudFormation::Init
                action=/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource PlatformClusterLaunchConfiguration --configsets all --region ${AWS::Region}
              mode: '000400'
              owner: root
              group: root
          services:
            sysvinit:
              cfn-hup:
                enabled: True
                ensureRunning: True
                files: [/etc/cfn/cfn-hup.conf, /etc/cfn/hooks.d/cfn-auto-reloader.conf]
        update_ecs_agent:
          commands:
            update_agent:
              command: yum update -y ecs-init
        faro_self_install:
          packages:
            yum:
              ruby: []
              aws-cli: []
              python27: []
              python27-boto3: []
              epel-release: [] 
              unzip: [] 
              ack: []
              wget: []
              jq: []
          commands:
            self_install:
              command: !Sub |
                #!/bin/bash
                yum -y --security update

                mkdir -p /etc/salt
                cd $(mktemp -d)
                REVNAME=$(basename ${CDRevisionLoc})
                aws --region ${AWS::Region} s3 cp ${CDRevisionLoc} $REVNAME.zip
                unzip -o $REVNAME.zip -d $REVNAME
                chmod +x $REVNAME/install.sh
                ./$REVNAME/install.sh
    Properties:
      BlockDeviceMappings:
        - DeviceName: /dev/xvda
          Ebs:
            VolumeSize: !Ref NodeOSVolumeSize
            VolumeType: gp2
            DeleteOnTermination: True
        - DeviceName: /dev/xvdcz
          VirtualName: ephemeral0
      EbsOptimized: True
      IamInstanceProfile: !Ref NodeInstanceProfile
      ImageId: !Ref NodeImageId
      InstanceMonitoring: True
      InstanceType: !Ref NodeInstanceType
      KeyName: !Ref NodeKeyName
      SecurityGroups: !Ref NodeSecurityGroups
      UserData: 
        Fn::Base64: 
          Fn::Sub: 
            - |
              Content-Type: multipart/mixed; boundary="**"
              MIME-Version: 1.0

              --**
              MIME-Version: 1.0
              Content-Type: text/cloud-boothook; charset="us-ascii"

              cloud-init-per once yum_update yum update -y
              cloud-init-per once install_aws_cfn_bootstrap yum -y install aws-cfn-bootstrap

              cloud-init-per instance custom_docker_options cat <<'EOF' > /etc/sysconfig/docker
              DAEMON_MAXFILES=1048576
              DAEMON_PIDFILE_TIMEOUT=10
              OPTIONS="--default-ulimit nofile=1024:4096"
              EOF

              cloud-init-per instance custom_docker_storage_options cat <<'EOF' > /etc/sysconfig/docker-storage-setup
              DEVS="${InstanceStoreDevices}"
              STORAGE_DRIVER="devicemapper"
              VG=docker
              DATA_SIZE=99%FREE
              AUTO_EXTEND_POOL=yes
              LV_ERROR_WHEN_FULL=yes
              EXTRA_DOCKER_STORAGE_OPTIONS="--storage-opt dm.fs=ext4 --storage-opt dm.use_deferred_deletion=true --storage-opt dm.basesize=20G"
              EOF

              cloud-init-per instance custom_ecs_options cat <<'EOF' > /etc/ecs/ecs.config
              ECS_CLUSTER=${PlatformCluster}
              ECS_ENABLE_TASK_IAM_ROLE=true
              ECS_ENABLE_TASK_IAM_ROLE_NETWORK_HOST=true 
              ECS_DISABLE_PRIVILEGED=true 
              ECS_AVAILABLE_LOGGING_DRIVERS=["json-file", "awslogs", "splunk"] 
              ECS_SELINUX_CAPABLE=false 
              ECS_APPARMOR_CAPABLE=false 
              ECS_ENGINE_TASK_CLEANUP_WAIT_DURATION=10m 
              ECS_CONTAINER_STOP_TIMEOUT=1m 
              ECS_DISABLE_IMAGE_CLEANUP=false 
              ECS_IMAGE_CLEANUP_INTERVAL=30m 
              ECS_IMAGE_MINIMUM_CLEANUP_AGE=30m 
              ECS_NUM_IMAGES_DELETE_PER_CYCLE=50 
              ECS_UPDATES_ENABLED=false 
              ECS_DISABLE_METRICS=false 
              ECS_ENABLE_CONTAINER_METADATA=true 
              ECS_AWSVPC_ADDITIONAL_LOCAL_ROUTES=["169.254.120.120/32"] 
              EOF

              --**
              MIME-Version: 1.0
              Content-Type: text/x-shellscript; charset="us-ascii"

              #!/bin/bash
              set -e

              # set sysctl before doing anything
              echo "net.ipv4.conf.all.forwarding = 1" >> /etc/sysctl.d/99-local.conf
              sysctl net.ipv4.conf.all.forwarding=1

              /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource PlatformClusterLaunchConfiguration --configsets all --region ${AWS::Region}
              /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource PlatformClusterASG --region ${AWS::Region}
            - PlatformCluster: !Ref PlatformCluster
              InstanceStoreDevices: !FindInMap [InstanceStoreDevices, !Ref NodeInstanceType, "DEVS"]


  PlatformClusterASG:
    Type: "AWS::AutoScaling::AutoScalingGroup"
    DependsOn:
      - PlatformClusterLaunchConfiguration
    Properties:
      Cooldown: 900
      HealthCheckGracePeriod: 600
      HealthCheckType: EC2
      LaunchConfigurationName: !Ref PlatformClusterLaunchConfiguration
      VPCZoneIdentifier: !Ref ClusterSubnets
      MaxSize: !Ref ClusterMaxSize
      MinSize: !Ref ClusterMinSize
      DesiredCapacity: !Ref ClusterMinSize
      MetricsCollection:
        - 
          Granularity: 1Minute
      NotificationConfigurations:
        -
          NotificationTypes:
            - autoscaling:EC2_INSTANCE_LAUNCH_ERROR
            - autoscaling:EC2_INSTANCE_TERMINATE_ERROR
          TopicARN: !Ref PlatformClusterNotifications
      TerminationPolicies:
        - NewestInstance
      Tags:
        - Key: Name
          Value: !Sub ${Product}${Environment}-pcs${ClusterIdentifier}
          PropagateAtLaunch: true
        - Key: Product
          Value: !Ref Product
          PropagateAtLaunch: true
        - Key: Environment
          Value: !Ref Environment
          PropagateAtLaunch: true
        - Key: Service
          Value: !Sub gtn:${Environment}:pcs
          PropagateAtLaunch: true
        - Key: Schedule
          Value: !Ref HanoverSchedule
          PropagateAtLaunch: true
    CreationPolicy:
      ResourceSignal:
        Timeout: PT20M
    UpdatePolicy:
      AutoScalingRollingUpdate:
        WaitOnResourceSignals: True
        PauseTime: PT20M
      AutoScalingScheduledAction:
        IgnoreUnmodifiedGroupSizeProperties: True

  PlatformClusterTeardownLifecycleHook:
    Type: "AWS::AutoScaling::LifecycleHook"
    DependsOn:
      - PlatformClusterASG
    Properties:
      AutoScalingGroupName: !Ref PlatformClusterASG
      DefaultResult: ABANDON
      HeartbeatTimeout: 900
      LifecycleTransition: autoscaling:EC2_INSTANCE_TERMINATING
      NotificationTargetARN: !Ref PlatformClusterLifecycleNotification
      RoleARN: !Ref NodeInstanceRole

Outputs:
  ECSAutoScalingGroup:
    Value: !Ref PlatformClusterASG

【问题讨论】:

  • 我不是 100% 确定 DH,但是您可以通过将 ECS_CLUSTER=YOUR_CLUSTER_NAME 放入 /etc/ecs/ecs.config 将您的实例固定到 ECS 集群(如果您在实例上安装了 ecs-agent)(您可以在user data 脚本中执行)
  • “DH 主要是为了节省成本” 与默认的“共享”租赁相比,专用主机没有任何方案可以节省成本。
  • 我正在考虑使用 ansible 循环创建实例。但即使我这样做了,我如何将它包含到我的 appsec.yml 中,而不必将其保存到 S3 中并产生额外费用? @Yupik

标签: amazon-ec2 aws-lambda amazon-cloudformation amazon-ecs autoscaling


【解决方案1】:

ASG 只是一种使用指定启动配置启动相同实例的便捷方式。

如果您获取启动配置并使用它来启动实例,那么您实际上就切断了 ASG。

在一天结束时,您希望设置您的用户数据以将您的容器实例注册到您的集群。

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_container_instance.html

有了它,您可以创建一个 launch template 并使用它来使用您的专用主机启动更多实例。然后,您可以使用 Cloudwatch 和 Lambda 构建穷人的 ASG。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-24
    • 2018-05-07
    • 1970-01-01
    • 2022-11-17
    • 1970-01-01
    • 2020-12-19
    • 2023-03-30
    相关资源
    最近更新 更多