阿里云「飞天发布时刻」2024来啦!新产品、新特性、新能力、新方案,等你来探~ 了解详情
写点什么

构建自动化的 EBS 快照生命周期管理

  • 2019-10-17
  • 本文字数:6992 字

    阅读完需:约 23 分钟

构建自动化的 EBS 快照生命周期管理

一 、引言

数据是企业的核心财产之一,数据备份一直是运维人员关注的工作,传统 IDC 通过专业备份软件与备份设备完成数据的备份与存储,当企业进行数字化转型拥抱云计算平台,如何在云端进行数据备份是新的热门话题,AWS 提供 EBS(Elastic Block Storage) 卷快照的功能,并开放相应的 API (快照创建、删除等),本文将介绍如何在 AWS 北京区域和宁夏区域构建一个自动化的 EBS 存储卷快照生命周期管理方案。


(AWS 海外区域可以直接使用 EBS 快照生命周期管理功能,本文方案建议用于 AWS 北京区域和宁夏区域。文中代码仅用于指导 EBS 快照生命周期管理的创建,请在应用到生产环境前进行仔细评估、测试与修改)

二、方案说明

本方案将涉及 Amazon CloudWatch Event,AWS Lambda,Amazon DynamoDB,Amazon EBS 快照等服务,简要说明如下。


Amazon CloudWatch Events 提供近乎实时的系统事件流,该流描述 Amazon Web Services (AWS) 资源的变化。通过使用可快速设置的简单规则,您可以匹配事件并将事件路由到一个或多个目标函数或流。您还可以使用 CloudWatch Events 来计划使用 Cron 或 rate 表达式在某些时间自行触发的自动化操作。本方案中将使用 Cron 表达式在特定时间触发 Lambda 进行相应的动作。


AWS Lambda 是一项计算服务,可使您无需预配置或管理服务器即可运行代码。AWS Lambda 只在需要时执行您的代码并自动缩放,从每天几个请求到每秒数千个请求。您只需按消耗的计算时间付费 – 代码未运行时不产生费用。您只需要以 AWS Lambda 支持的一种语言 (目前为 Node.js、Java、C#、Go 和 Python) 提供您的代码。本方案中我们将使用 Python 通过 Lambda 完成 EBS 卷的创建、删除等操作。


Amazon DynamoDB 是一种完全托管的 NoSQL 数据库服务,提供快速而可预测的性能,能够实现无缝扩展。使用 DynamoDB,您可以免除操作和扩展分布式数据库的管理工作负担,因而无需担心硬件预置、设置和配置、复制、软件修补或集群扩展等问题。DynamoDB 可以从表中自动删除过期的项,从而帮助您降低存储用量,减少用于存储不相关数据的成本。


DynamoDB 流(DynamoDB Stream) 是一种有关 Amazon DynamoDB 表中的项目更改的有序信息流。当您对表启用流时,DynamoDB 将捕获有关对表中的数据项目进行的每项修改的信息。


DynamoDB 的生存时间 (DynamoDB TTL) 可以定义表中项目的过期时间,以便它们能够从数据库中自动删除。在表中启用 TTL 后,您可以为每个项目设置删除时间戳,使得只有相关的记录才能占用存储。DynamoDB 通常在过期 48 小时内删除已过期的项目。项目在过期后真正被删除的确切时间取决于工作负载的性质和表的大小。


本方案中将应用 DynamoDB TTL 功能以及 DynamoDB 流以自动删除过期的项目(DynamoDB 表中“一条”数据成为一个项目,即一个 item )并通过流触发 Lambda 完成快照删除的动作。


Amazon EBS 快照 是基于时间点的快照,快照属于增量 备份,这意味着仅保存设备上在最新快照之后更改的数据块。由于无需复制数据,这将最大限度缩短创建快照所需的时间和增加存储成本节省。删除快照时,只有该快照特有的数据会被删除。每个快照都包含将数据 (拍摄快照时存在的数据) 还原到新 EBS 卷所需的所有信息。


标签(Tag) 是一些充当元数据的词和短语,用于标识和组织 AWS 资源。标签限制随资源而有所不同,但大多数最多可以有 50 个标签。每个标签都包含一个键(Key) 和一个值(Value)。通过使用标签标记 AWS 资源,可以方便用户识别与管理资源,比如 EC2 实例可以使用 键为 Name 标签,以区分使用实例的项目或应用系统,又或是使用键为 Env 的标签,以区分是生产环境还是测试开发环境。


本方案中简单架构如下:



方案说明:


1、快照创建自动化:


(1)通过 Cloud Watch Event 计划任务设定事件触发时间,如每天 24 点( UTC +8)触发创建快照的 Lambda,我们将其命名为 ebs-kuaizhao。


(2)该 Lambda 将完成三个事情:首先获取需要对哪些卷进行快照,在此我们通过获取 EBS 卷是否带有一个键(Key)为 Snapshot 的标签(tag)的方式来决定是否对一个卷做快照。


(3)同时该 Lambda 对标记需要做快照的卷进行快照,并将快照的元数据信息(如快照 id,快照创建时间等信息)写入到一张 DynamoDB 的表中。该表将启用 TTL 功能及 DynamoDB 流功能。


本方案中表中一个项目通常会有 4 个字段,分别为 snapshot_id (作为主键),create_time,description,timestamp,ttl(该字段为 TTL 属性)。


2、快照删除自动化:


(1)如 1 中所说明,DynamoDB 的表启用了 TTL (生存时间)功能,生存时间可以设定为快照需要保留的时间,如 7 天,则该项目写入到表 7 天后将自动被删除,当表中的数据发生变化的时候,会自动向流中写入一条记录。


(2)DynamoDB 流触发负责删除快照的 Lambda,该 Lambda 读取流中记录中的信息,如果发现是一条删除表中项目的记录,则获取待删除的快照 id,然后删除对应的快照。


通过该方案,您只需要对需要打快照的 EBS 卷添加一个标签,创建快照的 Lambda 将自动识别并对其进行打快照,新增或者删除的卷也将被自动识别出。另外通过使用 DynamoDB 流及生存时间,简化了快照生命周期管理方式,如果不用该方式,通常需要定期检查存储快照信息的 DynamoDB 的表,比较当前时间与快照创建时间,需要遍历或者条件查询该表,若发现超过快照保存时间,则删除该快照并删除表中的该条记录,增加了代码复杂度。

三、如何构建

了解了方案的思路后,我们就可以动手构建了,同样我们将分为两个部分。


前提:


(1)对需要做快照的 EBS 卷打上标签,标签至少要有两组;


col 1col 2col 3
KeyValue说明
Name用户自定义,且为英文字母必须项,且 Key 为 Name,Value 内容为英文或者拼音,不能为中文字符
SnapshotSnapshot必须项,且 Key 为 Snapshot


1、快照创建自动化


创建 DynamoDB 表,登录 AWS Console,选择 DynamoDB,创建表。



本示例中表名为 EBS-Snapshot-Lifecycle,您可以按需要自定义表名,主键为 snapshot_id,您可以自定义主键键名,本例中使用 snapshot_id,若改为其他,请注意后面的示例代码中修改对应的调用。


启用 TTL 功能。




TTL 属性填 ttl,当然您可以自定义该字段名字,本例中后面代码中使用了 ttl 字段,并勾选 DynamoDB 流,选择继续。在该部分中,关于 DynamoDB 表的吞吐能力选择了默认,即读取容量为 5,写入容量为 5,关于容量配置参考文件[5]。



在概述部分,可以得到该 DynamoDB 表的 arn 以及流的 arn 信息,该部分会在后面创建 Lambda 策略时用到,先复制到文本文件中,便于后面使用。


创建 Lambda



本方案中使用 Python 3.6。



选择创建自定义角色,跳转到新界面,IAM



选择确定就可以编辑策略。



将如下内容贴到编辑框内,并将 Resource 中加粗部分(arn:aws-cn:dynamodb:cn-north-1:xxaccount-id-xxxx:table/EBS-Snapshot-Lifecycle)替换为刚刚创建的 DynamoDB 的表的 arn:


Json


{    "Version": "2012-10-17",    "Statement": [        {            "Sid": "VisualEditor0",            "Effect": "Allow",            "Action": [                "logs:CreateLogStream",                "dynamodb:PutItem",                "logs:PutLogEvents"            ],            "Resource": [              "arn:aws-cn:dynamodb:cn-north-1:xxaccount-id-xxxx:table/EBS-Snapshot-Lifecycle",                "arn:aws-cn:logs:*:*:*"            ]        },        {            "Sid": "VisualEditor1",            "Effect": "Allow",            "Action": [                "ec2:DescribeVolumes",                "ec2:CreateSnapshot"            ],            "Resource": "*"        },        {            "Sid": "VisualEditor2",            "Effect": "Allow",            "Action": "logs:CreateLogGroup",            "Resource": "arn:aws-cn:logs:*:*:*"        }    ]}
复制代码


右下角 选择 允许;


跳回刚才 Lambda 界面,看到角色已经配置好了。



选择“创建函数”。


添加 CloudWatch Events 触发器:



配置 CloudWatch Events 触发器。



其中计划表达式为:cron(0 16 ? * MON-SUN *)


表示每天北京时间 24 点触发,关于计划表达式的写法请参考文献[1].


接下来编辑 Lambda 代码,点击中间的 Lambda,下方将出现代码编辑器。



将原有代码删掉,将如下代码复制进去,标红部分改为自己的 DynamoDB 表名。(代码文件可在文后下载)


Python


import boto3import os,timefrom botocore.exceptions import ClientErrorfrom datetime import datetime, timedelta, timezone
client = boto3.client('ec2')ec2 = boto3.resource('ec2')ddb = boto3.resource('dynamodb')
# 'EBS-Snapshot-Lifecycle' is the table you store snapshot metadata, modify it to your own table nametable = ddb.Table('EBS-Snapshot-Lifecycle')
# set days to keep 快照保留周期DAYS_TO_RETAIN = 7
def lambda_handler(event, context):
os.environ['TZ'] = 'Asia/Shanghai' time.tzset() i=time.strftime('%X %x %Z')
# set volume id, get volume who has a tag-key is 'Snapshot' describe_volumes=client.describe_volumes( Filters=[ { 'Name': 'tag-key', 'Values': ['Snapshot', ]
} ] ) volume_id_list = [] for vol in describe_volumes['Volumes']: volume_id_list.append(vol.get('VolumeId'))
# set snapshot for volume_id in volume_id_list: volume = ec2.Volume(volume_id)
for tags in volume.tags: if(tags.get('Key') == 'Name'): volume_name = tags.get('Value') description = volume_name + ' volume snapshot is created at ' + i
try: response = client.create_snapshot( Description=description, VolumeId=volume_id) except: print('Create Snapshot occured error, Volume id is ' + volume_id) else: print('Snapshot is created succeed, Snapshot id is ' + response.get('SnapshotId'))
# write into DynanoDB table snapshot_id = response.get('SnapshotId') start_time = response.get('StartTime') ttl_time = int(start_time.timestamp()) + 86400 * DAYS_TO_RETAIN
try: table.put_item( Item={ 'snapshot_id': snapshot_id, 'create_time': start_time.astimezone(timezone(timedelta(hours=8))).strftime('%X %x %Z'), 'description': description, 'timestamp': int(start_time.timestamp()), 'ttl': ttl_time, } ) except: print('Write to DynanoDB Table occured error, snapshot id is ' + snapshot_id) else: print('Write to DynanoDB Table succeed, snapshot id is ' + snapshot_id)
复制代码


``


说明:


(1)将 11 行中的 table = ddb.Table(‘EBS-Snapshot-Lifecycle’) 中 EBS-Snapshot-Lifecycle 替换为前面创建的 DynamoDB 的表名;


(2)14 行中的 DAYS_TO_RETAIN = 7 表示快照保留的周期,上例中表示保存 7 天,您可以根据需要修改该值。


(3)27 行的 Snapshot 是标签的键的内容,即我们设定凡是有一个键名为 Snapshot 的标签的卷,我们就对其做快照。


在 Lambda 基本设置中,可以将内存设为 128 MB,超时设为 10 s (通常情况下,1 s 内可执行完该 Lambda 代码,关于这部分的配置请参考文献[4])。


最后选择右上方“保存”。


至此,完成快照创建自动化。


2、快照删除自动化


创建一个新的 Lambda,方法如上,本例中命名为 EBS_Snapshot_Delete,同样创建时选择“创建自定义角色”,并将如下策略替换进去,其中 Resource 中内容(arn:aws-cn:dynamodb:cn-north-1:xxxx–your-account-id-xxxxx:table/EBS-Snapshot-Lifecycle/stream/yyyy-mm-ddThh:mm:ss.uuu)全部替换为前面创建的 DynamoDB 表的流的 arn 信息(注意是流的 arn 不是表的 arn)。


Json


{    "Version": "2012-10-17",    "Statement": [        {            "Sid": "VisualEditor0",            "Effect": "Allow",            "Action": [                "logs:CreateLogStream",                "ec2:DeleteSnapshot",                "logs:CreateLogGroup",                "logs:PutLogEvents",                "dynamodb:ListStreams"            ],            "Resource": "*"        },        {            "Sid": "VisualEditor1",            "Effect": "Allow",            "Action": [                "dynamodb:GetShardIterator",                "dynamodb:DescribeStream",                "dynamodb:GetRecords"            ],            "Resource": "arn:aws-cn:dynamodb:cn-north-1:xxxx--your-account-id-xxxxx:table/EBS-Snapshot-Lifecycle/stream/yyyy-mm-ddThh:mm:ss.uuu"        }    ]}
复制代码


选择 DynamoDB 作为触发器。




选择前面创建的 DynamoDB 表,选择添加。


在 Lambda 代码部分,使用如下代码,代码文件可在文后下载。该部分代码主要读取流中的记录,对于表中项目删除事件( REMOVE)获取快照 id 信息,然后调用快照删除 API,删除对应的快照。


Python


import boto3from botocore.exceptions import ClientError
client = boto3.client('ec2')
def lambda_handler(event, context): #将event打印出,主要为了用于调试与排错 print(event)
snapshot_to_delete = []
for record in event['Records']: if(record['eventName'] == 'REMOVE'): snapshot_to_delete.append(record['dynamodb']['Keys']['snapshot_id']['S'])
for snapshot_id in snapshot_to_delete: try: response = client.delete_snapshot( SnapshotId=snapshot_id, ) except ClientError as e: if(e.response['Error']['Code'] == 'InvalidSnapshot.NotFound'): print(snapshot_id + ' is not founded') except: print('Delete snapshot occured error, snapshot id is ' + snapshot_id) else: print('Delete snapshot succeed, snapshot id is '+ snapshot_id)
复制代码


同样 Lambda 的配置可以选择 128 MB,超时设为 10 s (通常 1 s 内能够执行完)。


选择右上角“保存”。


至此完成快照自动删除功能的配置。


当自动创建快照触发时,会在 DynamoDB 的表中看到有项目出现。



以上方案是一个简单的快照自动创建与定期删除方案,可以用于 AWS EBS 卷的快照的生命周期管理(自动创建、删除),快照是针对存储卷在该时刻点的快照,在做快照的时候我们通常需要考虑到先将内存数据写入到磁盘中,或者在快照前将磁盘写 IO 暂停,以免出现数据不一致的问题。在应用该方案到生产环境之前建议做好测试与评估,并对示例代码做必要的修改。


四、总结

本方案通过使用 Amazon CloudWatch Events、AWS Lambda、 Amazon DynamoDB 等服务实现了一个无服务器架构的 EBS 卷生命周期管理,希望通过本文读者对以上服务有进一步直观的认识与了解。AWS 提供丰富的无服务器服务以及 API 接口,用户可以很容易的根据业务需求构建适合自己业务场景的解决方案。


另附 Lambda 代码下载:


ebs-snapshot-create.py


ebs-snapshot-delete.py


五、参考资料

[1] Amazon CloudWatch Events 规则的计划表达式: https://docs.aws.amazon.com/zh_cn/AmazonCloudWatch/latest/events/ScheduledEvents.html


[2] 配合使用 AWS Lambda 和 Amazon DynamoDB:https://docs.aws.amazon.com/zh_cn/lambda/latest/dg/with-ddb.html


[3] 使用 DynamoDB 流 捕获表活动:https://docs.aws.amazon.com/zh_cn/amazondynamodb/latest/developerguide/Streams.html


[4] 配置 Lambda 函数:https://docs.aws.amazon.com/zh_cn/lambda/latest/dg/resource-model.html


[5] DynamoDB 读取和写入吞吐容量: https://docs.aws.amazon.com/zh_cn/amazondynamodb/latest/developerguide/HowItWorks.ProvisionedThroughput.html


[6] Python Boto3:https://boto3.amazonaws.com/v1/documentation/api/latest/index.html


[7] DynamoDB 生成时间: https://docs.aws.amazon.com/zh_cn/amazondynamodb/latest/developerguide/TTL.html


作者介绍:


王世帅


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


本文转载自 AWS 技术博客。


原文链接:


https://amazonaws-china.com/cn/blogs/china/construct-ebs-life-circle-management/


2019-10-17 08:00592
用户头像

发布了 1835 篇内容, 共 92.1 次阅读, 收获喜欢 73 次。

关注

评论

发布
暂无评论
发现更多内容

超越卡顿,突破瓶颈!华为云耀L实例引领中小企业游戏开发新风潮

平平无奇爱好科技

智能选购、简便操作,华为云耀云服务器L实例为小程序开发降本增效

平平无奇爱好科技

华为云耀云服务器L实例,企业数字化转型的理想云服务器

平平无奇爱好科技

探索数字化转型之道,华为云这款服务器助您飞跃商业高峰

平平无奇爱好科技

拼多多根据ID取商品详情 API 的优势是什么?

技术冰糖葫芦

API 接口

高性能保障企业上云,华为云助力小程序开发稳步推进

平平无奇爱好科技

JetBrains PyCharm Pro 2023 v2023.3中文激活版

影影绰绰一往直前

Photoshop 2022 for mac(PS 2022)v23.5.2中文激活版

影影绰绰一往直前

iStat Menus for mac v6.73 (1230)中文版

iMac小白

突破游戏开发瓶颈,华为云耀云服务器L实例助您游刃有余

平平无奇爱好科技

企业级即时通讯系统的领跑者,WorkPlus引领沟通协作创新潮流

WorkPlus

Sketch for mac(专业矢量绘图设计软件)v99.1中文激活版

iMac小白

引领数字化新风潮,华为云耀云服务器L实例有什么卓越之处?

轶天下事

Acrobat Pro DC 2022 mac 中文破解版下载

iMac小白

MATLAB R2023b for Mac 中文激活版下载

影影绰绰一往直前

Studio One 6 Pro for mac(音乐创作编辑软件)v6.2.0永久激活版

影影绰绰一往直前

App Cleaner & Uninstaller for Mac v8.2.4中文激活版

影影绰绰一往直前

痛过才知道,企业上云为什么要选择华为云

平平无奇爱好科技

JetBrains DataGrip 2023 for Mac v2023.3中文激活版

影影绰绰一往直前

Microsoft Remote Desktop Beta mac中文激活版下载

影影绰绰一往直前

解锁数字化转型的钥匙,华为云耀云服务器L实例深度解析

平平无奇爱好科技

稳定可靠的数字之选,华为云耀云服务器L实例成初创企业理想云服务器

平平无奇爱好科技

如让企业轻松上云?华为云这款服务器帮你轻松搞定

轶天下事

SecureCRT for Mac v9.3.2激活版下载

iMac小白

JetBrains PhpStorm 2023 mac v2023.3中文激活版下载

影影绰绰一往直前

京东商品详情数据在数据分析行业中的重要性

tbapi

京东商品详情数据接口 京东API接口

After Effects 2024 mac v24.1中文激活版下载

影影绰绰一往直前

抖音商品详情API是什么?

技术冰糖葫芦

API 接口

KeyShot 2023 Pro mac v12.2.2.4激活版

iMac小白

Prism 10 for Mac v10.0.0.3注册激活版

影影绰绰一往直前

Azure RTOS ThreadX 系统分析之TraceX

SkyFire

TraceX ThreadX

构建自动化的 EBS 快照生命周期管理_语言 & 开发_亚马逊云科技 (Amazon Web Services)_InfoQ精选文章