亚马逊AWS官方博客

如何使用Amazon EC2 Systems Manager自动创建数据一致的EBS快照(Part 1)

作者:王宇

关于Amazon EC2 Systems Manager(SSM)我们此前已经做过介绍,传送门:《Amazon EC2 Systems Manager让你轻松管理AWS混合云

当一个EC2实例在启动状态时,其上运行的如数据库等应用必然会有一些数据是保存在内存中,或是pending在数据存储阶段,这些数据都不能被EBS的快照检索到,因此这些数据也有可能无法从EBS的快照中恢复回来,从而导致应用数据的丢失。

Amazon EBS作为EC2的块级存储卷,可以创建时间点快照,并存放在S3存储中。在使用EBS的快照功能作为备份解决方案使用时,通常我们都不希望在打快照的过程中关闭EC2实例,因此我们需要创建一个数据一致的EBS快照,也就是说在打快照时通知正在运行的应用程序,让它们做好准备。

在本文中,我将介绍的内容就是利用Run Command和Maintenance Window这两个Amazon EC2 Systems Manager(SSM)的组件来完成自动创建数据一致的EBS快照工作。

使用Run Command创建数据一致的EBS快照

Run Command是一个安全的远程管理EC2实例的工具,例如远程在一个实例上执行命令或脚本,而不用登录到该实例上。当然,需要该实例事先安装好SSM Agent。

在本文的例子中,我们需要通过执行脚本命令来通知实例上的应用程序,再执行EBS快照的动作,顺序如下:

1.  发出命令给应用程序以及文件系统,使其将缓存中的数据固化到存储介质中去,然后暂时停止所有的I/O操作。此时,EBS存储处于数据一致的状态。

2.  使用元数据得到运行脚本的EC2实例ID。

3.  通过实例ID找到与其关联的所有EBS卷,并给这些卷打上快照。

4.  最后,在接到EC2 API对最后一个EBS快照命令的反馈之后,可以立即释放I/O操作控制,而不必等待最后一个EBS快照完成。

第一步中的脚本命令根据不同的操作系统和应用程序会有不同,在下面的一个例子中可以看到。

在这个过程中,EC2实例通过Run Command API来接收和执行脚本命令,并返回结果,而通过EC2 API来查找相关的EBS卷信息并给EBS打快照。因此我只需要在权限控制时创建一个Role,让这个Role具备AmazonEC2RoleforSSM这个policy以及ec2:DescribeInstanceAttribute和ec2:CreateSnapshot这两个action即可。使用这个Role来启动EC2实例。

使用Run Command进行操作的好处如下:

  • 脚本命令集中化管理,发生任何变化时可以立即应用到所有实例中去。
  • 命令可以安全地远程执行,甚至实例还可以连续不断的接收和执行新的命令。
  • 每个命令的执行情况和结果都能体现在Run Command报告中,这些信息也同样存储在AWS CloudTrail中便于审计。
  • Run Command与IAM集成,能够有效控制哪些用户可以访问以及用户的访问级别。

使用Maintenance Windows执行日常运维操作

Maintenance Windows可以定义一个重复的时间窗口,来执行Run Command中的命令脚本,从而达到自动执行日常运维操作的目的。那么我们就可以利用Maintenance Windows来创建一个非高峰时间的运行时间窗口来给EBS进行数据一致性快照操作。

在实际操作中,一个维护窗口可以与多个目标实例进行关联,可以把目标EC2实例用“ConsistentSnapshot”标签进行分组,再使用不同的标签值来区分每组实例应该执行什么样的脚本命令。每组目标上执行的命令都可以使用一个SSM document来进行描述,内容就包括使用Run Command在这组实例中进行数据一致的EBS快照操作。

举例:MySQL数据库在Amazon Linux实例上的数据一致快照

1.   使用Run Command在Amazon Linux实例上运行脚本:

mysql -u backup -h localhost -e ‘FLUSH TABLES WITH READ LOCK;’

这个脚本使MySQL数据库为备份做好准备。命令“FLUSH TABLES WITH READ LOCK”将等待所有活跃的事务运行结束,并将缓存中的数据固化至文件系统中去,并防止用户继续使用写操作。因此我们可以看到,这个方法会导致一个短暂的中断写操作,中断的时间取决于数据的大小和当前的负载情况,因此请注意在使用这个方法进行备份时尽量不要影响你的正常业务。

2.   暂停访问文件系统并在磁盘上创建一个镜像,在这个阶段,EBS卷处于数据一致的状态:

sync

for target in $(findmnt -nlo TARGET -t ext4); do fsfreeze -f

$target; done

3.   为每一个连接到该实例的EBS卷创建快照:

instance=`curl -s http://169.254.169.254/latest/meta-data/instance-id`

region=`curl -s 169.254.169.254/latest/meta-data/placement/availability-zone`

region=${region::-1}

volumes=`aws ec2 describe-instance-attribute --instance-id

$instance --attribute blockDeviceMapping --output text --query

BlockDeviceMappings[*].Ebs.VolumeId --region $region`


for volume in $(echo $volumes | tr " " "\n")

do aws ec2 create-snapshot --volume-id $volume --description

'Consistent snapshot of MySQL on Amazon Linux' --region $region >

/dev/null 2>&1

done

4.   释放文件系统和MySQL的写操作锁:

for target in $(findmnt -nlo TARGET -t ext4); do fsfreeze -u

$target; done

mysql -u backup -h localhost -e 'UNLOCK TABLES;'

我们可以把以上脚本内容保存到一个SSM document中,并在Maintenance Windows中定义一个每天晚上12点执行该document的时间窗口,再将执行目标关联至所有“ConsistentSnapshot”标签的数值为“AmazonLinuxMySQL”的EC2实例。

在AWS console中快速实践

1.  使用AWS CloudFormation快速创建一组资源,包括:

a)   VPC和互联网网关

b)   VPC中创建一个子网和一个新的路由表,来实现互联网连接和AWS APIs

c)   创建一个IAM角色来赋予EC2实例相应的权限

d)   在子网中使用IAM角色创建和启动一个Amazon Linux实例,并安装和配置好MySQL数据库和SSM Agent

e)   创建一个上面例子中的SSM document文件

f)   创建一个能够生成Maintenance Windows的IAM role

2.  创建一个Maintenance Window

a)   在EC2 Console中选择:Systems Manager Shared Resources -> Maintenance Windows -> Create a Maintenance Window

b)   Name:ConsistentSnapshots

c)   Specify with:CRON/Rate expression

d)   CRON/Rate expression:cron(0 0 * * ? *)

e)   Duration:2 hours

f)   Stop initiating tasks:0 hour

g)   选择Create maintenance window

3.  为Maintenance Window关联一组目标:

a)   在Maintenance Window列表中选择刚刚创建的维护窗口

b)   在Actions中选择Register targets

c)   Owner information:AmazonLinuxMySQL

d)   Select targets by:Specifying tags

e)   Tag Name:ConsistentSnapshot

f)   Tag Value:AmazonLinuxMySQL

g)   选择Register targets

4.  给Maintenance Window分配一个任务

a)   在Maintenance Window列表中选择刚刚创建的维护窗口

b)   在Actions中选择Register targets

c)   在Document中选择此前创建的SSM document文件名

d)   在Target by中选择刚刚创建的目标

e)   在Role中,选择在CloudFormation中创建的IAM Role

f)   在Execute on中,Targets:1,Stop after:1 errors

g)   选择Register task

运维窗口和一致性快照操作已经创建完毕,你可以在Maintenance Windows窗口中的History页面查看每一次任务的执行情况:

作者介绍:

王宇,AWS企业容灾解决方案业务拓展经理,目前负责AWS中国区的混合云、容灾和DevOps产品和解决方案。曾服务于VMware等传统私有云厂商,熟悉传统IT架构和私有云、混合云、公有云的解决方案融合。