EC2 Auto Scalingグループにオンデマンド/スポットインスタンスを混ぜる

EC2 Auto Scalingグループにオンデマンド/スポットインスタンスを混ぜる

以下のテキストでAWS費用を下げる手法が紹介されています。

AWSコスト最適化ガイドブック

紹介されている手法の1つに、スポットインスタンスがあります。

スポットインスタンスは、単体のAmazonEC2インスタンスとしても起動できますが、ほとんどのユースケースではAmazonEC2AutoScalingグループで管理するのがおすすめです。AmazonEC2AutoScalingサービスは、負荷に応じてインスタンスの台数を自動的に増減する仕組みですが、その手前に重要な機能があります。それは、稼働する台数の自動維持です。

AWSコスト最適化ガイドブック

そしてEC2 Auto Scalingグループにおいて、オンデマンドインスタンスとスポットインスタンスを混在させる構成も可能です。

1 つの Auto Scaling グループ内で、オンデマンドインスタンスとスポットインスタンスのフリートを起動してオートスケールできます。

複数のインスタンスタイプと購入オプションを使用する Auto Scaling グループ

今回はオンデマンド・スポットインスタンスで構成されたEC2 Auto Scalingグループを作成します。

構築する環境

Diagram of mix on-demand/spot instances in EC2 Auto Scaling Group.

プライベートサブネット内にEC2 Auto Scalingグループを作成します。
グループ内に作成するインスタンスのOSは、最新のAmazon Linux 2とします。

グループにインスタンスサイズを2に固定します。
つまり希望数/最小数/最大数を全て2に設定します。
そしてスケーリングポリシーは設定しません。

2つのインスタンスの内、一方はオンデマンドインスタンスとします。
そしてもう一方をスポットインスタンスとします。

EC2 Auto Scalingグループの全面にALBを配置します。

CloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。

https://github.com/awstut-an-r/awstut-fa/tree/main/139

テンプレートファイルのポイント解説

本ページは、オンデマンド・スポットインスタンスが混在したEC2 Auto Scalingグループの作成方法を取り上げます。

EC2 Auto Scalingに関する基本的な事項については、以下のページをご確認ください。

あわせて読みたい
EC2 Auto Scaling入門 – スケーリングポリシーなし 【EC2 Auto Scaling入門 - スケーリングポリシーなし】 EC2 Auto Scalingを利用することによって、任意の数のEC2インスタンスを起動し、アプリケーションの可用性を高め...

起動テンプレート

Resources:
  LaunchTemplate:
    Type: AWS::EC2::LaunchTemplate
    Properties:
      LaunchTemplateData:
        IamInstanceProfile:
          Arn: !GetAtt InstanceProfile.Arn
        ImageId: !Ref ImageId
        InstanceType: !Ref InstanceType1
        SecurityGroupIds:
          - !Ref InstanceSecurityGroup
        UserData: !Base64 |
          #!/bin/bash -xe
          yum update -y
          yum install -y httpd
          systemctl start httpd
          systemctl enable httpd
          ec2-metadata -i > /var/www/html/index.html
      LaunchTemplateName: !Sub "${Prefix}-LaunchTemplate"
Code language: YAML (yaml)

特別な設定は不要です。

インスタンスタイプにt3a.nanoを指定します。

ユーザデータで初期化処理を定義します。
処理内容ですが、Apacheをインストールして、index.htmlを用意します。

Auto Scalingグループ

Resources:
  AutoScalingGroup:
    Type: AWS::AutoScaling::AutoScalingGroup
    Properties:
      AutoScalingGroupName: !Sub "${Prefix}-AutoScalingGroup"
      DesiredCapacity: !Ref DesiredCapacity
      MaxSize: !Ref MaxSize
      MinSize: !Ref MinSize
      MixedInstancesPolicy:
        InstancesDistribution:
          OnDemandAllocationStrategy: prioritized
          OnDemandBaseCapacity: 1
          OnDemandPercentageAboveBaseCapacity: 0
          SpotAllocationStrategy: price-capacity-optimized
        LaunchTemplate:
          LaunchTemplateSpecification:
            LaunchTemplateId: !Ref LaunchTemplate
            Version: !GetAtt LaunchTemplate.LatestVersionNumber
          Overrides:
            - InstanceType: !Ref InstanceType1
            - InstanceType: !Ref InstanceType2
            - InstanceType: !Ref InstanceType3
      VPCZoneIdentifier:
        - !Ref PrivateSubnet1
        - !Ref PrivateSubnet2
      TargetGroupARNs:
        - !Ref ALBTargetGroup
Code language: YAML (yaml)

オンデマンドインスタンスとスポットインスタンスを混ぜた構成にする上で、ポイントとなる設定はMixedInstancesPolicyプロパティです。

LaunchTemplateプロパティに、先ほど確認した起動テンプレートを設定します。

今回はインスタンスタイプのオーバーライドします。

オーバーライドは、起動テンプレートのプロパティに加える変更です。Amazon EC2 Auto Scaling では、インスタンスタイプ プロパティへのオーバーライドがサポートされています。これにより、複数のインスタンスタイプを指定できます。

上書きを設定する

Overridesプロパティに以下の3種類のインスタンスタイプを指定します。

  1. t3a.nano
  2. t3.nano
  3. t2.nano

オンデマンドインスタンスに関しては、以下の3つのプロパティを設定します。

1つ目はOnDemandAllocationStrategyプロパティです。
本プロパティに「prioritized」を指定します。
この意味は以下の通りに説明されています。

オンデマンドキャパシティを満たすとき、Amazon EC2 Auto Scaling は、起動テンプレートのオーバーライドのリスト内のインスタンスタイプの順序に基づき、最初に使用するインスタンスタイプを決定します。

配分戦略

今回ですと、1番優先順位が高いインスタンスタイプはt3a.nanoです。
ですからオンデマンドインスタンスのタイプは、これが選ばれることになります。

2つ目と3つ目はOnDemandBaseCapacity・OnDemandPercentageAboveBaseCapacityプロパティです。
これらはオンデマンドインスタンスの数を制御するためのパラメータです。
以下のページに詳しいです。

https://docs.aws.amazon.com/ja_jp/autoscaling/ec2/userguide/ec2-auto-scaling-mixed-instances-groups.html#instances-distribution

今回の設定方法ですと、オンデマンドインスタンスは常に1台実行されることになります。

SpotAllocationStrategyプロパティは、スポットインスタンスのインスタンスタイプの決定に関するパラメータです。
今回は本プロパティに「price-capacity-optimized」を指定します。
この意味は以下の通りに説明されています。

価格とキャパシティで最適化された配分戦略では、価格とキャパシティの両方を考慮して、中断される可能性が最も低く、価格ができるだけ低いスポットインスタンスプールを選択します。

配分戦略

今回ですと、上記の3つのインスタンスタイプの中から、価格およびキャパシティの空き状況を勘案して決まります。

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成し、スタック内のリソースを確認する

CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

あわせて読みたい
CloudFormationのネストされたスタックで環境を構築する 【CloudFormationのネストされたスタックで環境を構築する方法】 CloudFormationにおけるネストされたスタックを検証します。 CloudFormationでは、スタックをネストす...

各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。

  • ALBのDNS名:http://fa-139-ALB-981952103.ap-northeast-1.elb.amazonaws.com
  • ALBターゲットグループ:fa-139-ALBTargetGroup
  • 起動テンプレート:fa-139-LaunchTemplate
  • EC2 Auto Scalingグループ:fa-139-AutoScalingGroup

作成されたリソースをAWS Management Consoleから確認します。

Auto Scalingグループを確認します。

Detail of Auto Scaling 1.

インスタンスタイプに関する設定に注目します。
起動テンプレートでは、t3a.nanoが指定されています。
対してインスタンスタイプ要件を見ると、t3a.nanoを含む3つのタイプが登録されていることがわかります。
つまりオンデマンド・スポットインスタンスともに、需要状況や価格に応じて、この3つからタイプが決定するということです。

購入オプションを見ると、CloudFormationで指定した通りに設定されていることがわかります。
オンデマンドインスタンスは1台だけ作成し、残りはスポットインスタンスとなります。
今回の構成では、Auto Scalingグループの希望数/最小数/最大数を全て2に設定しています。
ですからオンデマンド・スポットインスタンスは1台ずつ作成されることになります。

動作確認

Auto Scalingグループ内に作成されたEC2インスタンスを確認します。

まずはグループのアクティビティを確認します。

Detail of Auto Scaling 2.

グループ内に2つのインスタンスが生成されたことがわかります。

作成されたインスタンスを確認します。

Detail of AutoScaling 3

インスタンスタイプに注目します。
一方はt3a.nano、もう一方はt3.nanoです。
本来は起動テンプレートに従って、t3a.nanoが選ばれるはずです。
しかしEC2の需要状況や価格に応じて、インスタンスタイプ要件に挙げられた別のインスタンスタイプが選ばれたということです。

t3a.nanoの方のインスタンス(i-0a1472ccedc0518af)の詳細を確認します。

Detail of EC2 1.

Lifecycleを見ると、「normal」とあります。
つまりこのインスタンスはオンデマンドインスタンスということです。
そしてオンデマンドインスタンスのインスタンスタイプは、起動テンプレート通りのt3a.nanoが選ばれたということになります。

続いてt3.nanoの方のインスタンス(i-071d637777a0e0823)の詳細を確認します。

Detail of EC2 2.

Lifecycleを見ると、「spot」とあります。
つまりこのインスタンスはスポットインスタンスということです。
このことから、スポットインスタンスのインスタンスタイプは、起動テンプレートで指定したものではなく、インスタンス要件で挙げた別のタイプが選ばれたということです。

一応、このAuto ScalingグループをアタッチしているALBにアクセスしてみます。

$ curl http://fa-139-ALB-981952103.ap-northeast-1.elb.amazonaws.com
instance-id: i-0a1472ccedc0518af

$ curl http://fa-139-ALB-981952103.ap-northeast-1.elb.amazonaws.com
instance-id: i-071d637777a0e0823
Code language: Bash (bash)

ALBを通じて、2台のインスタンスにアクセスできています。
つまり1つのAuto Scalingグループに、オンデマンドインスタンスとスポットインスタンスを混在させる構成にしても、正常に動作します。

まとめ

オンデマンド・スポットインスタンスで構成されたEC2 Auto Scalingグループを作成しました。