HarmonyOS开发者限时福利来啦!最高10w+现金激励等你拿~ 了解详情
写点什么

构建自动化的 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:00704
用户头像

发布了 1848 篇内容, 共 114.0 次阅读, 收获喜欢 78 次。

关注

评论

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

如何进行Linux CPU中的Kernel space分析

百度搜索:蓝易云

鸿蒙NEXT开发案例:抛硬币

zhongcx

One Switch for Mac(系统功能快速开关工具)中文版

Mac相关知识分享

苹果电脑清除浏览器缓存和内存 macbook怎么清理浏览器缓存

阿拉灯神丁

浏览器 优化软件 缓存清除 CleanMyMac X中文版 mac 效率工具

ScrumMaster认证机构及CSM、PSM、RSM价值解析

ShineScrum捷行

Spring高手之路24——事务类型及传播行为实战指南

砖业洋__

spring 事务

Topaz Video AI for mac(专业性的视频增强软件)

Mac相关知识分享

中昊芯英斩获2024年第十九届“中国芯”最高奖“年度重大创新突破产品”

科技热闻

EndNote 21 for Mac专业文献管理工具

Mac相关知识分享

交互原型设计软件Axure RP 9 for Mac

Mac相关知识分享

ROS2:从初识到深入,探索机器人操作系统的进化之路

梦笔生花

机器人 DDS ROS2

Cornerstone for Mac(SVN管理工具)

Mac相关知识分享

深入解析京东商品详情数据API接口

代码忍者

API 接口 pinduoduo API

LED显示屏为什么要做老化测试

Dylan

产品 LED显示屏 全彩LED显示屏 led显示屏厂家 户内led显示屏

CST如何计算CMA中的模式加权系数MWC

思茂信息

cst cst使用教程 CST软件

怎么把苹果电脑里的文件拷贝到u盘 苹果电脑使用u盘注意事项

阿拉灯神丁

U盘启动盘 Tuxera NTFS2023 苹果电脑 NTFS 磁盘管理器 磁盘工具

Navicat Premium 16 for Mac多连接数据库管理工具

Mac相关知识分享

AirServer 7 for Mac(mac投屏软件)

Mac相关知识分享

Microsoft Excel 2019 for Mac(excel电子表格)中文版

Mac相关知识分享

CSS基础PHP如何对二维数组(多维数组)进排序

百度搜索:蓝易云

鸿蒙Navigation页面生命周期

龙儿筝

通过API接口探索电商平台商品详情:一站式接入指南

代码忍者

API 接口 pinduoduo API

git everything up-to-date解决方法

百度搜索:蓝易云

Linux arm64 set_memory_ro/rw函数

百度搜索:蓝易云

看板在项目管理中的应用场景及其核心优势

爱吃小舅的鱼

项目管理 可视化 项目管理看板

Redis Desktop Manager for mac( Redis 数据库管理工具)

Mac相关知识分享

Macos 的跨平台键鼠共享工具synergy for mac

Mac相关知识分享

鸿蒙自定义组件生命周期

龙儿筝

鸿蒙

《Django 5 By Example》阅读笔记:p1-p16

codists

Python django 编程人 codists

如何成为优秀的项目经理?核心职责与能力要求

爱吃小舅的鱼

项目管理 项目经理 项目规划

看板在项目管理中的应用:提高透明度与协作效率

爱吃小舅的鱼

项目管理 看板 项目管理看板

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