混沌工程实践 - 使用 AWS Fault Injection Simulator 验证容错性
介绍使用 AWS Fault Injection Simulator(FIS)实践混沌工程。包括故障注入场景设计、向 EC2/ECS/RDS 注入故障以及安全实验的推进方法。
混沌工程的必要性与 FIS 的作用
生产环境的故障在不可预测的时间发生。EC2 实例突然停止、AZ 故障、网络延迟增大、数据库故障转移等,预先验证系统在这些故障下能否正确运行就是混沌工程。这种方法源于 Netflix 开发的 Chaos Monkey,通过有意注入故障来验证系统的容错性。AWS Fault Injection Simulator(FIS)是 2021 年发布的托管混沌工程服务,以安全且受控的方式对 AWS 资源执行故障注入。无需自建混沌工程工具,通过与 AWS 服务的原生集成,可向 EC2、ECS、EKS、RDS、ElastiCache、Systems Manager 等广泛资源注入故障。
实验模板的设计
FIS 的实验通过实验模板定义。模板由操作(做什么)、目标(对哪些资源)和停止条件(何时中止)三个要素构成。操作示例包括:aws:ec2:stop-instances(停止 EC2)、aws:ec2:send-spot-instance-interruptions(模拟 Spot 中断)、aws:ssm:send-command(通过 SSM 施加 CPU/内存压力)、aws:ecs:stop-task(停止 ECS 任务)、aws:rds:failover-db-cluster(Aurora 故障转移)、aws:fis:inject-api-internal-error(AWS API 错误注入)。 ```json { "description": "EC2 实例停止实验", "targets": { "ec2Instances": { "resourceType": "aws:ec2:instance", "resourceTags": {"Environment": "dev"}, "selectionMode": "COUNT(1)" } }, "actions": { "stopInstances": { "actionId": "aws:ec2:stop-instances", "parameters": {"startInstancesAfterDuration": "PT5M"}, "targets": {"Instances": "ec2Instances"} } }, "stopConditions": [ {"source": "aws:cloudwatch:alarm", "value": "arn:aws:cloudwatch:ap-northeast-1:123:alarm:high-error-rate"} ], "roleArn": "arn:aws:iam::123:role/FISExperimentRole" } ``` 通过目标的 selectionMode 控制目标资源的选择方式。COUNT(1) 选择 1 个,PERCENT(50) 选择 50% 的资源。可通过基于标签的过滤限定实验对象。
安全实验的推进方法
混沌工程中最重要的是确保安全性。FIS 提供多重安全机制。停止条件(Stop Conditions)监控 CloudWatch 告警,当错误率或延迟超过阈值时自动停止实验。这防止实验对生产服务造成过度影响。通过 IAM 角色将实验权限限制到最小,防止对实验对象外资源的影响。实验的逐步扩大也是重要实践。首先在 dev 环境从小规模实验(停止 1 个实例)开始,验证结果后扩大范围。然后在 stg 环境以接近生产的条件实验,最终在生产环境进行有限实验。实验前建立假设(「即使 1 台 EC2 停止,ALB 也会自动分配流量,错误率应保持在 1% 以下」)也很重要,假设不成立时系统的改进点就会明确。 容错性设计的实践经验可参考Amazon 的相关书籍。
实践性实验场景
介绍代表性实验场景。AZ 故障模拟中,同时停止特定 AZ 内的 EC2 实例,验证多 AZ 配置的 Auto Scaling 是否正确工作。网络延迟注入中,通过 SSM 执行 tc(traffic control)命令增加特定实例的网络延迟,确认微服务间通信是否通过超时和重试正确处理。RDS 故障转移中,执行 Aurora 集群的故障转移,验证应用是否自动重新连接到新的写入端点。Spot 实例中断模拟中,模拟 2 分钟前的中断通知,确认应用的优雅关闭是否正确工作。费用为实验操作执行时间每分钟 0.10 USD,5 分钟的实验为 0.50 USD。
总结
AWS FIS 是以安全且受控的方式实践混沌工程的托管服务。通过实验模板定义故障注入场景,停止条件确保安全性,逐步扩大实验范围。从 dev 环境的小规模实验开始,逐步扩展到生产环境,持续验证和改善系统的容错性。