はじめに
この記事はAWS Hands on for BeginnersのEC2 Auto Scaling基礎編を参考に記事にしました。
1.AWS Cloudformation を利用してリソースを構築
ハンズオンに必要なリソースをCloudformationによって構築する。
CloudformationはAWS環境のコードによる管理を実現することができ、テンプレートで定義した環境を作成・変更・削除できる。
これを利用することで下記の項目を手作業でやる手間なく一括で構築できる。
・Amazon VPC
・サブネット
・インターネットゲートウェイ
・ルートテーブル
・セキュリティーグループ
・Application Load Balancer,ターゲットグループ
事前準備で出来上がるリソース↓
マネジメントコーンソール からAWSCloudformation→スタックの作成を選択する。
テンプレートの指定→テンプレートファイルのアップロードを選択
以下に設定ファイルに記述するコードを示す。
{
"AWSTemplateFormatVersion" : "2022-07-14",
"Description" : "This template is for 'AWS Hands-on for Beginners Amazon EC2 Auto Scaling'.",
"Resources" : {
"VPC" : {
"Type" : "AWS::EC2::VPC",
"Properties" : {
"CidrBlock" : "10.0.0.0/16",
"EnableDnsSupport" : true,
"EnableDnsHostnames" : true,
"Tags" : [ {"Key" : "Name", "Value" : "h4b-vpc" } ]
}
},
"PublicSubnet1" : {
"Type" : "AWS::EC2::Subnet",
"Properties" : {
"VpcId" : { "Ref" : "VPC" },
"CidrBlock" : "10.0.0.0/24",
"AvailabilityZone" : { "Fn::Select" : [ "0", { "Fn::GetAZs" : { "Ref" : "AWS::Region" }}]},
"MapPublicIpOnLaunch" : true,
"Tags" : [ {"Key" : "Name", "Value" : "h4b-subnet1" } ]
}
},
"PublicSubnet2" : {
"Type" : "AWS::EC2::Subnet",
"Properties" : {
"VpcId" : { "Ref" : "VPC" },
"CidrBlock" : "10.0.1.0/24",
"AvailabilityZone" : { "Fn::Select" : [ "1", { "Fn::GetAZs" : { "Ref" : "AWS::Region" }}]},
"MapPublicIpOnLaunch" : true,
"Tags" : [ {"Key" : "Name", "Value" : "h4b-subnet2" } ]
}
},
"InternetGateway" : {
"Type" : "AWS::EC2::InternetGateway",
"Properties" : {
"Tags" : [ {"Key" : "Name", "Value" : "h4b-igw" } ]
}
},
"AttachGateway" : {
"Type" : "AWS::EC2::VPCGatewayAttachment",
"Properties" : {
"VpcId" : { "Ref" : "VPC" },
"InternetGatewayId" : { "Ref" : "InternetGateway" }
}
},
"RouteTable" : {
"Type" : "AWS::EC2::RouteTable",
"Properties" : {
"VpcId" : {"Ref" : "VPC"},
"Tags" : [ {"Key" : "Name", "Value" : "h4b-route-table" } ]
}
},
"Route" : {
"Type" : "AWS::EC2::Route",
"DependsOn" : "AttachGateway",
"Properties" : {
"RouteTableId" : { "Ref" : "RouteTable" },
"DestinationCidrBlock" : "0.0.0.0/0",
"GatewayId" : { "Ref" : "InternetGateway" }
}
},
"SubnetRouteTableAssociation1" : {
"Type" : "AWS::EC2::SubnetRouteTableAssociation",
"Properties" : {
"SubnetId" : { "Ref" : "PublicSubnet1" },
"RouteTableId" : { "Ref" : "RouteTable" }
}
},
"SubnetRouteTableAssociation2" : {
"Type" : "AWS::EC2::SubnetRouteTableAssociation",
"Properties" : {
"SubnetId" : { "Ref" : "PublicSubnet2" },
"RouteTableId" : { "Ref" : "RouteTable" }
}
},
"ALBSecurityGroup" : {
"Type" : "AWS::EC2::SecurityGroup",
"Properties" : {
"VpcId" : { "Ref" : "VPC" },
"GroupDescription" : "Enable http access",
"GroupName" : "h4b-alb-sg",
"SecurityGroupIngress" : [
{ "IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0"}
],
"Tags" : [ {"Key" : "Name", "Value" : "h4b-alb-sg" } ]
}
},
"EC2SecurityGroup" : {
"Type" : "AWS::EC2::SecurityGroup",
"Properties" : {
"VpcId" : { "Ref" : "VPC" },
"GroupDescription" : "Enable http access from ALB Security Group",
"GroupName" : "h4b-ec2-sg",
"SecurityGroupIngress" : [
{ "IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : "0.0.0.0/0" },
{ "IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "SourceSecurityGroupId" : { "Ref" : "ALBSecurityGroup" }}
],
"Tags" : [ {"Key" : "Name", "Value" : "h4b-ec2-sg" } ]
}
},
"ALBTargetGroup" : {
"Type" : "AWS::ElasticLoadBalancingV2::TargetGroup",
"Properties" : {
"HealthCheckEnabled" : true,
"HealthCheckIntervalSeconds" : 30,
"Matcher" : {
"HttpCode" : "200"
},
"Name" : "h4b-tg",
"Port" : 80,
"Protocol" : "HTTP",
"TargetGroupAttributes" : [{
"Key" : "deregistration_delay.timeout_seconds",
"Value" : "120"
}],
"VpcId" : { "Ref" : "VPC" },
"Tags" : [ {"Key" : "Name", "Value" : "h4b-tg"} ]
}
},
"ALB" : {
"Type" : "AWS::ElasticLoadBalancingV2::LoadBalancer",
"Properties" : {
"IpAddressType" : "ipv4",
"Name" : "h4b-alb",
"Scheme" : "internet-facing",
"SecurityGroups" : [{ "Ref" : "ALBSecurityGroup" }],
"Subnets" : [ { "Ref" : "PublicSubnet1" }, {"Ref" : "PublicSubnet2"} ],
"Tags" : [ {"Key" : "Name", "Value" : "h4b-alb"} ],
"Type" : "application"
}
},
"ALBListener" : {
"Type" : "AWS::ElasticLoadBalancingV2::Listener",
"Properties" : {
"DefaultActions" : [{
"TargetGroupArn" : { "Ref" : "ALBTargetGroup" },
"Type" : "forward"
}],
"LoadBalancerArn" : { "Ref" : "ALB" },
"Port" : 80,
"Protocol" : "HTTP"
}
}
}
}
ファイルをアップロードして次へを選択し、スタックの名前をh4b-stack
にする。
これ以降の設定は任意で設定し、スタックの作成を選択する。
2.Amazon AutoScalingのコンポーネント
Amazon AutoScalingコンポーネントは大きく分けて以下の2つである。
・起動テンプレート
・オートスケーリンググループ
起動テンプレート
オートスケーリングによって起動されるインスタンスの起動情報を設定するテンプレート
起動情報とは...
- Amazon Machine image(AMI)
- インスタンスタイプ
- ネットワーク設定 など
オートスケーリンググループ
スケーリングの設定を行うコンポーネント
設定内容
- どの構成テンプレートを使用するか
- 何台構成にするか
- スケールアウトする台数
- スケールインする台数
- なにをトリガーにスケールするか
3.スケジュールスケーリングの設定
一度きりの実行や毎日、毎週といった実行が可能。
起動テンプレートの作成
マネジメントコンソールからEC2→起動テンプレート→テンプレートを作成を選択
ここでは以下のように設定した。
起動テンプレート名:h4b-template
AMI:クイックスタートタブ→AmazonLinux→Amazon Linux2 AMI
インスタンスタイプ:t2.micro
セキュリティーグループ:h4b-ec2-sg(EC2用のセキュリティーグループ(先ほどのCloudformationで作成済み))
リソースタグ:キーをName、値はh4b-instance
高度な設定:Cloudwatch モニタリング有効化
ユーザーデータ:下のコードを貼り付ける。事前に以下のコマンドが実行された状態でEC2が立ち上がる。
#!/bin/bash
sudo yum update -y
sudo yum install -y httpd
sudo amazon-linux-extras install epel -y
sudo yum install stress -y
sudo systemctl start httpd
sudo echo `hostname` > /var/www/html/index.html
sudo echo "ClientAliveInterval 60" >> /etc/ssh/sshd_config
sudo echo "ClientAliveCountMax 120" >> /etc/ssh/sshd_config
sudo systemctl restart sshd.service
オートスケーリンググループの作成
マネジメントコンソール→EC2 →オートスケーリンググループ→オートスケーリンググループの作成を選択
設定内容
Auto Scaling グループ名:h4b-autoscaling-group
起動テンプレート:h4b-template(先ほどつくったもの)
次へ
↓
VPC:h4b-vpc(Cloudformationで設定したもの)
アベイラビリティーゾンとサブネット:h4b-subnet1,h4b-subnet2(アベイラビリティーゾンが異なる2つ選択)
次へ
↓
既存のロードバランサーへアタッチ
既存のロードバランサーターゲットグループ:h4b-tg
次へ
↓
希望する容量:1
最小キャパシティー:1
最大キャパシティー:4
↓
次へ
↓
次へ
↓
オートスケーリンググループを作成を選択
作成したオートスケーリンググループをクリックし、詳細タブやアクティビティータブを見るときちんと実行されているのが確認できる。
スケジュールの設定
マネジメントコンソールからEC2→Auto Scalingグループ→オートスケーリングタブ→予定されたアクションを作成する。
設定内容
名前:h4b-schedule
希望する容量:2
最小キャパシティー:2
最大キャパシティー4
開始時刻:(例)2022年7月17日 15:38(5分後を目安にするといいみたい)
再度、作成したオートスケーリンググループをクリックし、詳細タブやアクティビティータブを見るときちんと実行されているのが確認できる。
4.動的スケーリング
動的スケーリング実行するためにはスケーリングポリシーを作成する必要がある。
スケーリングポリシーには3種類のポリシーがある
- ターゲット追跡スケーリング
- ステップスケーリング
- シンプルなスケーリング
今回はターゲット追跡スケーリングを使用する。
ターゲット追跡スケーリングは設定したターゲット値を維持するようにスケールイン、スケールアウトする。
ターゲット追跡スケーリングの設定
マネジメントコンソールからEC2→Auto Scalingグループ→オートスケーリングタブ→動的スケーリングポリシーを作成する。
設定内容
ポリシータイプ:ターゲット追跡スケーリング
ターゲット値:80
マネジメントコンソールからCloudWatchLogs→アラームで現在出ているアラームを確認できる。
負荷をかけてスケールアウト確認
マネジメントコンソールからEC2→インスタンスを選択する。
該当インスタンス2つにssh接続し、stress -c 1
←このコマンドを実行する。
この挙動もCloudWatchLogsから確認できる。
負荷を止めてスケールインを確認
ssh接続した画面に戻り、ctr-Cでコマンドを中止する。
しばらく待つとh4bインスタンスが2台に減少することを確認できる。
##異常なインスタンスの置き換え
EC2のインスタンス画面から、h4bインスタンスを選択し削除するとスケジュールスケーリングで設定したインスタンスの台数に戻っていることが確認できる。
5.リソースの削除
以下の順番でリソースを削除する。
オートスケーリンググループの削除
↓
起動テンプレートの削除
↓
CloudFormationのスタックの削除
補足
スケーリングによってインスタンスが増減するため、特定のサーバーに依存するようなステートフルな設計ではなくステートレスな設計が求められる。
例えば)セッション管理,ログ管理など