亚马逊AWS官方博客

企业备份&容灾系列 – AWS 多区域 Pilot Light 容灾设计

本文详细介绍了如何在AWS上实现跨区域的pilot light灾备方案,由于部分闲置的AWS组件会给客户增加额外的成本,因此在整个方案中,除了VPC预配置和RDS热备外,其余所有的组件 都是灾难发生后通过脚本动态创建,达到最小的Infra cost。当发生灾难时,用户通过预先定义好的灾备脚本,在灾备 区域快速构建 AWS 资源。

前提假设

该方案是模拟一个 WordPress cluster 部署在 AWS 上进行 multi-region pilot light 灾备的方案。生产区域组件选择如下:

  • RDS MySQL: WordPress 数据库
  • ElastiCache: 使用 Redis Object Cache 插件,使得 WordPress 支持Redis 作为缓存,提高用户访问体验
  • S3: WordPress 的文件存储在 S3 上,通过 S3FS 软件挂载到EC2
  • EC2: 安装 WordPress 应用,通过Auto Scaling Group 实现弹性伸缩
  • ELB: 作为负载均衡,将接收到的流量转发给后端的 WordPress 集群
  • NAT Gateway: WordPress 经由 NAT 网关主动访问外网

架构

根据 Pilot Light 的需求,我们需要将 WordPress 的文件存储,和数据库异步同步到其他其他区域。架构图如下:  以下为各个组件的介绍。 RDS MySQL 数据备份  RDS Mysql 配置Cross Region Replica,实现数据库的异步复制。如何配置跨Region只读副本,请参考文档。 当灾难发生后,通过提升只读副本为独立的数据库实例,使其能够执行正常的写入操作。在本方案中,会使用脚本实现 提升只读副本的操作。 S3 Bucket 数据备份(WordPress Media File) 开启S3 Cross Region Replication,实现S3文件的跨Region自动复制。关于如何开启S3跨区域复制, 请参考文档。 应用镜像  当北京区域新建AMI后,需要把新建的AMI复制到宁夏区域。您可以手动触发复制过程 也可以通过脚本自动化整个过程,例如在CloudWatch Event中设定时任务,触发lambda捕捉某段时间内 新建的AMI,通过简单的AWS api调用把新建的AMI复制到到宁夏区域。请根据项目实时性的需求为定时任务 设定合适的执行频率。 应用配置  在EC2的启动配置中设置user-data,使EC2内应用程序在启动后能够获取所需的配置,例如RDS Mysql和 Redis的endpoint等等。启动配置已经包含在灾难恢复的脚本中。 灾备脚本  按照上述方案,在GitHub aws-dr-samples上提供了基于 Terraform 的可执行脚本,该套脚本可以帮助用户快速构建模拟生产环境和灾备环境。 用户根据所需创建的资源写成脚本文件。执行脚本时,Terraform 通过调用 AWS API 来快速构建 AWS 资源。下文有如何使用的详细步骤描述。 在本方案中,设定Redis不包含持久化数据。因此无需实现复制,只需在灾难恢复时通过脚本创建新实例即可。 当灾难发生后,按照以下顺序进行灾难恢复:

  1. 手动提升RDS只读副本为独立的数据库实例.
  2. 执行脚本创建容灾集群。
  3. 进行健康检查,确定容灾集群能够正常运行。
  4. 执行DNS切换,把用户访问切换到容灾集群。

接下来,我们会详细描述该方案的实施步骤和脚本运行执行过程。

价格

以宁夏区为例,按照上述灾备方案,假定需要的灾备资源及产生的费用为:

    • AMI 20G: 镜像文件在宁夏区存储的费用
    • S3 1T 不频繁访问:由于是灾备访问,平时不会被使用,推荐不频繁访问
    • RDS Read Replica: 跨区域可读实例
    • 跨区域网络传输 2T: 包括S3 跨区域拷贝,Read Replica 跨区域复制等等
服务 类型 单价 1 年价格
AMI 20G   0.277/GB/月 66.48
S3 不频繁访问 1T   0.1030029/GB/月 1265.7
RDS Read Replica db.m4.large 单AZ 1.1733/小时 5540
Cross Region traffic 2T   0.6003/GB 1229.414
    Total 8101.594
    Total with tax 8587.69

以上仅做参考,实际配置情况,应该根据工作负载合理配置。

terraform脚本目录

terraform脚本请点击此处获取。 项目内有三个文件夹,basicdatabaseapp

      • basic: 基础结构。可用于构建基础网络架构, 基础安全配置等等。 包含如下资源:
        • VPC
        • Subnet (包含 public subnet, private subnet)
        • Security Group
        • DB Subnet Group
        • Cache Subnet Group
        • Route Table
      • database: 数据库架构。用于自动创建 RDS 实例。包含如下资源:
        • Database Parameter Group
        • Database 实例
      • app:应用相关资源。可用于自动构建缓存,应用及更新配置文件。包含如下资源:
        • Redis
        • Application Load Balancer
        • NAT
        • Route Table (给私有子网增加 NAT 路由)
        • Launch Template
        • Auto Scaling Group
        • Application Load Balancer
        • Listener, Target Group
        • 自动生成配置文件
        • S3FS 自动挂载到 EC2 作为 WordPress 的 Media Library

准备工作

      1. 本文使用 AWS China Region, 如使用 AWS Global Region,需要修改镜像地址和 region 信息。
      2. 提前提升好 limits. 每一项 AWS 服务都有 limits,确保灾备切换时,能否启动足够的资源来支撑应用。
      3. 本文架构部署使用 Terraform 一键部署AWS 资源, 请在本机安装 Terraform, 并配置好AWS Credentials
      4. Terraform 可以将信息存储在 S3 和 DynamoDB 中,创建用于存储 Terraform 状态的 S3 Bucket和 DynamoDB Table(由于使用的很少,DynamoDB 建议使用 On-Demand 收费方式), 该 DynamoDB 的 primary key 必须为 LockID,类型为 string。在本环境中,该 DynamoDB Table名称 为tf-state

        请勿在生产区域部署 S3, DynamoDB,防止 Region Down 之后,无法使用 Terraform。

      5. 在生产区域制作 AMI, 并拷贝到灾备区域。 出于演示的目的,已经提前在 AWS 中国区域部署了 WordPress 5.2.2 版本的AMI. WordPress 应用程序位 于 /var/www/html 目录下,可直接使用。
        • 北京区域 AMI: ami-0eebef1aaa174c852
        • 宁夏区域 AMI: ami-0cbbf10eaeaf0f9c3

        由于 WordPress 会记录域名,请勿使用ELB的域名直接访问, 为 WordPress 配置自定义域名。

      6. 将使用到的 SSL 证书提前导入 IAM。
      7. 修改 <project>/index.tf 和 <project>/variables.tf<project>代表basicdatabaseapp三个相应folder的泛指,请分别进行修改。
        • index.tf 是状态信息保存的地方, 需要使用到之前提到的 DynamoDB 和 S3。
        • variables.tf 是模板的变量, 根据实际情况修改。
      8. 配置好 AWS Credentials. 该 credentials 需要具备访问 S3, DynamoDB 及自动创建相关资源的权限。
      9. 中国大陆地区执行 terraform init 下载 aws provider 会比较慢,可提前手动下载, 并解压到<project>/.terraform/plugins/<arch>/ 目录下。<arch> 为本机的系统和CPU架构, 如 darwin_amd64linux_amd64。 >>>点击此处手动下载 Terraform AWS Provider<<<

详细步骤

1. (可选)创建模拟生产环境

如果对现有生产环境进行操作,直接跳过此步骤。

该步骤创建模拟的生产环境,用于演示。可以选择手动创建,或者利用脚本快速创建。使用脚本的好处是, 在演示结束后,我们可以快速销毁演示环境。 创建基础环境

      1. 修改 basic/variables.tf 和 basic/index.tf
      2. 在 basic 目录下执行 terraform init
      3. 执行 terraform workspace new prod 创建 模拟生产环境的 workspace. 我们使用 workspace 来区分是模拟生产环境或者灾备环境
      4. 执行 terraform apply 创建基础网络环境

创建数据库

      1. 修改 database/variables.tf 和 database/index.tf
      2. 在 database 目录下执行 terraform init
      3. 执行 terraform workspace new prod 创建 模拟生产环境的 workspace.
      4. 执行 terraform apply 创建数据库相关资源

创建应用层

      1. 在模拟生产区域创建 S3 Bucket, 并启用 versioning 功能,用于存储 WordPress media 文件
      2. 修改 app/variables.tf 和 app/index.tf
      3. 在 app 目录下执行 terraform init
      4. 执行 terraform workspace new prod 创建模拟生产环境的 workspace
      5. 执行 terraform apply 创建APP相关资源

2. 灾备环境准备工作

我们需要提前在灾备环境创建基础网络架构,来使得灾难发生时可以快速切换。在使用以下脚本的时候 注意参数的配置。推荐使用脚本创建,这样可以提高自动化的水平。 如果已经在创建模拟生产环境中修改了 index.tf 文件,无需修改该文件。 拷贝镜像

      1. 在生产区域中选择 EC2, 创建镜像文件
      2. 需要拷贝的镜像文件, 拷贝到灾备区域

创建基础环境

      1. 修改 basic/dr.tfvars 和 basic/index.tf
      2. 在 basic 目录下执行 terraform init
      3. 执行 terraform workspace new dr 创建灾备环境的 workspace. 我们使用 workspace 来区分是模拟生产环境或者灾备环境
      4. 执行 terraform apply --var-file=dr.tfvars 创建基础网络环境

S3 数据同步

      1. 在灾备区域中创建 S3 Bucket, 并启用 versioning 功能,用于备份 WordPress 的 Media 文件
      2. 利用 AWS CLI 将已存在的文件拷贝到灾备区域,aws s3 sync s3://SOURCE_BUCKET_NAME s3://TARGET_BUCKET_NAME
      3. 在 S3 Console 中选择生产区域的 S3 Bucket, 点击 Management, 选择 Replication
      4. 点击 Add Rule, 选择 Entire bucket, 并点击 Next
      5. 选择在灾备区域中选择的目标桶,点击 Next
      6. 在 IAM Role 中选择 Create new role, 输入 Rule name, 选择 Next。 
      7. 选择 Save 保存复制规则。

有关于开启 S3 Cross Region Replication 的更多资料,请参考这里

RDS 数据同步

      1. 在生产区域中选中 RDS 实例,点击右上角 Actions, 选择 Create read replica。 如果该按钮显示为灰色,请先 Take Snapshot, 等快照创建完毕后,再创建跨区域只读副本
      2. 在 Create read replica DB instance页面,选择 Destination region 为灾备区域, 选择 Destination DB subnet group 为 db-group(在 basic 模板中自动创建) 
      3. 根据需要,选择 instance class 和 Multi-AZ deployment
      4. 在 Settings 中 DB instance identifier 中输入数据库实例名称
      5. 其他设置保持默认, 选择 Create read replica,等待灾备区域的数据库实例启动完成
      6. 由于创建跨区域只读库无法选择安全组,因此我们需要手动跨区域只读节点的安全组。在 RDS Console 选择进入可读节点,选择右上角 Modify
      7. 在 Network & Security 选择 DB_SG(在 basic 模板中自动创建), 选择右下角 Continue 
      8. 在 Scheduling of modifications 选择 Apply immediately
      9. 选择 Modify DB Instance

修改灾备应用脚本启动参数

      1. 将跨区域只读库的 endpoint 更新到 app/dr.tfvars
      2. 修改 app/dr.tfvarsapp/index.tf(如之前未修改)
      3. 在 app 目录下执行 terraform init
      4. 执行 terraform workspace new dr 创建灾备环境的 workspace.

修改灾备脚本参数时,要谨慎核对参数。

3. 故障转移

强烈建议在完成数据同步之后,进行一次故障转移的演练。

在灾难发生后,执行故障转移, 请确保 app 目录下的 terraform workspace 是 dr。 可以通过 terraform workspace list 来确认当前 workspace, 或者通过 terraform workspcae select dr 来切换到 dr workspace。

      1. 执行 terraform apply --var-file=dr.tfvars 来启动资源
      2. 在 灾备区域 RDS Console 将 RDS Instance 提升为 master (可与上一步同时执行)。在灾备区域 RDS 控制台选择实例, 点击 Actions, 选择 Promote,在弹出的对话中选择 Continue 
      3. 测试。功能测试应该在之前测试过,这里主要测试连通性
      4. 切换 DNS

4. 灾后恢复

灾后恢复请务必咨询架构师!

      1. S3 的数据可以通过 AWS CLI Sync 命令来完成
      2. RDS 需要将原 region 的数据库拆除,并新建可读节点进行同步
      3. 找一个合适的时间,重启业务,让数据写入到原 region
      4. 切换DNS

5.(可选)销毁演示环境

可以通过以下步骤快速销毁演示环境。 销毁灾备环境 以下都是 dr terraform workspace

      1. 在灾备区域 AWS RDS 控制台删除数据库实例
      2. 在 app 目录下执行 terraform destroy --var-file=dr.tfvars
      3. 在 basic 目录下执行 terraform destroy --var-file=dr.tfvars, 请在数据库实例删除后执行

销毁演示生产环境 以下都是 prod terraform workspace, 可以通过 terraform workspace select prod 切换。

      1. 在 app 目录下执行 terraform destory
      2. 在 database 目录下执行 terraform destroy
      3. 在 basic 目录下执行 terraform destory

如需要,可手动删除 WordPress Media 文件 S3 Bucket, 以及 Terraform backend.

脚本故障排查

Terraform 故障排查 可以通过在 Terraform 命令之前添加环境变量,来使 Terraform 输出更多的日志信息来帮助故障排查,如:

TF_LOG=DEBUG terraform init

注意事项和RPO说明

      1. S3 Cross Region Replication是以异步复制的方式进行。大多数对象会在 15 分钟内复制, 但有时候可能需要两三个小时。极少数情况下,复制可能需要更长时间。因此,当进行灾难恢复时, 您需要关注部分没有得到复制的数据对您业务所造成的影响,并做出相应的调整。
      2. RDS Mysql Cross Region Replication采用异步复制的方式进行。Replica和Master之间 的lag主要取决于事务的大小以及Master负荷。当进行灾难恢复时,您需要关注没有得到复制的数据 对您业务所造成的影响。您可以自行检查数据表的情况进行了解,或者在 Amazon CloudWatch 中通 过查看 Amazon RDS ReplicaLag 监控指标来大致了解复制滞后的程度。
      3. 容灾方案中的Redis节点是冷启动,启动后内存中没有恢复已有缓存的数据。因此您需要关注灾难 恢复后数据库可能会遭受来自客户端重试导致瞬间的读写冲击。您应该在应用代码中实施类如熔断等机 制以减少冲击。
      4. 在本次方案中,您需要在灾难恢复时填写保存在宁夏区域的AMI ID,以作为AutoScaling Launch Template中EC2启动的镜像。如果您在北京区域对EC2进行了变更,请及时把北京区域的AMI复制到宁夏 区域,以保证宁夏区域的AMI保持最新状态。

总结

本文详细介绍了如何在AWS上实现跨区域的pilot light灾备方案,并提供了terraform模板进行可行性验证。在整个方案中,除了VPC预配置和RDS热备外,其余所有的组件 都是灾难发生后通过脚本动态创建,达到最小的Infra cost。当发生灾难时,用户通过预先定义好的灾备脚本,在灾备 区域快速构建 AWS 资源。

本篇作者

施乔

施乔,亚马逊 AWS 解决方案架构师,负责基于 AWS 的云计算方案的架构设计,在应用开发, Serverless, 大数据,IoT 方向有丰富的实践经验。

邱越俊

亚马逊AWS解决方案架构师,熟悉AWS 大数据和IOT平台的开发和使用,擅长数据分析、IOT架构和管理, 具有丰富的解决客户实际问题的经验。

王世帅

AWS解决方案架构师,负责基于 AWS 的云计算方案的咨询与架构设计,同时致力于 AWS 云服务在教育、医疗、媒体等行业的应用和推广。在互联网直播,OTT,企业数字化转型等领域有着广泛的设计与实践经验,对于人工智能,深度学习框架和应用等有浓厚的兴趣和热情。在加入AWS 之前曾在国航担任系统工程师,负责存储方案的架构设计,在企业混合 IT 等方面有丰富经验。