Auto Scaling and Rolling Updates on AWS via Cloud Formation
前言
在設計架構時, 通常會去考慮水平擴展的可能性, 使其將來能應付突然湧入的大量請求, 要作到這點, 可以把EC2建在AWS的Auto Scaling Group裡面, 透過修改Launch Configuration, 讓Auto Scaling Group去調整目前EC2的實體數量, 然後外部再串一個Load Balancer,做為用戶端的單一存取窗口並且將流量分散到各個EC2實體上
大致上需要部屬在雲上的資源有
- Security Group
- Launch Configuration
- Load Balancer
- Auto Scaling Group
如果用AWS Portal去一個個把這些資源建立起來的話實在很花時間, 這邊介紹如何使用CloudFormation快速的部屬雲端資源
CloudFormation
這個功能有點類似於Azure Resource Manager, 開發人員可以用一份描述檔以JSON或是YAML的格式來描述雲端上的資源, 然後再餵給CloudFormation 去把所有資源部屬起來描述檔結構, 基本上可以分為四個部分
{
"AWSTemplateFormatVersion": "2010-09-09",
"Metadata": { ... },
"Parameters": { ... },
"Resources": { ... }
}
Parameters
Parameters這邊我們先定義幾個變數: myVPC, keyName 以及BuildNumber "Parameters": {
"myVPC": {
"Type": "String",
"Default": "vpc-da58b9b1"
},
"mykeyName": {
"Type": "String",
"Default": "app123"
},
"BuildNumber": {
"Type": "String",
"Default": "1",
"Description": "Number of the build being deployed"
}
},
aws ec2 describe-vpcs
將VPC的資料輸出來看keyName則是用來登錄EC2的金鑰對名稱, 可以執行指令
aws ec2 describe-key-pairs
列出目前可用的金鑰Security Group
用來定義那些Port應該要開, 或者哪些IP的請求能進來,,,等等"SecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Allow http to client host",
"VpcId": {
"Ref": "myVPC"
},
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": 80,
"ToPort": 80,
"CidrIp": "0.0.0.0/0"
}
],
"SecurityGroupEgress": [
{
"IpProtocol": "-1",
"CidrIp": "0.0.0.0/0"
}
]
}
},
Launch Configuration
這邊我們可以定義要部屬的instance種類, OS Image, 登陸EC2用的金鑰對, Security Group, 以及欲配置的EC2硬碟大小"LaunchConfig": {
"Type": "AWS::AutoScaling::LaunchConfiguration",
"Properties": {
"ImageId": "ami-0986c2ac728528ac2",
"InstanceType": "t2.micro",
"KeyName": { "Ref": "mykeyName" },
"SecurityGroups": [
{
"Ref": "SecurityGroup"
}
],
"BlockDeviceMappings": [
{
"DeviceName": "/dev/sda1",
"Ebs": {
"SnapshotId": "snap-08052bb8129c221eb",
"VolumeSize": 20,
"VolumeType": "gp2",
"DeleteOnTermination": true
}
}
],
"UserData": {
"Fn::Base64": {
"Fn::Join": [
"",
[
"Content-Type: multipart/mixed; boundary=\"//\"\n",
"MIME-Version: 1.0\n",
"\n",
"--//\n",
"Content-Type: text/x-include-url; charset=\"us-ascii\"\n",
"MIME-Version: 1.0 \n",
"\n",
"#include\n",
"https://raw.githubusercontent.com/andy51002000/cloud-formation-example/master/init.sh",
"\n",
"--//\n",
"Content-Type: text/x-shellscript; charset=\"us-ascii\"\n",
"MIME-Version: 1.0\n",
"\n",
"#!/bin/bash\n",
"touch /tmp/cloud-init-was-here\n",
"touch /tmp/ver-", { "Ref": "BuildNumber" }, "\n",
"apt install -y python-pip\n",
"pip install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",
"# Signal the status from cfn-init\n",
"/usr/local/bin/cfn-signal -s true",
" --stack ", { "Ref" : "AWS::StackName" },
" --resource AutoScalingGroup ",
" --region ", { "Ref" : "AWS::Region" },
"\n",
"\n",
"--//\n"
]
]
}
}
},
上面定義的User Data寫成白話文的話如下所示,
Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0
--//
Content-Type: text/x-include-url; charset="us-ascii"
MIME-Version: 1.0
#include
https://csg91462f27b9a8x414axa81.blob.core.windows.net
--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
#!/bin/bash
touch /tmp/ver-$BuildNumber
apt install -y python-pip
pip install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz
# Signal the status from cfn-init
/usr/local/bin/cfn-signal -s true
--stack my-stack-123
--resource AutoScalingGroup
--region us-east-2
--//
主要分為兩個部分
第一部分用#include去下載腳本然後執行
第二部分則是用#!/bin/bash直接執行定義的指令, 這些指令主要作的事情很簡單, 就是叫cfn-signal去送一個"部屬已經完成"的信號給CloudFormation
Load Balancer
這邊需要定義Security Group, 以及Scheme的種類, 若是想要配置一個對外的Load Balancer, Scheme這邊需要指定為"internet-facing", 除此之外,還需要定義那些Port需要被監聽, 以及Health Check的規則"LoadBalancer": {
"Type": "AWS::ElasticLoadBalancing::LoadBalancer",
"Properties": {
"SecurityGroups": [
{
"Ref": "SecurityGroup"
}
],
"Scheme": "internet-facing",
"Subnets": [
"subnet-cf5610b5",
"subnet-3346e87f",
"subnet-0351596b"
],
"Listeners": [
{
"InstancePort": "80",
"InstanceProtocol": "HTTP",
"LoadBalancerPort": "80",
"Protocol": "HTTP"
}
],
"HealthCheck": {
"Target": "HTTP:80/",
"Timeout": "5",
"Interval": "30",
"UnhealthyThreshold": "2",
"HealthyThreshold": "2"
}
},
},
Auto Scaling Group
這邊可以定義要起多少EC2 VM, 外掛哪個Load Balancer, 以及根據哪一份Launch Configuration去建立EC2資源,,,等等除此之外, 我們也可以定義一些規則如Create Policy, Update Policy
Creation Policy
這部分可以決定要不要去等VM的"部屬完成"信號, 以及等待時間, 當超出這個時限, CloudFormation會認為部屬失敗
Update Policy
可以用來規範Rolling update的方法
"AutoScalingGroup": {
"Type": "AWS::AutoScaling::AutoScalingGroup",
"Properties": {
"AvailabilityZones": [
"us-east-2a",
"us-east-2b",
"us-east-2c"
],
"LaunchConfigurationName": {
"Ref": "LaunchConfig"
},
"MinSize": "1",
"MaxSize": "4",
"DesiredCapacity": "1",
"HealthCheckType": "ELB",
"HealthCheckGracePeriod": "1800",
"LoadBalancerNames": [
{
"Ref": "LoadBalancer"
}
]
},
"UpdatePolicy": {
"AutoScalingRollingUpdate": {
"MinInstancesInService": "1",
"MaxBatchSize": "1",
"WaitOnResourceSignals": "true",
"PauseTime": "PT40M"
}
},
"CreationPolicy": {
"ResourceSignal": {
"Count": "1",
"Timeout": "PT40M"
}
}
}
開始使用CloudFormation配置資源
先建立一個資源描述檔cloud_formation.json, 然後將它傳到S3保存
(描述檔可以到這邊下載https://raw.githubusercontent.com/andy51002000/cloud-formation-example/master/cloud_formation.json)
aws s3 mb s3://andy-deploy-cloud
aws s3 cp ./cloud_formation.json s3://andy-deploy-cloud
建立Stack
欲配置的資源都需要放在一個Stack裡面, 這樣的好處是建立時可以一起建立, 刪除時也可以一併刪除
aws cloudformation create-stack \
--stack-name myteststack \
--template-url https://s3.amazonaws.com/andy-deploy-cloud/cloud_formation.json
結論
使用Cloud Formation開發者可以非常快速地建立雲上的資源, 修改資源, 以及刪除資源, 因為所有的相關資源都被群組在同一份Stack 裡面, 除此之外, 使用CloudFormation還有一個好處, 就是資源的設置可以進版控, 進而保存資源配置的所有變化Source Code 位置
https://github.com/andy51002000/cloud-formation-example.git更新資源
以上的內容是關於如何建置, 若想要知道如何更新資源可以參考下一篇Ref:
CloudFormation Samples
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/sample-templates-services-us-west-2.html#w2ab1c23c48c13b7
https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-key-pairs.html
https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-vpcs.html
https://docs.aws.amazon.com/zh_tw/AWSCloudFormation/latest/UserGuide/stacksets-getting-started-create.html
https://criconmun.wordpress.com/2016/04/23/auto-scaling-and-rolling-updates-on-aws/
留言
張貼留言