Terraform :AWS Auto Scaling 自动扩缩容
·
Terraform AWS Auto Scaling 自动扩缩容完整详解
这是AWS云原生架构的核心组件,彻底解决了手动管理服务器的痛点。通过自动扩缩容,你的应用可以根据流量自动调整服务器数量:流量高峰时自动增加实例保证性能,流量低谷时自动减少实例节省成本。这是所有生产级Web应用的必备功能。
一、核心价值:为什么需要自动扩缩容?
手动管理服务器的痛点
- 流量突增时,手动加机器来不及,导致服务宕机
- 流量低谷时,大量服务器闲置,浪费成本
- 服务器故障时,需要手动重启或重建,恢复时间长
- 无法应对不可预测的流量波动
Auto Scaling 的核心能力
✅ 自动扩容:CPU/内存/网络使用率高时,自动增加实例
✅ 自动缩容:使用率低时,自动减少实例,节省成本
✅ 自动自愈:实例故障时,自动终止并创建新实例替换
✅ 多可用区部署:自动将实例分布在多个可用区,提高可用性
✅ 零人工干预:所有操作完全自动化,不需要SSH登录
二、整体架构与核心概念
核心组件关系图
CloudWatch 监控
↓
指标达到阈值 → 触发告警 → 执行扩缩容策略
↓
Auto Scaling Group (ASG)
↓
Launch Configuration
↓
自动创建/终止 EC2 实例
核心概念澄清
-
Launch Configuration(启动配置)
- 是创建EC2实例的模板
- 定义了实例的所有属性:AMI、实例类型、SSH密钥、安全组、User Data等
- 不可变:一旦创建就不能修改,修改后会创建新的启动配置
-
Auto Scaling Group(自动扩展组)
- 是Auto Scaling的核心
- 定义了实例的数量范围、部署位置、健康检查方式等
- 根据扩缩容策略自动调整实例数量
- 自动将实例分布在多个可用区,实现高可用
-
Auto Scaling Policy(扩缩容策略)
- 定义了如何调整实例数量
- 支持多种调整方式:增加固定数量、减少固定数量、调整到指定数量、按百分比调整
-
CloudWatch Alarm(云监控告警)
- 监控EC2实例的各种指标(CPU、内存、网络等)
- 当指标达到阈值时,触发告警
- 告警会执行对应的扩缩容策略
三、核心代码逐行解析
1. autoscaling.tf(启动配置 + 自动扩展组)
1.1 Launch Configuration(启动配置)
resource "aws_launch_configuration" "example-launchconfig" {
name_prefix = "example-launchconfig" # 名称前缀,自动生成唯一名称
image_id = var.AMIS[var.AWS_REGION] # AMI镜像
instance_type = "t2.micro" # 实例规格
key_name = aws_key_pair.mykeypair.key_name # SSH密钥
security_groups = [aws_security_group.allow-ssh.id] # 安全组
}
关键说明:
name_prefix:强烈推荐使用name_prefix而不是name。因为Launch Configuration是不可变的,当你修改任何参数时,Terraform会创建一个新的Launch Configuration并删除旧的。使用name_prefix可以自动生成唯一的名称,避免命名冲突。- 这里可以添加
user_data参数,结合上一章节的CloudInit,实现实例启动时自动部署应用。
1.2 Auto Scaling Group(自动扩展组)
resource "aws_autoscaling_group" "example-autoscaling" {
name = "example-autoscaling"
vpc_zone_identifier = [aws_subnet.main-public-1.id, aws_subnet.main-public-2.id]
launch_configuration = aws_launch_configuration.example-launchconfig.name
min_size = 1 # 最小实例数
max_size = 2 # 最大实例数
desired_capacity = 1 # 期望实例数(可选,默认等于min_size)
health_check_grace_period = 300 # 健康检查宽限期(秒)
health_check_type = "EC2" # 健康检查类型
force_delete = true # 强制删除(测试环境用,生产环境不要开)
tag {
key = "Name"
value = "ec2 instance"
propagate_at_launch = true # 自动将标签传播到新创建的实例
}
}
关键参数详解:
| 参数 | 说明 | 生产环境建议 |
|---|---|---|
vpc_zone_identifier | 实例部署的子网列表 | 必须指定至少2个不同可用区的子网,实现高可用 |
min_size | 自动扩展组维护的最小实例数 | 根据业务最低需求设置 |
max_size | 自动扩展组允许的最大实例数 | 设置合理的上限,避免成本失控 |
desired_capacity | 期望实例数 | 不指定时默认等于min_size |
health_check_grace_period | 实例启动后,多久开始进行健康检查 | 给应用足够的启动时间,一般设置为300-600秒 |
health_check_type | 健康检查类型 | 生产环境建议使用ELB(负载均衡器健康检查),比EC2更准确 |
force_delete | 删除自动扩展组时,是否强制终止所有实例 | 生产环境必须设为false,防止误删 |
propagate_at_launch | 是否将标签传播到新创建的实例 | 设为true,方便管理和计费 |
三个数量参数的区别:
min_size:底线,无论如何都不能低于这个数量max_size:上限,无论如何都不能高于这个数量desired_capacity:当前期望的数量,扩缩容就是调整这个值
2. autoscalingpolicy.tf(扩缩容策略 + CloudWatch告警)
2.1 扩容策略与告警
# 扩容策略:增加1个实例
resource "aws_autoscaling_policy" "example-cpu-policy" {
name = "example-cpu-policy"
autoscaling_group_name = aws_autoscaling_group.example-autoscaling.name
adjustment_type = "ChangeInCapacity" # 调整类型:增加/减少固定数量
scaling_adjustment = "1" # 增加1个实例
cooldown = "300" # 冷却期:300秒(5分钟)
policy_type = "SimpleScaling" # 策略类型:简单扩展策略
}
# CloudWatch告警:CPU使用率>=30%持续4分钟,触发扩容
resource "aws_cloudwatch_metric_alarm" "example-cpu-alarm" {
alarm_name = "example-cpu-alarm"
comparison_operator = "GreaterThanOrEqualToThreshold"
evaluation_periods = "2" # 连续2个周期
metric_name = "CPUUtilization" # 监控指标:CPU使用率
namespace = "AWS/EC2" # 指标命名空间
period = "120" # 每个周期120秒(2分钟)
statistic = "Average" # 统计方式:平均值
threshold = "30" # 阈值:30%
# 监控哪个自动扩展组的指标
dimensions = {
"AutoScalingGroupName" = aws_autoscaling_group.example-autoscaling.name
}
actions_enabled = true
alarm_actions = [aws_autoscaling_policy.example-cpu-policy.arn] # 触发时执行的策略
}
2.2 缩容策略与告警
# 缩容策略:减少1个实例
resource "aws_autoscaling_policy" "example-cpu-policy-scaledown" {
name = "example-cpu-policy-scaledown"
autoscaling_group_name = aws_autoscaling_group.example-autoscaling.name
adjustment_type = "ChangeInCapacity"
scaling_adjustment = "-1" # 减少1个实例
cooldown = "300" # 冷却期:5分钟
policy_type = "SimpleScaling"
}
# CloudWatch告警:CPU使用率<=5%持续4分钟,触发缩容
resource "aws_cloudwatch_metric_alarm" "example-cpu-alarm-scaledown" {
alarm_name = "example-cpu-alarm-scaledown"
comparison_operator = "LessThanOrEqualToThreshold"
evaluation_periods = "2"
metric_name = "CPUUtilization"
namespace = "AWS/EC2"
period = "120"
statistic = "Average"
threshold = "5" # 阈值:5%
dimensions = {
"AutoScalingGroupName" = aws_autoscaling_group.example-autoscaling.name
}
actions_enabled = true
alarm_actions = [aws_autoscaling_policy.example-cpu-policy-scaledown.arn]
}
关键参数详解:
adjustment_type:调整类型,支持三种:ChangeInCapacity:增加/减少固定数量的实例ExactCapacity:调整到指定数量的实例PercentChangeInCapacity:按百分比增加/减少实例
cooldown:冷却期。扩缩容操作完成后,在冷却期内不会再执行任何扩缩容操作。作用是避免频繁扩缩容,给系统足够的时间稳定下来。period:每个数据点的时间间隔,单位秒。evaluation_periods:连续多少个周期达到阈值才触发告警。- Demo中阈值设置得很低(30%扩容,5%缩容)是为了方便测试,生产环境建议设置为:
- 扩容阈值:CPU使用率>=70-80%
- 缩容阈值:CPU使用率<=20-30%
四、完整工作流程
Auto Scaling Group 启动
↓
创建 min_size 个实例,分布在多个可用区
↓
CloudWatch 持续监控所有实例的平均 CPU 使用率
↓
┌─────────────────────────────────────────────────┐
│ CPU >= 30% 持续 4 分钟 │
│ ↓ │
│ 触发扩容告警 │
│ ↓ │
│ 执行扩容策略,增加 1 个实例 │
│ ↓ │
│ 进入 5 分钟冷却期,期间不执行任何扩缩容操作 │
└─────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────┐
│ CPU <= 5% 持续 4 分钟 │
│ ↓ │
│ 触发缩容告警 │
│ ↓ │
│ 执行缩容策略,减少 1 个实例 │
│ ↓ │
│ 进入 5 分钟冷却期,期间不执行任何扩缩容操作 │
└─────────────────────────────────────────────────┘
↓
循环监控
自动自愈流程:
- Auto Scaling 会定期检查所有实例的健康状态
- 如果发现某个实例不健康(如系统崩溃、网络不通)
- 会自动终止该实例,并创建一个新的实例替换它
- 整个过程完全自动,不需要人工干预
五、完整部署与测试步骤
1. 准备工作
# 生成SSH密钥对
ssh-keygen -t rsa -b 2048 -f mykey -N ""
2. 部署所有资源
cd demo-12-autoscaling
terraform init
terraform plan
terraform apply
3. 查看自动扩展组和实例
# 查看自动扩展组详情
aws autoscaling describe-auto-scaling-groups --auto-scaling-group-names example-autoscaling
# 查看当前运行的实例
aws ec2 describe-instances --filters "Name=tag:Name,Values=ec2 instance"
4. 测试自动扩容
# SSH登录到其中一个实例
ssh -i mykey ubuntu@<实例公网IP>
# 安装stress工具,压测CPU
sudo apt update && sudo apt install -y stress
# 启动4个进程,每个进程占用100%CPU
stress -c 4
现在等待4-5分钟,CloudWatch会检测到CPU使用率超过30%,触发扩容,自动创建第二个实例。
5. 测试自动缩容
# 在实例中按Ctrl+C停止stress工具
等待4-5分钟,CPU使用率会降到5%以下,触发缩容,自动终止一个实例,回到1个实例的状态。
6. 查看扩缩容活动历史
aws autoscaling describe-scaling-activities --auto-scaling-group-name example-autoscaling
六、生产环境最佳实践
1. 使用 Launch Template 代替 Launch Configuration
Launch Configuration 已经被 AWS 标记为**遗留(legacy)**功能,推荐使用 Launch Template 代替:
- 支持版本管理,可以回滚到之前的版本
- 支持更多高级功能:混合实例类型、竞价实例、专用主机等
- 可以在不替换整个自动扩展组的情况下更新启动模板
2. 高可用改进
- 跨至少3个可用区部署:提高容错能力
- 使用 ELB 健康检查:比 EC2 健康检查更准确,可以检测应用层的健康状态
- 启用实例保护:防止重要的实例被缩容终止
3. 扩缩容策略改进
- 使用目标跟踪扩展策略(Target Tracking Scaling) 代替简单扩展策略:
- 更智能,自动调整实例数量,将指标维持在目标值附近
- 不需要手动配置扩容和缩容两个策略
- 示例:将平均CPU使用率维持在70%
- 配置计划扩展:应对已知的流量高峰(如促销活动)
- 配置预测扩展:AWS会根据历史流量预测未来的需求,提前扩容
4. 成本优化
- 使用混合实例策略:结合按需实例和竞价实例,大幅降低成本
- 合理设置缩容阈值:不要过于激进,避免频繁缩容
- 使用合适的实例规格:根据应用的CPU/内存需求选择合适的实例类型
5. 安全改进
- 不要给实例公网IP:将实例放在私网子网,通过NAT网关上网
- 使用最小权限原则:给实例分配具有最小权限的IAM角色
- 配置安全组:只开放必要的端口
6. 运维改进
- 配置通知:扩缩容时发送邮件或短信通知
- 启用 CloudWatch 详细监控:收集1分钟粒度的指标数据
- 配置生命周期钩子:在实例启动和终止时执行自定义操作(如注册到服务发现、注销负载均衡器)
七、常见坑点与排错
-
实例创建失败但Auto Scaling不报错:
- 查看自动扩展组的活动历史:
aws autoscaling describe-scaling-activities - 常见原因:AMI不存在、实例规格不足、安全组不存在、子网没有足够的IP地址
- 查看自动扩展组的活动历史:
-
健康检查太严格导致实例频繁被终止:
- 调大
health_check_grace_period,给应用足够的启动时间 - 使用ELB健康检查代替EC2健康检查
- 调大
-
冷却期设置不合理导致频繁扩缩容:
- 冷却期太短:会导致频繁扩缩容,系统不稳定
- 冷却期太长:无法及时响应流量变化
- 一般设置为300-600秒比较合适
-
CloudWatch告警不触发:
- 检查
dimensions是否正确,特别是AutoScalingGroupName - 检查指标是否有数据:
aws cloudwatch get-metric-statistics - 检查
period和evaluation_periods的设置
- 检查
-
缩容时终止了错误的实例:
- 配置终止策略:默认是先终止最旧的实例
- 可以配置为终止最接近下一个计费小时的实例,节省成本
- 对重要实例启用实例保护
八、下一步进阶方向
掌握了基础的Auto Scaling后,你可以继续学习以下内容,组成完整的高可用Web应用架构:
- ALB应用负载均衡器:将流量分发到多个实例,实现负载均衡和HTTPS
- 目标跟踪扩展策略:更智能的扩缩容方式
- 计划扩展和预测扩展:应对已知和未知的流量高峰
- 混合实例策略:结合按需实例和竞价实例,大幅降低成本
- 生命周期钩子:在实例启动和终止时执行自定义操作
- 蓝绿部署和滚动更新:实现应用的无停机更新
更多推荐
所有评论(0)