EC2 Auto Scalingグループにオンデマンド/スポットインスタンスを混ぜる
以下のテキストでAWS費用を下げる手法が紹介されています。
紹介されている手法の1つに、スポットインスタンスがあります。
スポットインスタンスは、単体のAmazonEC2インスタンスとしても起動できますが、ほとんどのユースケースではAmazonEC2AutoScalingグループで管理するのがおすすめです。AmazonEC2AutoScalingサービスは、負荷に応じてインスタンスの台数を自動的に増減する仕組みですが、その手前に重要な機能があります。それは、稼働する台数の自動維持です。
AWSコスト最適化ガイドブック
そしてEC2 Auto Scalingグループにおいて、オンデマンドインスタンスとスポットインスタンスを混在させる構成も可能です。
1 つの Auto Scaling グループ内で、オンデマンドインスタンスとスポットインスタンスのフリートを起動してオートスケールできます。
複数のインスタンスタイプと購入オプションを使用する Auto Scaling グループ
今回はオンデマンド・スポットインスタンスで構成されたEC2 Auto Scalingグループを作成します。
構築する環境
プライベートサブネット内に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に関する基本的な事項については、以下のページをご確認ください。
起動テンプレート
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種類のインスタンスタイプを指定します。
- t3a.nano
- t3.nano
- t2.nano
オンデマンドインスタンスに関しては、以下の3つのプロパティを設定します。
1つ目はOnDemandAllocationStrategyプロパティです。
本プロパティに「prioritized」を指定します。
この意味は以下の通りに説明されています。
オンデマンドキャパシティを満たすとき、Amazon EC2 Auto Scaling は、起動テンプレートのオーバーライドのリスト内のインスタンスタイプの順序に基づき、最初に使用するインスタンスタイプを決定します。
配分戦略
今回ですと、1番優先順位が高いインスタンスタイプはt3a.nanoです。
ですからオンデマンドインスタンスのタイプは、これが選ばれることになります。
2つ目と3つ目はOnDemandBaseCapacity・OnDemandPercentageAboveBaseCapacityプロパティです。
これらはオンデマンドインスタンスの数を制御するためのパラメータです。
以下のページに詳しいです。
今回の設定方法ですと、オンデマンドインスタンスは常に1台実行されることになります。
SpotAllocationStrategyプロパティは、スポットインスタンスのインスタンスタイプの決定に関するパラメータです。
今回は本プロパティに「price-capacity-optimized」を指定します。
この意味は以下の通りに説明されています。
価格とキャパシティで最適化された配分戦略では、価格とキャパシティの両方を考慮して、中断される可能性が最も低く、価格ができるだけ低いスポットインスタンスプールを選択します。
配分戦略
今回ですと、上記の3つのインスタンスタイプの中から、価格およびキャパシティの空き状況を勘案して決まります。
環境構築
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グループを確認します。
インスタンスタイプに関する設定に注目します。
起動テンプレートでは、t3a.nanoが指定されています。
対してインスタンスタイプ要件を見ると、t3a.nanoを含む3つのタイプが登録されていることがわかります。
つまりオンデマンド・スポットインスタンスともに、需要状況や価格に応じて、この3つからタイプが決定するということです。
購入オプションを見ると、CloudFormationで指定した通りに設定されていることがわかります。
オンデマンドインスタンスは1台だけ作成し、残りはスポットインスタンスとなります。
今回の構成では、Auto Scalingグループの希望数/最小数/最大数を全て2に設定しています。
ですからオンデマンド・スポットインスタンスは1台ずつ作成されることになります。
動作確認
Auto Scalingグループ内に作成されたEC2インスタンスを確認します。
まずはグループのアクティビティを確認します。
グループ内に2つのインスタンスが生成されたことがわかります。
作成されたインスタンスを確認します。
インスタンスタイプに注目します。
一方はt3a.nano、もう一方はt3.nanoです。
本来は起動テンプレートに従って、t3a.nanoが選ばれるはずです。
しかしEC2の需要状況や価格に応じて、インスタンスタイプ要件に挙げられた別のインスタンスタイプが選ばれたということです。
t3a.nanoの方のインスタンス(i-0a1472ccedc0518af)の詳細を確認します。
Lifecycleを見ると、「normal」とあります。
つまりこのインスタンスはオンデマンドインスタンスということです。
そしてオンデマンドインスタンスのインスタンスタイプは、起動テンプレート通りのt3a.nanoが選ばれたということになります。
続いてt3.nanoの方のインスタンス(i-071d637777a0e0823)の詳細を確認します。
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グループを作成しました。