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

阅读数:27 2019 年 11 月 7 日 08:00

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

作者:王宇

上一期我们讨论了如何在不关机的前提下实现 AWS 上实例的数据一致性快照问题,传送门:《如何使用 Amazon EC2 Systems Manager 自动创建数据一致的 EBS 快照 (Part 1)

在本文的介绍中,我们将共同探索如何利用 Amazon EC2 Systems Manager(SSM) 和 Microsoft VSS (Volume Shadow Copy Service) 来创建数据一致的 EBS 快照。

SSM + VSS 数据一致快照的原理

VSS (Volume Shadow Copy Service) 是一个 Windows 操作系统内置的服务,用来协调与 VSS 兼容的应用程序(如 SQL Server、Exchange Server 等)的备份工作,如冻结或释放这些应用程序的 I/O 操作等。

VSS 服务能够启动和监督副本拷贝的创建。“副本拷贝”是指一个逻辑卷在某一个时间点上的数据一致快照。比如:“C:”是一个逻辑卷,它与 EBS 快照不同。创建副本拷贝的步骤包括:

  • 请求方向 VSS 发出创建副本拷贝的请求。
  • VSS provider 创建并维护副本拷贝。
  • VSS 写入器(writer)保证数据的一致性。写入器负责在 VSS provider 创建副本拷贝之前固化临时数据并冻结 I/O 操作,并在 VSS provider 完成创建后释放 I/O 操作。通常情况下,会为每一个与 VSS 兼容的应用程序分配一个独立的写入器(writer)。

我们可以使用 Run Command 在 windows 实例中运行一个 PowerShell 脚本:

Java

复制代码
$EbsSnapshotPsFileName = "C:/tmp/ebsSnapshot.ps1"
$EbsSnapshotPs = New-Item -Type File $EbsSnapshotPsFileName -Force
Add-Content $EbsSnapshotPs '$InstanceID = Invoke-RestMethod -Uri http://169.254.169.254/latest/meta-data/instance-id'
Add-Content $EbsSnapshotPs '$AZ = Invoke-RestMethod -Uri http://169.254.169.254/latest/meta-data/placement/availability-zone'
Add-Content $EbsSnapshotPs '$Region = $AZ.Substring(0, $AZ.Length-1)'
Add-Content $EbsSnapshotPs '$Volumes = ((Get-EC2InstanceAttribute -Region $Region -Instance "$InstanceId" -Attribute blockDeviceMapping).BlockDeviceMappings.Ebs |? {$_.Status -eq "attached"}).VolumeId'
Add-Content $EbsSnapshotPs '$Volumes | New-EC2Snapshot -Region $Region -Description " Consistent snapshot of a Windows instance with VSS" -Force'
Add-Content $EbsSnapshotPs 'Exit $LastExitCode'

首先创建了一个名为“ebsSnapshot.ps1”的 PowerShell 脚本文件,脚本中为实例的每一个 EBS 卷创建一个快照。

Java

复制代码
$EbsSnapshotCmdFileName = "C:/tmp/ebsSnapshot.cmd"
$EbsSnapshotCmd = New-Item -Type File $EbsSnapshotCmdFileName -Force
Add-Content $EbsSnapshotCmd 'powershell.exe -ExecutionPolicy Bypass -file $EbsSnapshotPsFileName'
Add-Content $EbsSnapshotCmd 'exit $?'

再创建第二个名为“ebsSnapshot.cmd”脚本文件,用来执行之前创建的 PowerShell 脚本。

Java

复制代码
$VssScriptFileName = "C:/tmp/scriptVss.txt"
$VssScript = New-Item -Type File $VssScriptFileName -Force
Add-Content $VssScript 'reset'
Add-Content $VssScript 'set context persistent'
Add-Content $VssScript 'set option differential'
Add-Content $VssScript 'begin backup'
$Drives = Get-WmiObject -Class Win32_LogicalDisk |? {$_.VolumeName -notmatch "Temporary" -and $_.DriveType -eq "3"} | Select-Object DeviceID
$Drives | ForEach-Object { Add-Content $VssScript $('add volume ' + $_.DeviceID + ' alias Volume' + $_.DeviceID.Substring(0, 1)) }
Add-Content $VssScript 'create'
Add-Content $VssScript "exec $EbsSnapshotCmdFileName"
Add-Content $VssScript 'end backup'
$Drives | ForEach-Object { Add-Content $VssScript $('delete shadows id %Volume' + $_.DeviceID.Substring(0, 1) + '%') }
Add-Content $VssScript 'exit'

第三个名为“scriptVss.txt”的文件包含了 DiskShadow 命令。DiskShadow 是一个包含在 Windows Server 2008 及以上版本中的 VSS 工具。这个脚本在 EBS 上为每一个逻辑卷创建一个副本拷贝,再为这个 EBS 创建一个快照,最后删除副本拷贝来释放磁盘空间。

Java

复制代码
diskshadow.exe /s $VssScriptFileName
Exit $LastExitCode

最终,在脚本模式中来运行 DiskShadow 命令。

这个脚本将保存在一个新的 SSM Document 中并关联到一个维护窗口中,在每天的午夜时间在每一台标签“consistentsnapshot”等于“windowsvss”的实例上运行。

在 AWS console 中快速实践

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

a) VPC 和互联网网关

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

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

d) 创建一个安全组,来允许来自 internet 的 RDP 访问,稍后将要通过远程登录到这个 EC2 实例中

e) 在子网中使用 IAM 角色创建和启动一个 Windows 实例,并分配好安全组

f) 创建一个包含上面例子中脚本的 SSM document 文件,来创建数据一致 EBS 快照

g) 创建另一个 SSM document 文件,其中的脚本来恢复逻辑卷中的数据,这些脚本将在下面的章节中详细说明

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

  1. 创建一个 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

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

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

b) 在 Actions 中选择 Register targets

c) Owner information:WindowsVSS

d) Select targets by:Specifying tags

e) Tag Name:ConsistentSnapshot

f) Tag Value:WindowsVSS

g) 选择 Register targets

  1. 给 Maintenance Window 分配一个任务

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

b) 在 Actions 中选择 Register targets

c) 在 Document 中选择此前创建的用于创建 EBS 快照的 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 页面查看每一次任务的执行情况。

如何将逻辑卷恢复到数据一致状态

在本文上面的例子中,我们会注意到,在给 EBS 进行快照的脚本中,我们实际上是先使用 DiskShadow 进行了副本拷贝操作,这个操作中已经包含了对 I/O 操作的冻结和释放,在此之后再进行了 EBS 的快照操作。而在这两个操作之间的瞬间如果数据发生改变,那么 EBS 快照中的数据就可能不能保持数据一致状态。

解决这个问题有两个方向,其一是自己创建一个 VSS provider 来创建 EBS 快照,而不是使用 DiskShadow 采用的 windows 内置的 VSS provider 来执行,在自己创建的 VSS provider 中做到先创建 EBS 快照再释放 I/O 操作,来保持数据一致性。

本文会介绍另一个解决方向,就是检查在 EBS 快照中的每一个逻辑卷数据,如果发现数据不一致的情况,就将其恢复到此前的副本拷贝(副本拷贝中的数据被 VSS writer 保持了数据一致性)。

步骤如下:

  1. 在 EC2 console 中,选择 Instances

  2. 搜索获得 EBS 进行了快照的实例,注意这个实例所在的 AZ

  3. 选择 Snapshots

  4. 选择最新的快照,再选择 Actions,Create Volume

  5. 选择与此前相同的 AZ,然后选择 Create, Volumes

  6. 选择刚刚创建的 Volume,然后选择 Actions, Attach Volume

  7. 在 Instances 中选择进行了 EBS 快照的实例,然后选择 Attach

  8. 选择 Run Command, Run a command

  9. 在 Command document 中选择恢复 EBS 的脚本 Document,在 Target 中选择这个 Windows 实例,然后选择 Run

恢复 EBS 的脚本如下:

Java

复制代码
$OfflineDisks = (Get-Disk |? {$_.OperationalStatus -eq "Offline"})
foreach ($OfflineDisk in $OfflineDisks) {
Set-Disk -Number $OfflineDisk.Number -IsOffline $False
Set-Disk -Number $OfflineDisk.Number -IsReadonly $False
Write-Host "Disk " $OfflineDisk.Signature " is now online"
}
$ShadowCopyIds = (Get-CimInstance Win32_ShadowCopy).Id
Write-Host "Number of shadow copies found: " $ShadowCopyIds.Count
foreach ($ShadowCopyId in $ShadowCopyIds) {
"revert " + $ShadowCopyId | diskshadow
}
foreach ($OfflineDisk in $OfflineDisks) {
$CurrentSignature = (Get-Disk -Number $OfflineDisk.Number).Signature
if ($OfflineDisk.Signature -eq $CurrentSignature) {
Set-Disk -Number $OfflineDisk.Number -IsReadonly $True
Set-Disk -Number $OfflineDisk.Number -IsOffline $True
Write-Host "Disk " $OfflineDisk.Number " is now offline"
}
else {
Set-Disk -Number $OfflineDisk.Number -Signature $OfflineDisk.Signature
Write-Host "Reverting to the initial disk signature: " $OfflineDisk.Signature
}
}

通过比较,将数据不一致的逻辑卷恢复到了数据一致状态,这个 EBS 就回到了数据一致的状态。

本次的介绍就到这里。如对 AWS 混合云架构解决方案感兴趣,请联系我们:yuwangcn@amazon.com

作者介绍:

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

本文转载自 AWS 技术博客。

原文链接:
https://amazonaws-china.com/cn/blogs/china/how-to-use-amazon-ec2-systems-manager-to-automatically-create-consistent-ebs-snapshots-of-datapart-2/

欲了解 AWS 的更多信息,请访问【AWS 技术专区】

评论

发布