我们使用机器学习技术将英文博客翻译为简体中文。您可以点击导航栏中的“中文(简体)”切换到英文版本。
在 Spinnaker 中构建多元化且成本优化的 EC2 服务器组
这篇博客文章由高级专业容器股份公司桑迪普·帕拉瓦拉萨和软件开发工程师 Prathibha Datta-Kumar 撰写
在听取客户对 Spinnaker
在这篇文章中,我们将详细介绍最近的增强功能,以及如何按照
亚马逊 EC2 竞价型实例
遵守竞价最佳
三角帆概念
Spinnaker 使用三个关键
应用程序是集群的集合,集群是服务器组的集合,服务器组标识可部署的项目和基本配置设置,例如实例数量、自动扩展策略、元数据等。这与 亚马逊云科技 中的 Aut
三角帆和亚马逊 EC2 集成
2020 年年中,我们开始研究 Spinnaker 支持的亚马逊 EC2 功能集中的客户请求和差距。大约在同一时间,Spinnaker OSS 增加了对
以下是最近贡献的一些功能亮点:
Feature | Why use it? (Example use cases) |
Multiple Instance Types | Tap into multiple capacity pools to achieve and maintain the desired scale using Spot Instances. |
Combining On-Demand and Spot Instances | — 控制在服务器组中启动的按需和竞价型实例的比例。 — 将竞价型实例与 Amazon EC2 预留实例或储蓄计划相结合。 |
Amazon EC2 Auto Scaling allocation strategies | Reduce overall Spot interruptions by launching from Spot pools that are optimally chosen based on the available Spot capacity, using capacity-optimized Spot allocation strategy. |
Capacity rebalancing | Improve your workload availability by proactively shifting your Spot capacity to optimal pools by enabling capacity rebalancing along with capacity-optimized allocation strategy. |
Improved support for
|
Reduce costs by preventing wastage of CPU cycles. |
我们建议 API 用户使用 Spinnaker 稳定版 1.28.x,用户界面用户使用 1.29.x。这是相关 PR 和功能版本 的
现在我们已经了解了新功能,让我们在下面的教程中看看如何使用其中的一些功能。
示例教程:使用按需和竞价型实例在自动扩展组上部署演示 Web 应用程序
在本示例教程中,我们将 Spinnaker 设置为部署到 Amazon EC2,创建
在整个教程中,我们将利用 Spinnaker 的 API 来创建新资源,并提供有关如何使用 Spinnaker UI(Deck)部署相同资源并利用 UI 查看资源的快速指南。
先决条件
作为完成本教程的先决条件,您必须拥有一个具有
1。三角帆设置
1.1 创建用于连接 Spinnaker 和 Spinnaker 启动的 EC2 实例的安全外壳 (SSH) 密钥对。
AWS_REGION=us-west-2 # Change the region where you want Spinnaker deployed
EC2_KEYPAIR_NAME=spinnaker-blog-${AWS_REGION}
aws ec2 create-key-pair --key-name ${EC2_KEYPAIR_NAME} --region ${AWS_REGION} --query KeyMaterial --output text > ~/${EC2_KEYPAIR_NAME}.pem
chmod 600 ~/${EC2_KEYPAIR_NAME}.pem
1.2 部署 Cloudformation 堆栈。
STACK_NAME=spinnaker-blog
SPINNAKER_VERSION=1.29.1 # Change the version if newer versions are available
NUMBER_OF_AZS=3
AVAILABILITY_ZONES=${AWS_REGION}a,${AWS_REGION}b,${AWS_REGION}c
ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
S3_BUCKET_NAME=spin-persitent-store-${ACCOUNT_ID}
# Download template
curl -o setup-spinnaker-with-deployment-vpc.yml https://raw.githubusercontent.com/awslabs/ec2-spot-labs/master/ec2-spot-spinnaker/setup-spinnaker-with-deployment-vpc.yml
# deploy stack
aws cloudformation deploy --template-file setup-spinnaker-with-deployment-vpc.yml \
--stack-name ${STACK_NAME} \
--parameter-overrides NumberOfAZs=${NUMBER_OF_AZS} \
AvailabilityZones=${AVAILABILITY_ZONES} \
EC2KeyPairName=${EC2_KEYPAIR_NAME} \
SpinnakerVersion=${SPINNAKER_VERSION} \
SpinnakerS3BucketName=${S3_BUCKET_NAME} \
--capabilities CAPABILITY_NAMED_IAM --region ${AWS_REGION}
1.3 连接到三角帆
1.3.1 获取 SSH 命令转发 Deck(基于浏览器的用户界面(9000)和 Gate(API Gateway(8084)的端口转发,以访问 Spinnaker 用户界面和 API。
SPINNAKER_INSTANCE_DNS_NAME=$(aws cloudformation describe-stacks --stack-name ${STACK_NAME} --region ${AWS_REGION} --query "Stacks[].Outputs[?OutputKey=='SpinnakerInstance'].OutputValue" --output text)
echo 'ssh -A -L 9000:localhost:9000 -L 8084:localhost:8084 -L 8087:localhost:8087 -i ~/'${EC2_KEYPAIR_NAME}' ubuntu@$'{SPINNAKER_INSTANCE_DNS_NAME}''
1.3.2 打开一个新终端并使用 SSH 命令(上一个命令的输出)连接到 Spinnaker 实例。
2。部署演示 Web 应用程序
在继续操作之前,让我们确保在 shell 中拥有所需的环境变量。如果你使用与以前相同的终端窗口,那么你可能已经有了这些变量。
STACK_NAME=spinnaker-blog 亚马逊云科技_REGION=us-west-2 # use the same region as before EC2_KEYPAIR_NAME=spinnaker-blog-${亚马逊云科技_REGION} VPC_ID=$(aws cloudformation describe-stacks --stack-name ${STACK_NAME} --region ${亚马逊云科技_REGION} --query "Stacks[].Outputs[?OutputKey=='VPCID'].OutputValue" --output text)
2.1 创建三角帆应用程序
我们首先在 Spinnaker 中创建一个应用程序,它是我们部署的服务的占位符。
curl 'http://localhost:8084/tasks' \
-H 'Content-Type: application/json;charset=utf-8' \
--data-raw \
'{
"job":[
{
"type":"createApplication",
"application":{
"cloudProviders":"aws",
"instancePort":80,
"name":"demoapp",
"email":"test@test.com",
"providerSettings":{
"aws":{
"useAmiBlockDeviceMappings":true
}
}
}
}
],
"application":"demoapp",
"description":"Create Application: demoapp"
}'
2.2 创建应用程序负载均衡器
让我们创建一个应用程序负载均衡器和端口 80 的目标组,跨越公有子网中的三个可用区。我们使用防火墙 演示-ALB-SecurityGroup 来允许公众通过端口 80 访问 ALB。
由于竞价型实例会中断并发出两分钟警告,因此您必须将目标组的
curl 'http://localhost:8084/tasks' \
-H 'Content-Type: application/json;charset=utf-8' \
--data-binary \
'{
"application":"demoapp",
"description":"Create Load Balancer: demoapp",
"job":[
{
"type":"upsertLoadBalancer",
"name":"demoapp-lb",
"loadBalancerType":"application",
"cloudProvider":"aws",
"credentials":"my-aws-account",
"region":"'"${AWS_REGION}"'",
"vpcId":"'"${VPC_ID}"'",
"subnetType":"public-subnet",
"idleTimeout":60,
"targetGroups":[
{
"name":"demoapp-targetgroup",
"protocol":"HTTP",
"port":80,
"targetType":"instance",
"healthCheckProtocol":"HTTP",
"healthCheckPort":"traffic-port",
"healthCheckPath":"/",
"attributes":{
"deregistrationDelay":90
}
}
],
"regionZones":[
"'"${AWS_REGION}"'a",
"'"${AWS_REGION}"'b",
"'"${AWS_REGION}"'c"
],
"securityGroups":[
"Demo-ALB-SecurityGroup"
],
"listeners":[
{
"protocol":"HTTP",
"port":80,
"defaultActions":[
{
"type":"forward",
"targetGroupName":"demoapp-targetgroup"
}
]
}
]
}
]
}'
2.3 创建服务器组
在创建服务器组(Auto Scaling 组)之前,以下是示例中 使用的
-
-
- onDemandBaseCapacity (默认为 0): 必须由按需实例提供的 ASG 的最低容量(也可以应用于预留实例或储蓄计划)。该示例使用三个 OnDemandBas eCapacity。
- OnDemandPercentageAboveBaseCapacity ( 默认 100) :超出 OnDemandBaseCapacity 额外容量的 按需实例和竞价型实例的百分比。 该示例使用了 10%(即 90 % 现货)的 onDemandPercentageAboveBase Capacity。
- SpotAllocationSt rategy :这表明您希望如何在每个可用区的竞价型实例池中分配实例。该示例使用推荐的 容量优化 策略。实例是从最佳竞价池中启动的,这些池是根据启动的实例数量的可用竞价容量选择的。
- launchTemplateOverridesforInstanceType :适用于您的工作负载的实例类型 列表。指定多个实例类型可以利用多个可用区中的多个实例池,旨在增强服务的可用性。您可以使用
ec2-instance-selec tor(一种开源 亚马逊云科技 命令行接口 (CLI) 工具)根据 vcpus 和内存等资源标准来缩小实例类型的范围。
-
-
-
- 容量再平衡 :启用后,此功能会利用新的 EC2 实例
再平衡建议主动管理 EC 2 竞价型实例 生命周期。 通过在 ASG 中断竞价型实例被 Amazon EC2 中断之前,自动尝试替换 ASG 中的竞价型实例,从而提高了对可用性的重视。我们在这个例子中启用了这个功能。
- 容量再平衡 :启用后,此功能会利用新的 EC2 实例
-
了解有关 sp
让我们创建一个服务器组,其所需容量为 12 个实例,涵盖当前和上一代实例类型,附加之前创建的 ALB,使用仅允许来自 ALB 的 http 流量的防火墙的 demo-ec2-SecurityGrou p,使用以下 bash 脚本安装 http,并将实例元 数据 添加 到 index.html 中。
2.3.1 将用户数据 bash 脚本保存到 user-date.sh 文件中。
请注意,三角帆仅支持 base64 编码的用户数据。在下一步中,我们将使用 b ase64 b ash 命令对文件内容进行编码。
cat << "EOF" > user-data.sh
#!/bin/bash
yum update -y
yum install httpd -y
echo "<html>
<head>
<title>Demo Application</title>
<style>body {margin-top: 40px; background-color: #Gray;} </style>
</head>
<body>
<h2>You have reached a Demo Application running on</h2>
<ul>
<li>instance-id: <b> `curl http://169.254.169.254/latest/meta-data/instance-id` </b></li>
<li>instance-type: <b> `curl http://169.254.169.254/latest/meta-data/instance-type` </b></li>
<li>instance-life-cycle: <b> `curl http://169.254.169.254/latest/meta-data/instance-life-cycle` </b></li>
<li>availability-zone: <b> `curl http://169.254.169.254/latest/meta-data/placement/availability-zone` </b></li>
</ul>
</body>
</html>" > /var/www/html/index.html
systemctl start httpd
systemctl enable httpd
EOF
2.3.2 通过运行以下命令创建服务器组。请注意,我们使用创建的 KeypairName 作为先决条件的一部分。
curl 'http://localhost:8084/tasks' \
-H 'Content-Type: application/json;charset=utf-8' \
-d \
'{
"job":[
{
"type":"createServerGroup",
"cloudProvider":"aws",
"account":"my-aws-account",
"application":"demoapp",
"stack":"",
"credentials":"my-aws-account",
"healthCheckType": "ELB",
"healthCheckGracePeriod":600,
"capacityRebalance": true,
"onDemandBaseCapacity":3,
"onDemandPercentageAboveBaseCapacity":10,
"spotAllocationStrategy":"capacity-optimized",
"setLaunchTemplate":true,
"launchTemplateOverridesForInstanceType":[
{
"instanceType":"m4.large"
},
{
"instanceType":"m5.large"
},
{
"instanceType":"m5a.large"
},
{
"instanceType":"m5ad.large"
},
{
"instanceType":"m5d.large"
},
{
"instanceType":"m5dn.large"
},
{
"instanceType":"m5n.large"
}
],
"capacity":{
"min":6,
"max":21,
"desired":12
},
"subnetType":"private-subnet",
"availabilityZones":{
"'"${AWS_REGION}"'":[
"'"${AWS_REGION}"'a",
"'"${AWS_REGION}"'b",
"'"${AWS_REGION}"'c"
]
},
"keyPair":"'"${EC2_KEYPAIR_NAME}"'",
"securityGroups":[
"Demo-EC2-SecurityGroup"
],
"instanceType":"m5.large",
"virtualizationType":"hvm",
"amiName":"'"$(aws ec2 describe-images --owners amazon --filters "Name=name,Values=amzn2-ami-hvm-2*x86_64-gp2" --query 'reverse(sort_by(Images, &CreationDate))[0].Name' --region ${AWS_REGION} --output text)"'",
"targetGroups":[
"demoapp-targetgroup"
],
"base64UserData":"'"$(base64 user-data.sh)"'",,
"associatePublicIpAddress":false,
"instanceMonitoring":false
}
],
"application":"demoapp",
"description":"Create New server group in cluster demoapp"
}'
Spinnaker 会创建一个 Amazon EC2
我们刚刚创建的服务器组和启动模板在 Spinnaker UI 中将如下所示:
用户界面还显示容量类型,例如实例 信息 部分中每种 实例 类型的购买选项:
3。访问应用程序
选择服务器组右上角的树形图标复制应用程序负载均衡器 URL,然后在浏览器中进行访问。您可以多次刷新,以查看请求每次都会发送到不同的实例。
恭喜!您成功地将演示应用程序部署到分散在多种实例类型和购买选项的 Amazon EC2 服务器组上。
此外,您可以克隆、修改、禁用和销毁这些服务器组,也可以将它们与 Spinnaker
节省成本
前往 EC2 控制台 > 竞价请求 > 保存摘要,查看在 EC2 竞价型实例上部署演示应用程序所节省的费用。
清理
为避免产生任何额外费用,请清理本教程中创建的资源。
首先,删除 Spinnaker 中的服务器组、应用程序负载均衡器和应用程序。
curl 'http://localhost:8084/tasks' \
-H 'Content-Type: application/json;charset=utf-8' \
--data-raw \
'{
"job":[
{
"reason":"Cleanup",
"asgName":"demoapp-v000",
"moniker":{
"app":"demoapp",
"cluster":"demoapp",
"sequence":0
},
"serverGroupName":"demoapp-v000",
"type":"destroyServerGroup",
"region":"'"${AWS_REGION}"'",
"credentials":"my-aws-account",
"cloudProvider":"aws"
},
{
"cloudProvider":"aws",
"loadBalancerName":"demoapp-lb",
"loadBalancerType":"application",
"regions":[
"'"${AWS_REGION}"'"
],
"credentials":"my-aws-account",
"vpcId":"'"${VPC_ID}"'",
"type":"deleteLoadBalancer"
},
{
"type":"deleteApplication",
"application":{
"name":"demoapp",
"cloudProviders":"aws"
}
}
],
"application":"demoapp",
"description":"Deleting ServerGroup, ALB and Application: demoapp"
}'
等待 Spinnaker 删除所有资源,然后再继续操作。您可以在 Spinnaker 用户界面或
然后通过运行以下命令删除 Spinnaker 基础架构:
aws ec2 delete-key-pair --key-name ${EC2_KEYPAIR_NAME} --region ${亚马逊云科技_REGION} rm ~/${EC2_KEYPAIR_NAME}.pem aws s3api delete-objects \ --bucket ${S3_BUCKET_NAME} \ --delete "$(aws s3api list-object-versions \ --bucket ${S3_BUCKET_NAME} \ --query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}')" #If error occurs, there are no Versions and is OK aws s3api delete-objects \ --bucket ${S3_BUCKET_NAME} \ --delete "$(aws s3api list-object-versions \ --bucket ${S3_BUCKET_NAME} \ --query='{Objects: DeleteMarkers[].{Key:Key,VersionId:VersionId}}')" #If error occurs, there are no DeleteMarkers and is OK aws s3 rb s3://${S3_BUCKET_NAME} --force #Delete Bucket aws cloudformation delete-stack --region ${亚马逊云科技_REGION} --stack-name ${STACK_NAME}
结论
在这篇文章中,我们了解了最近添加到 Spinnaker 中的 Amazon EC2 新功能,以及如何使用它们来构建多元化和优化的自动扩展组。我们还讨论了
我们很乐意听取你的意见!