aws(学习笔记第十五课) 如何从灾难中恢复(recover)
aws(学习笔记第十五课)
- 如何从灾难中恢复
学习内容:
- 使用
CloudWatch
对服务器进行监视与恢复 - 区域(
region
),可用区(available zone
)和子网(subnet
) - 使用自动扩展(
AutoScalingGroup
)
1. 使用CloudWatch
对服务器进行监视与恢复
- 整体架构
这里模拟Jenkins Server
在灾难时候,可以由AWS Cloudwatch Alarm
监视到,之后将其recover
。
在这里,elastic ip
定义了,并且将其指向了Jenkins Server
。为什么平时没有使用elastic ip
,这里特意使用它呢。
因为默认如果让AWS
自动配置给ec2
的internet ip
,都是临时的ip
,每次ec2
实例重启了之后,都会重新分配ip
。但是作为Jenkins Server
来使用,并且一旦从灾难中recover
之后,ip address
变化的话,运用起来将会特别不方便。
2. 代码解析
- 代码
{"AWSTemplateFormatVersion": "2010-09-09","Description": " (Jenkins (CI server) running on EC2 with AWS CloudWatch recovery)","Parameters": {"KeyName": {"Description": "Key Pair name","Type": "AWS::EC2::KeyPair::KeyName","Default": "my-cli-key"},"JenkinsAdminPassword": {"Description": "Password for Jenkins admin user","Type": "String","AllowedPattern" : "[a-zA-Z0-9]*","MinLength" : "8","MaxLength" : "42"}},"Mappings": {"EC2RegionMap": {"ap-northeast-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-cbf90ecb"},"ap-southeast-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-68d8e93a"},"ap-southeast-2": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-fd9cecc7"},"eu-central-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-a8221fb5"},"eu-west-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-a10897d6"},"sa-east-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-b52890a8"},"us-east-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-1ecae776"},"us-west-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-d114f295"},"us-west-2": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-e7527ed7"}}},"Resources": {"VPC": {"Type": "AWS::EC2::VPC","Properties": {"EnableDnsSupport": "true","EnableDnsHostnames": "true","CidrBlock": "10.0.0.0/16","Tags": [{"Key": "Name","Value": "jenkins-recovery"}]}},"Subnet": {"Type": "AWS::EC2::Subnet","Properties": {"VpcId": {"Ref": "VPC"},"AvailabilityZone": {"Fn::Select": ["0", {"Fn::GetAZs": ""}]},"CidrBlock": "10.0.0.0/24","Tags": [{"Key": "Name","Value": "jenkins-recovery"}]}},"InternetGateway": {"Type": "AWS::EC2::InternetGateway","Properties": {"Tags": [{"Key": "Name","Value": "jenkins-recovery"}]}},"GatewayToInternet": {"Type": "AWS::EC2::VPCGatewayAttachment","Properties": {"VpcId": {"Ref": "VPC"},"InternetGatewayId": {"Ref": "InternetGateway"}}},"RouteTable": {"Type": "AWS::EC2::RouteTable","Properties": {"VpcId": {"Ref": "VPC"},"Tags": [{"Key": "Name","Value": "jenkins-recovery"}]}},"InternetRoute": {"Type": "AWS::EC2::Route","Properties": {"RouteTableId": {"Ref": "RouteTable"},"DestinationCidrBlock": "0.0.0.0/0","GatewayId": {"Ref": "InternetGateway"}},"DependsOn": "GatewayToInternet" },"RouteTableAssociation": {"Type": "AWS::EC2::SubnetRouteTableAssociation","Properties": {"SubnetId": {"Ref": "Subnet"},"RouteTableId": {"Ref": "RouteTable"}}},"NetworkAcl": {"Type": "AWS::EC2::NetworkAcl","Properties": {"VpcId": {"Ref": "VPC"},"Tags": [{"Key": "Name","Value": "jenkins-recovery"}]}},"NetworkAceSSH": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "10","Protocol": "6","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "22","To": "22"}}},"NetworkAceJenkinsHTTP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "11","Protocol": "6","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "8080","To": "8080"}}},"NetworkAceNTP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "20","Protocol": "17","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "123","To": "123"}}},"NetworkAceICMP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "30","Protocol": "1","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","Icmp": {"Code": "-1","Type": "-1"}}},"NetworkAceHighPortsTCP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "40","Protocol": "6","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "1024","To": "65535"}}},"NetworkAceHighPortsUDP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "41","Protocol": "17","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "1024","To": "65535"}}},"NetworkAceEgress": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "10","Protocol": "-1","RuleAction": "allow","Egress": "true","CidrBlock": "0.0.0.0/0","PortRange": {"From": "0","To": "65535"}}},"NetworkAclAssociation": {"Type": "AWS::EC2::SubnetNetworkAclAssociation","Properties": {"SubnetId": {"Ref": "Subnet"},"NetworkAclId": {"Ref": "NetworkAcl"}}},"SecurityGroup": {"Type": "AWS::EC2::SecurityGroup","Properties": {"GroupDescription": "SecurityGroupforjenkins","VpcId": {"Ref": "VPC"},"Tags": [{"Key": "Name","Value": "jenkins-recovery"}],"SecurityGroupIngress": [{"IpProtocol": "tcp","FromPort": "22","ToPort": "22","CidrIp": "0.0.0.0/0"},{"IpProtocol": "tcp","FromPort": "8080","ToPort": "8080","CidrIp": "0.0.0.0/0"},{"IpProtocol": "icmp","FromPort": "-1","ToPort": "-1","CidrIp": "0.0.0.0/0"}]}},"ElasticIP": {"Type": "AWS::EC2::EIP","Properties": {"InstanceId": {"Ref": "Server"},"Domain": "vpc"},"DependsOn": "GatewayToInternet"},"Server": {"Type": "AWS::EC2::Instance","Properties": {"ImageId": {"Fn::FindInMap": ["EC2RegionMap", {"Ref": "AWS::Region"}, "AmazonLinuxAMIHVMEBSBacked64bit"]},"InstanceType": "t2.micro","KeyName": {"Ref": "KeyName"},"SecurityGroupIds": [{"Ref": "SecurityGroup"}],"SubnetId": {"Ref": "Subnet"},"UserData": {"Fn::Base64": {"Fn::Join": ["", ["#!/bin/bash -ex\n","wget http://pkg.jenkins-ci.org/redhat/jenkins-1.616-1.1.noarch.rpm\n","rpm --install jenkins-1.616-1.1.noarch.rpm\n","sed -i -e 's/JENKINS_ARGS=\\\"\\\"/JENKINS_ARGS=\\\"--argumentsRealm.passwd.admin=", {"Ref": "JenkinsAdminPassword"}, " --argumentsRealm.roles.admin=admin\\\"/g' /etc/sysconfig/jenkins\n","echo \"<?xml version='1.0' encoding='UTF-8'?><hudson><version>1.0</version><useSecurity>true</useSecurity><authorizationStrategy class=\\\"hudson.security.FullControlOnceLoggedInAuthorizationStrategy\\\"/><securityRealm class=\\\"hudson.security.LegacySecurityRealm\\\"/></hudson>\" > /var/lib/jenkins/config.xml\n","service jenkins start\n"]]}},"Tags": [{"Key": "Name","Value": "jenkins-recovery"}]},"DependsOn": "GatewayToInternet"},"RecoveryAlarm": {"Type": "AWS::CloudWatch::Alarm","Properties": {"AlarmDescription": "Recover server when underlying hardware fails.","Namespace": "AWS/EC2" ,"MetricName": "StatusCheckFailed_System","Statistic": "Minimum","Period": "60","EvaluationPeriods": "5","ComparisonOperator": "GreaterThanThreshold","Threshold": "0","AlarmActions": [{"Fn::Join": ["", ["arn:aws:automate:", { "Ref": "AWS::Region"}, ":ec2:recover"]]}],"Dimensions": [{"Name": "InstanceId", "Value": {"Ref": "Server"}}]}}},"Outputs": {"JenkinsURL": {"Description": "URL to access web interface of Jenkins server.","Value": {"Fn::Join": ["", ["http://", {"Ref": "ElasticIP"}, ":8080"]]}},"User": {"Description": "Administrator user for Jenkins.","Value": "admin"},"Password": {"Description": "Password for Jenkins administrator user.","Value": {"Ref": "JenkinsAdminPassword"}}} }
- 分析
- 这里使用了
AWS:CloudWatch:Alarm
,如下所示。
这里,设置了"RecoveryAlarm": {"Type": "AWS::CloudWatch::Alarm","Properties": {"AlarmDescription": "Recover server when underlying hardware fails.","Namespace": "AWS/EC2" ,"MetricName": "StatusCheckFailed_System","Statistic": "Minimum","Period": "60","EvaluationPeriods": "5","ComparisonOperator": "GreaterThanThreshold","Threshold": "0","AlarmActions": [{"Fn::Join": ["", ["arn:aws:automate:", { "Ref": "AWS::Region"}, ":ec2:recover"]]}],"Dimensions": [{"Name": "InstanceId", "Value": {"Ref": "Server"}}]}}
AWS::CloudWatch::Alarm
,每隔60秒检查下ec2
的状态,如有ec2
有问题,那么使用arn:aws:automate:
进行在其他的Available Zone
恢复,但是这里无法让ec2 server
模拟出问题的场合,所以这里不能实际上让arn:aws:automate:ec2:recover
发生。
- 这里使用了
2. 区域(region
),可用区(available zone
)和子网(subnet
)
- 区域(
region
),可用区(available zone
)- 一个区域(
region
)里面,包含多个可用区(available zone
),每个可用区(available zone
)有多个数据中心(DataCenter
)。 - 不同区域(
region
)的之间通过低延时的链路链接。可以想象,在同一个region
的服务之前的网络延时会非常小。
- 一个区域(
- 全球性的服务跨多个区域
- 各种服务的不同区域
- 各种服务的不同区域
VPC
,区域(region
)以及子网(subnet
)VPC
一定会属于一个区域(region
)- 子网(
subnet
)一定属于一个可用区(Availibility Zone
)
3. 使用自动扩展(AutoScalingGroup
)
-
使用自动扩展(
AutoScalingGroup
),可以保证执行数量的虚拟服务器一直运行。- 代码
{"AWSTemplateFormatVersion": "2010-09-09","Description": "(Jenkins (CI server) running with Auto Scaling Group over multiple AZs)","Parameters": {"KeyName": {"Description": "Key Pair name","Type": "AWS::EC2::KeyPair::KeyName","Default": "my-cli-key"},"JenkinsAdminPassword": {"Description": "Password for Jenkins admin user","Type": "String","AllowedPattern" : "[a-zA-Z0-9]*","MinLength" : "8","MaxLength" : "42"}},"Mappings": {"EC2RegionMap": {"ap-northeast-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-cbf90ecb"},"ap-southeast-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-68d8e93a"},"ap-southeast-2": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-fd9cecc7"},"eu-central-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-a8221fb5"},"eu-west-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-a10897d6"},"sa-east-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-b52890a8"},"us-east-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-1ecae776"},"us-west-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-d114f295"},"us-west-2": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-e7527ed7"}}},"Resources": {"VPC": {"Type": "AWS::EC2::VPC","Properties": {"EnableDnsSupport": "true","EnableDnsHostnames": "true","CidrBlock": "10.0.0.0/16","Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"SubnetA": {"Type": "AWS::EC2::Subnet","Properties": {"VpcId": {"Ref": "VPC"},"AvailabilityZone": {"Fn::Select": ["0", {"Fn::GetAZs": ""}]},"CidrBlock": "10.0.0.0/24","Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"SubnetB": {"Type": "AWS::EC2::Subnet","Properties": {"VpcId": {"Ref": "VPC"},"AvailabilityZone": {"Fn::Select": ["1", {"Fn::GetAZs": ""}]},"CidrBlock": "10.0.1.0/24","Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"InternetGateway": {"Type": "AWS::EC2::InternetGateway","Properties": {"Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"GatewayToInternet": {"Type": "AWS::EC2::VPCGatewayAttachment","Properties": {"VpcId": {"Ref": "VPC"},"InternetGatewayId": {"Ref": "InternetGateway"}}},"RouteTable": {"Type": "AWS::EC2::RouteTable","Properties": {"VpcId": {"Ref": "VPC"},"Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"InternetRoute": {"Type": "AWS::EC2::Route","Properties": {"RouteTableId": {"Ref": "RouteTable"},"DestinationCidrBlock": "0.0.0.0/0","GatewayId": {"Ref": "InternetGateway"}},"DependsOn": "GatewayToInternet"},"RouteTableAssociationA": {"Type": "AWS::EC2::SubnetRouteTableAssociation","Properties": {"SubnetId": {"Ref": "SubnetA"},"RouteTableId": {"Ref": "RouteTable"}}},"RouteTableAssociationB": {"Type": "AWS::EC2::SubnetRouteTableAssociation","Properties": {"SubnetId": {"Ref": "SubnetB"},"RouteTableId": {"Ref": "RouteTable"}}},"NetworkAcl": {"Type": "AWS::EC2::NetworkAcl","Properties": {"VpcId": {"Ref": "VPC"},"Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"NetworkAceSSH": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "10","Protocol": "6","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "22","To": "22"}}},"NetworkAceJenkinsHTTP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "11","Protocol": "6","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "8080","To": "8080"}}},"NetworkAceNTP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "20","Protocol": "17","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "123","To": "123"}}},"NetworkAceICMP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "30","Protocol": "1","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","Icmp": {"Code": "-1","Type": "-1"}}},"NetworkAceHighPortsTCP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "40","Protocol": "6","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "1024","To": "65535"}}},"NetworkAceHighPortsUDP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "41","Protocol": "17","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "1024","To": "65535"}}},"NetworkAceEgress": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "10","Protocol": "-1","RuleAction": "allow","Egress": "true","CidrBlock": "0.0.0.0/0","PortRange": {"From": "0","To": "65535"}}},"NetworkAclAssociationA": {"Type": "AWS::EC2::SubnetNetworkAclAssociation","Properties": {"SubnetId": {"Ref": "SubnetA"},"NetworkAclId": {"Ref": "NetworkAcl"}}},"NetworkAclAssociationB": {"Type": "AWS::EC2::SubnetNetworkAclAssociation","Properties": {"SubnetId": {"Ref": "SubnetB"},"NetworkAclId": {"Ref": "NetworkAcl"}}},"SecurityGroupJenkins": {"Type": "AWS::EC2::SecurityGroup","Properties": {"GroupDescription": "SecurityGroupforjenkins","VpcId": {"Ref": "VPC"},"Tags": [{"Key": "Name","Value": "jenkins-multiaz"}],"SecurityGroupIngress": [{"IpProtocol": "tcp","FromPort": "22","ToPort": "22","CidrIp": "0.0.0.0/0"},{"IpProtocol": "tcp","FromPort": "8080","ToPort": "8080","CidrIp": "0.0.0.0/0"},{"IpProtocol": "icmp","FromPort": "-1","ToPort": "-1","CidrIp": "0.0.0.0/0"}]}},"LaunchTemplate": {"Type": "AWS::EC2::LaunchTemplate","Properties": {"LaunchTemplateName": "LaunchTemplate","LaunchTemplateData":{"ImageId": {"Fn::FindInMap": ["EC2RegionMap", {"Ref": "AWS::Region"}, "AmazonLinuxAMIHVMEBSBacked64bit"]},"KeyName": {"Ref": "KeyName"},"NetworkInterfaces":[{"DeviceIndex":0,"AssociatePublicIpAddress":true,"Groups":[{"Ref": "SecurityGroupJenkins"}],"DeleteOnTermination":true}],"InstanceType": "t2.micro","UserData": {"Fn::Base64": {"Fn::Join": ["",["#!/bin/bash -ex\n","wget http://pkg.jenkins-ci.org/redhat/jenkins-1.616-1.1.noarch.rpm\n","rpm --install jenkins-1.616-1.1.noarch.rpm\n","sed -i -e 's/JENKINS_ARGS=\\\"\\\"/JENKINS_ARGS=\\\"--argumentsRealm.passwd.admin=", {"Ref": "JenkinsAdminPassword"}, " --argumentsRealm.roles.admin=admin\\\"/g' /etc/sysconfig/jenkins\n","echo \"<?xml version='1.0' encoding='UTF-8'?><hudson><version>1.0</version><useSecurity>true</useSecurity><authorizationStrategy class=\\\"hudson.security.FullControlOnceLoggedInAuthorizationStrategy\\\"/><securityRealm class=\\\"hudson.security.LegacySecurityRealm\\\"/></hudson>\" > /var/lib/jenkins/config.xml\n","service jenkins start\n"]]}}}}},"AutoScalingGroup": {"Type": "AWS::AutoScaling::AutoScalingGroup","Properties": {"LaunchTemplate" : {"LaunchTemplateId" : {"Ref" : "LaunchTemplate"},"Version" : {"Fn::GetAtt" : ["LaunchTemplate","LatestVersionNumber"]}},"Tags": [{"Key": "Name","Value": "jenkins-multiaz","PropagateAtLaunch": true}],"DesiredCapacity": 1,"MinSize": 1,"MaxSize": 1,"VPCZoneIdentifier": [{"Ref": "SubnetA"}, {"Ref": "SubnetB"}],"HealthCheckGracePeriod": 600,"HealthCheckType": "EC2"},"DependsOn": "GatewayToInternet"}} }
- 代码解析
AutoScalingGroup
设定了两个subnet
,可以在一个subnet
的EC2 server
出现问题的时候,在另一个subnet
启动另一个EC2 server
。
subnet A
和subnet B
每个subnet
都在不同的Availability Zone
。
- 创建一个
jenkins task
- 删除
jenkins
实例
- 检测
Auto Scaling Group
的动作
可以看到Auto Scaling Group
会马上启动另一个EC2 server
来支持jenkins
服务。
注意,这里,IP
地址和建立的jenkins task
都已经没有了,接下来解决两个问题。 - 代码
-
使用
AMI
进行恢复。- 在现在的
jenkins server
上建立task
- 对当前的
jenkins server
保存镜像Dell@DESKTOP-DHMQMJG MINGW64 ~/.ssh $ aws ec2 create-image --instance-id i-05593a7ba7b94e566 --name jenkins-multiaz {"ImageId": "ami-01ed9b718c5a467c4" }
- 对
cloudformation
进行更新
*在参数中增加AMISnapshot
,稍后更新CloudFormation
的时候会选择上面建立的AMI
。
-
对
cloudformation
进行更新,LaunchTemplate
里面设定AMI
参数- 在参数中增加
AMISnapshot
,稍后更新CloudFormation
的时候会选择上面建立的AMI
。
- 对
cloudformation
进行更新
- 在参数中增加
-
Cloudformation
更新成功
*删除当前的Jenkins server
-
重启之后的
jenkins server
确认
可以看到上面建立的jenkins task
已经保留过来了,原因是使用了AMI
,对当前的EBS
进行了保存。
-
cloudformation
代码{"AWSTemplateFormatVersion": "2010-09-09","Description": "AWS in Action: chapter 11 (Jenkins (CI server) running with Auto Scaling Group over multiple AZs)","Parameters": {"KeyName": {"Description": "Key Pair name","Type": "AWS::EC2::KeyPair::KeyName","Default": "my-cli-key"},"JenkinsAdminPassword": {"Description": "Password for Jenkins admin user","Type": "String","AllowedPattern" : "[a-zA-Z0-9]*","MinLength" : "8","MaxLength" : "42"},"AMISnapshot": {"Description": "AMI ID to start virtual server from.","Type": "String","AllowedPattern" : "[\u0020-\uD7FF\uE000-\uFFFD\uD800\uDC00-\uDBFF\uDFFF\r\n\t]*","MinLength" : "1","MaxLength" : "255"}},"Resources": {"VPC": {"Type": "AWS::EC2::VPC","Properties": {"EnableDnsSupport": "true","EnableDnsHostnames": "true","CidrBlock": "10.0.0.0/16","Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"SubnetA": {"Type": "AWS::EC2::Subnet","Properties": {"VpcId": {"Ref": "VPC"},"AvailabilityZone": {"Fn::Select": ["0", {"Fn::GetAZs": ""}]},"CidrBlock": "10.0.0.0/24","Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"SubnetB": {"Type": "AWS::EC2::Subnet","Properties": {"VpcId": {"Ref": "VPC"},"AvailabilityZone": {"Fn::Select": ["1", {"Fn::GetAZs": ""}]},"CidrBlock": "10.0.1.0/24","Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"InternetGateway": {"Type": "AWS::EC2::InternetGateway","Properties": {"Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"GatewayToInternet": {"Type": "AWS::EC2::VPCGatewayAttachment","Properties": {"VpcId": {"Ref": "VPC"},"InternetGatewayId": {"Ref": "InternetGateway"}}},"RouteTable": {"Type": "AWS::EC2::RouteTable","Properties": {"VpcId": {"Ref": "VPC"},"Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"InternetRoute": {"Type": "AWS::EC2::Route","Properties": {"RouteTableId": {"Ref": "RouteTable"},"DestinationCidrBlock": "0.0.0.0/0","GatewayId": {"Ref": "InternetGateway"}},"DependsOn": "GatewayToInternet"},"RouteTableAssociationA": {"Type": "AWS::EC2::SubnetRouteTableAssociation","Properties": {"SubnetId": {"Ref": "SubnetA"},"RouteTableId": {"Ref": "RouteTable"}}},"RouteTableAssociationB": {"Type": "AWS::EC2::SubnetRouteTableAssociation","Properties": {"SubnetId": {"Ref": "SubnetB"},"RouteTableId": {"Ref": "RouteTable"}}},"NetworkAcl": {"Type": "AWS::EC2::NetworkAcl","Properties": {"VpcId": {"Ref": "VPC"},"Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"NetworkAceSSH": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "10","Protocol": "6","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "22","To": "22"}}},"NetworkAceJenkinsHTTP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "11","Protocol": "6","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "8080","To": "8080"}}},"NetworkAceNTP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "20","Protocol": "17","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "123","To": "123"}}},"NetworkAceICMP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "30","Protocol": "1","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","Icmp": {"Code": "-1","Type": "-1"}}},"NetworkAceHighPortsTCP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "40","Protocol": "6","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "1024","To": "65535"}}},"NetworkAceHighPortsUDP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "41","Protocol": "17","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "1024","To": "65535"}}},"NetworkAceEgress": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "10","Protocol": "-1","RuleAction": "allow","Egress": "true","CidrBlock": "0.0.0.0/0","PortRange": {"From": "0","To": "65535"}}},"NetworkAclAssociationA": {"Type": "AWS::EC2::SubnetNetworkAclAssociation","Properties": {"SubnetId": {"Ref": "SubnetA"},"NetworkAclId": {"Ref": "NetworkAcl"}}},"NetworkAclAssociationB": {"Type": "AWS::EC2::SubnetNetworkAclAssociation","Properties": {"SubnetId": {"Ref": "SubnetB"},"NetworkAclId": {"Ref": "NetworkAcl"}}},"SecurityGroupJenkins": {"Type": "AWS::EC2::SecurityGroup","Properties": {"GroupDescription": "SecurityGroupforjenkins","VpcId": {"Ref": "VPC"},"Tags": [{"Key": "Name","Value": "jenkins-multiaz"}],"SecurityGroupIngress": [{"IpProtocol": "tcp","FromPort": "22","ToPort": "22","CidrIp": "0.0.0.0/0"},{"IpProtocol": "tcp","FromPort": "8080","ToPort": "8080","CidrIp": "0.0.0.0/0"},{"IpProtocol": "icmp","FromPort": "-1","ToPort": "-1","CidrIp": "0.0.0.0/0"}]}},"LaunchTemplate": {"Type": "AWS::EC2::LaunchTemplate","Properties": {"LaunchTemplateName": "LaunchTemplate","LaunchTemplateData":{"ImageId": {"Ref": "AMISnapshot"},"KeyName": {"Ref": "KeyName"},"NetworkInterfaces":[{"DeviceIndex":0,"AssociatePublicIpAddress":true,"Groups":[{"Ref": "SecurityGroupJenkins"}],"DeleteOnTermination":true}],"InstanceType": "t2.micro","UserData": {"Fn::Base64": {"Fn::Join": ["",["#!/bin/bash -ex\n","wget http://pkg.jenkins-ci.org/redhat/jenkins-1.616-1.1.noarch.rpm\n","rpm --install jenkins-1.616-1.1.noarch.rpm\n","sed -i -e 's/JENKINS_ARGS=\\\"\\\"/JENKINS_ARGS=\\\"--argumentsRealm.passwd.admin=", {"Ref": "JenkinsAdminPassword"}, " --argumentsRealm.roles.admin=admin\\\"/g' /etc/sysconfig/jenkins\n","echo \"<?xml version='1.0' encoding='UTF-8'?><hudson><version>1.0</version><useSecurity>true</useSecurity><authorizationStrategy class=\\\"hudson.security.FullControlOnceLoggedInAuthorizationStrategy\\\"/><securityRealm class=\\\"hudson.security.LegacySecurityRealm\\\"/></hudson>\" > /var/lib/jenkins/config.xml\n","service jenkins start\n"]]}}}}},"AutoScalingGroup": {"Type": "AWS::AutoScaling::AutoScalingGroup","Properties": {"LaunchTemplate" : {"LaunchTemplateId" : {"Ref" : "LaunchTemplate"},"Version" : {"Fn::GetAtt" : ["LaunchTemplate","LatestVersionNumber"]}},"Tags": [{"Key": "Name","Value": "jenkins-multiaz","PropagateAtLaunch": true}],"DesiredCapacity": 1,"MinSize": 1,"MaxSize": 1,"VPCZoneIdentifier": [{"Ref": "SubnetA"}, {"Ref": "SubnetB"}],"HealthCheckGracePeriod": 600,"HealthCheckType": "EC2"},"DependsOn": "GatewayToInternet"}} }
- 在现在的
-
使用
elastic IP
进行对网络接口进行固定。IP
地址每次都要发生变化,还是不理想。- 利用
elastic IP
进行网络接口的固定 - 修改的代码
- 设定
IamRole
"IamRole": {"Type": "AWS::IAM::Role","Properties": {"AssumeRolePolicyDocument": {"Version": "2012-10-17","Statement": [{"Effect": "Allow","Principal": {"Service": ["ec2.amazonaws.com"]},"Action": ["sts:AssumeRole"]}]},"Path": "/","Policies": [{"PolicyName": "root","PolicyDocument": {"Version": "2012-10-17","Statement": [{"Action": ["ec2:AssociateAddress"],"Resource": ["*"],"Effect": "Allow"}]}}]}},"IamInstanceProfile": {"Type": "AWS::IAM::InstanceProfile","Properties": {"Path": "/","Roles": [{"Ref": "IamRole"}]}},
- 为
LaunchTemplate
设定IamRole
参数
这里主要是为了给EC2 server
实例设定IamRole
,以便EC2 server
能够执行aws ec2 associate-address
命令,在灾难恢复的时候设定固定的Elastic IP
。
- 更新
cloudformation
堆栈
*Elastic IP
整体代码{"AWSTemplateFormatVersion": "2010-09-09","Description": "AWS in Action: chapter 11 (Jenkins (CI server) running with Auto Scaling Group over multiple AZs)","Parameters": {"KeyName": {"Description": "Key Pair name","Type": "AWS::EC2::KeyPair::KeyName","Default": "my-cli-key"},"JenkinsAdminPassword": {"Description": "Password for Jenkins admin user","Type": "String","AllowedPattern" : "[a-zA-Z0-9]*","MinLength" : "8","MaxLength" : "42"},"AMISnapshot": {"Description": "AMI ID to start virtual server from.","Type": "String","AllowedPattern" : "[\u0020-\uD7FF\uE000-\uFFFD\uD800\uDC00-\uDBFF\uDFFF\r\n\t]*","MinLength" : "1","MaxLength" : "255"}},"Mappings": {"EC2RegionMap": {"ap-northeast-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-cbf90ecb"},"ap-southeast-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-68d8e93a"},"ap-southeast-2": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-fd9cecc7"},"eu-central-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-a8221fb5"},"eu-west-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-a10897d6"},"sa-east-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-b52890a8"},"us-east-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-1ecae776"},"us-west-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-d114f295"},"us-west-2": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-e7527ed7"}}},"Resources": {"VPC": {"Type": "AWS::EC2::VPC","Properties": {"EnableDnsSupport": "true","EnableDnsHostnames": "true","CidrBlock": "10.0.0.0/16","Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"SubnetA": {"Type": "AWS::EC2::Subnet","Properties": {"VpcId": {"Ref": "VPC"},"AvailabilityZone": {"Fn::Select": ["0", {"Fn::GetAZs": ""}]},"CidrBlock": "10.0.0.0/24","Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"SubnetB": {"Type": "AWS::EC2::Subnet","Properties": {"VpcId": {"Ref": "VPC"},"AvailabilityZone": {"Fn::Select": ["1", {"Fn::GetAZs": ""}]},"CidrBlock": "10.0.1.0/24","Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"InternetGateway": {"Type": "AWS::EC2::InternetGateway","Properties": {"Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"GatewayToInternet": {"Type": "AWS::EC2::VPCGatewayAttachment","Properties": {"VpcId": {"Ref": "VPC"},"InternetGatewayId": {"Ref": "InternetGateway"}}},"RouteTable": {"Type": "AWS::EC2::RouteTable","Properties": {"VpcId": {"Ref": "VPC"},"Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"InternetRoute": {"Type": "AWS::EC2::Route","Properties": {"RouteTableId": {"Ref": "RouteTable"},"DestinationCidrBlock": "0.0.0.0/0","GatewayId": {"Ref": "InternetGateway"}},"DependsOn": "GatewayToInternet"},"RouteTableAssociationA": {"Type": "AWS::EC2::SubnetRouteTableAssociation","Properties": {"SubnetId": {"Ref": "SubnetA"},"RouteTableId": {"Ref": "RouteTable"}}},"RouteTableAssociationB": {"Type": "AWS::EC2::SubnetRouteTableAssociation","Properties": {"SubnetId": {"Ref": "SubnetB"},"RouteTableId": {"Ref": "RouteTable"}}},"NetworkAcl": {"Type": "AWS::EC2::NetworkAcl","Properties": {"VpcId": {"Ref": "VPC"},"Tags": [{"Key": "Name","Value": "jenkins-multiaz"}]}},"NetworkAceSSH": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "10","Protocol": "6","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "22","To": "22"}}},"NetworkAceJenkinsHTTP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "11","Protocol": "6","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "8080","To": "8080"}}},"NetworkAceNTP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "20","Protocol": "17","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "123","To": "123"}}},"NetworkAceICMP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "30","Protocol": "1","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","Icmp": {"Code": "-1","Type": "-1"}}},"NetworkAceHighPortsTCP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "40","Protocol": "6","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "1024","To": "65535"}}},"NetworkAceHighPortsUDP": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "41","Protocol": "17","RuleAction": "allow","Egress": "false","CidrBlock": "0.0.0.0/0","PortRange": {"From": "1024","To": "65535"}}},"NetworkAceEgress": {"Type": "AWS::EC2::NetworkAclEntry","Properties": {"NetworkAclId": {"Ref": "NetworkAcl"},"RuleNumber": "10","Protocol": "-1","RuleAction": "allow","Egress": "true","CidrBlock": "0.0.0.0/0","PortRange": {"From": "0","To": "65535"}}},"NetworkAclAssociationA": {"Type": "AWS::EC2::SubnetNetworkAclAssociation","Properties": {"SubnetId": {"Ref": "SubnetA"},"NetworkAclId": {"Ref": "NetworkAcl"}}},"NetworkAclAssociationB": {"Type": "AWS::EC2::SubnetNetworkAclAssociation","Properties": {"SubnetId": {"Ref": "SubnetB"},"NetworkAclId": {"Ref": "NetworkAcl"}}},"SecurityGroupJenkins": {"Type": "AWS::EC2::SecurityGroup","Properties": {"GroupDescription": "SecurityGroupforjenkins","VpcId": {"Ref": "VPC"},"Tags": [{"Key": "Name","Value": "jenkins-multiaz"}],"SecurityGroupIngress": [{"IpProtocol": "tcp","FromPort": "22","ToPort": "22","CidrIp": "0.0.0.0/0"},{"IpProtocol": "tcp","FromPort": "8080","ToPort": "8080","CidrIp": "0.0.0.0/0"},{"IpProtocol": "icmp","FromPort": "-1","ToPort": "-1","CidrIp": "0.0.0.0/0"}]}},"IamRole": {"Type": "AWS::IAM::Role","Properties": {"AssumeRolePolicyDocument": {"Version": "2012-10-17","Statement": [{"Effect": "Allow","Principal": {"Service": ["ec2.amazonaws.com"]},"Action": ["sts:AssumeRole"]}]},"Path": "/","Policies": [{"PolicyName": "root","PolicyDocument": {"Version": "2012-10-17","Statement": [{"Action": ["ec2:AssociateAddress"],"Resource": ["*"],"Effect": "Allow"}]}}]}},"IamInstanceProfile": {"Type": "AWS::IAM::InstanceProfile","Properties": {"Path": "/","Roles": [{"Ref": "IamRole"}]}},"ElasticIP": {"Type": "AWS::EC2::EIP","Properties": {"Domain": "vpc"},"DependsOn": "GatewayToInternet"},"LaunchTemplate": {"Type": "AWS::EC2::LaunchTemplate","Properties": {"LaunchTemplateName": "LaunchTemplate","LaunchTemplateData":{"ImageId": {"Ref": "AMISnapshot"},"KeyName": {"Ref": "KeyName"},"NetworkInterfaces":[{"DeviceIndex":0,"AssociatePublicIpAddress":true,"Groups":[{"Ref": "SecurityGroupJenkins"}],"DeleteOnTermination":true}],"InstanceType": "t2.micro","UserData": {"Fn::Base64": {"Fn::Join": ["",["#!/bin/bash -ex\n","aws configure set default.region ", {"Ref": "AWS::Region"},"\n","INSTANCE_ID=`curl -s http://169.254.169.254/latest/meta-data/instance-id`\n","aws ec2 associate-address --instance-id $INSTANCE_ID --allocation-id ", {"Fn::GetAtt": ["ElasticIP", "AllocationId"]}, "\n","wget http://pkg.jenkins-ci.org/redhat/jenkins-1.616-1.1.noarch.rpm\n","rpm --install jenkins-1.616-1.1.noarch.rpm\n","sed -i -e 's/JENKINS_ARGS=\\\"\\\"/JENKINS_ARGS=\\\"--argumentsRealm.passwd.admin=", {"Ref": "JenkinsAdminPassword"}, " --argumentsRealm.roles.admin=admin\\\"/g' /etc/sysconfig/jenkins\n","echo \"<?xml version='1.0' encoding='UTF-8'?><hudson><version>1.0</version><useSecurity>true</useSecurity><authorizationStrategy class=\\\"hudson.security.FullControlOnceLoggedInAuthorizationStrategy\\\"/><securityRealm class=\\\"hudson.security.LegacySecurityRealm\\\"/></hudson>\" > /var/lib/jenkins/config.xml\n","service jenkins start\n"]]}}}}},"AutoScalingGroup": {"Type": "AWS::AutoScaling::AutoScalingGroup","Properties": {"LaunchTemplate" : {"LaunchTemplateId" : {"Ref" : "LaunchTemplate"},"Version" : {"Fn::GetAtt" : ["LaunchTemplate","LatestVersionNumber"]}},"Tags": [{"Key": "Name","Value": "jenkins-elasticip","PropagateAtLaunch": true}],"DesiredCapacity": 1,"MinSize": 1,"MaxSize": 1,"VPCZoneIdentifier": [{"Ref": "SubnetA"}, {"Ref": "SubnetB"}],"HealthCheckGracePeriod": 600,"HealthCheckType": "EC2"},"DependsOn": "GatewayToInternet"}},"Outputs": {"JenkinsURL": {"Description": "URL to access web interface of Jenkins server.","Value": {"Fn::Join": ["", ["http://", {"Ref": "ElasticIP"}, ":8080"]]}},"User": {"Description": "Administrator user for Jenkins.","Value": "admin"},"Password": {"Description": "Password for Jenkins administrator user.","Value": {"Ref": "JenkinsAdminPassword"}}} }
- 为
- 设定