使用 AWS Batch 自动备份 Amazon RDS for PostgreSQL 数据库实例 - AWS Prescriptive Guidance

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用 AWS Batch 自动备份 Amazon RDS for PostgreSQL 数据库实例

由 Kirankumar Chandrashekar (AWS)创建

环境:PoC 或试点

技术:容器和微服务;数据库; DevOps

工作负载:所有其他工作负载

AWS 服务:亚马逊 RDS;AWS Batch;亚马逊 CloudWatch;AWS Lambda;亚马逊 S3

总结

备份 PostgreSQL 数据库是一项重要的任务,通常可以使用pg_dump utility完成,该实用程序默认使用 COPY 命令创建 PostgreSQL 数据库的架构和数据转储。但是,如果您需要定期备份多个 PostgreSQL 数据库,则此进程可能会变得重复。如果您的 PostgreSQL 数据库托管在云端,您也可以利用Amazon Relational Database Service (Amazon RDS) 为 PostgreSQL 提供的自动备份功能。此示例介绍了如何使用 pg_dump 实用程序自动执行适用于 Amazon RDS for PostgreSQL 数据库实例的定期备份。

注意:这些说明假定您使用的是 Amazon RDS。但是,您也可以对托管在 Amazon RDS 外部的 PostgreSQL 数据库采用这种方法。若要进行备份,AWS Lambda 函数必须能访问您的数据库。

基于时间的亚马逊 CloudWatch 事件会启动 Lambda 函数,该函数搜索应用于 Amazon RDS 上 PostgreSQL 数据库实例元数据的特定备份标签。如果 PostgreSQL 数据库实例具有 bkp:AutomatedDBDump = Active标签和其他必要备份标签,则 Lambda 函数可为每份 AWS Batch 数据库提交单独作业。 

AWS Batch 会处理这些任务,并将备份数据上至到 Amazon Simple Storage Service(Amazon S3)存储桶。此模式使用 Dockerfile 和 entrypoint.sh 文件构建 Docker 容器映像,该映像用于在 AWS Batch 作业中进行备份。备份过程完成后,AWS Batch 会将备份详细信息记录至 Amazon DynamoDB 的库存表。作为一项额外的保护措施,如果任务在 AWS Batch 中失败, CloudWatch 事件事件会启动亚马逊简单通知服务 (Amazon SNS) Simple Notification Service 通知。 

先决条件和限制

先决条件

架构

技术堆栈

  • 亚马逊 CloudWatch 活动

  • Amazon DynamoDB

  • Amazon Elastic Container Registry (Amazon ECR)

  • Amazon RDS

  • Amazon SNS

  • Amazon S3

  • Amazon Batch

  • AWS Key Management Service(AWS KMS)

  • AWS Lambda

  • AWS Secrets Manager

  • Docker

工具

  • Amazon CloudWatch Ev CloudWatch ents — Events 提供近乎实时的系统事件流,这些事件描述了 AWS 资源的变化。

  • Amazon DynamoDB - DynamoDB 是一种全托管 NoSQL 数据库服务,提供快速而可预测的性能,能够实现无缝扩展。

  • Amazon ECR - Amazon Elastic Container Registry (Amazon ECR) 是一项安全、可靠且可扩展的 AWS 托管容器映像注册表服务。

  • Amazon RDS - Amazon Relational Database Service (Amazon RDS) 是一项 Web 服务,让用户能够在 Amazon Web Services Cloud 中轻松设置、操作和扩展关系数据库。

  • Amazon SNS - Amazon Simple Notification Service(Amazon SNS)是一项托管服务,提供从发布者至订阅用户的消息传输。

  • Amazon S3 – Amazon Simple Storage Service (Amazon S3) 是一项面向互联网的存储服务。

  • AWS Batch – AWS Batch 可帮助您在 AWS Cloud上运行批量计算工作负载。

  • AWS KMS - AWS Key Management Service(AWS KMS)是一项托管服务,可让您轻松创建和控制加密您的数据所用的加密密钥。

  • AWS Lambda – AWS Lambda 是一项计算服务,可使您无需预置或管理服务器即可运行代码。

  • AWS Secrets Manager - Secrets Manager 帮助您将代码中的硬编码凭证(包括密码)替换为对 Secrets Manager 的 API 调用,以便以编程方式检索密钥。

  • Docker - Docker 有助于开发人员轻松打包、交付和运行任何应用程序,将其作为轻量级、便携且自给自足的容器。

您在 Amazon RDS 上的 PostgreSQL 数据库实例必须为其元数据应用标签。Lambda 函数搜索标签以识别应备份的数据库实例,这通常使用以下标签。

标签

描述

bkp:AutomatedDBDump = Active

将 Amazon RDS 数据库实例标识为备份候选实例。

bkp: = AutomatedBackupSecret <secret_name >

标识 Secrets Manager 密钥,其中包含 Amazon RDS 登录凭证。

bkp:AutomatedDBDumpS3Bucket = <s3_bucket_name>

标识要向其发送备份的目标 S3 存储桶。

bkp: automatedDB DumpFrequency

bkp: automatedDB DumpTime

确定数据库备份的频率和时间。 

bkp:pgdumpcommand = <pgdump_command>

标识需要对其执行备份的数据库。

操作说明

任务描述所需技能
在 DynamoDB 中创建表。

登录 Amazon Web Services Management Console,打开 Amazon DynamoDB 控制台,然后创建表。要获取有关此操作和其他操作的帮助,请参阅相关资源部分。

云管理员、数据库管理员
确认已创建表格。

运行 aws dynamodb describe-table --table-name <table-name> | grep TableStatus命令。如果该表存在,则该命令将返回 "TableStatus": "ACTIVE",结果。

云管理员、数据库管理员
任务描述所需技能
创建 SNS 主题。

打开 Amazon SNS 控制台,选择主题,然后创建名为 JobFailedAlert的 SNS 主题。以有效电子邮箱地址订阅此主题,并查看您的电子邮件收件箱以确认来自 AWS Notifications 的 SNS 订阅电子邮件。

云管理员
为 AWS Batch 创建失败作业事件规则。

打开 Amazon CloudWatch 控制台,选择事件,然后选择创建规则。选择显示高级选项,并选择编辑。对于构建模式,选择按您的目标处理的事件,将现有文本替换为其他信息部分的“失败作业事件”代码。此代码定义了在 A CloudWatch WS Batch 有Failed事件时启动的事件规则。

云管理员
添加事件规则目标。

目标中,选择添加目标,然后选择 JobFailedAlertSNS 主题。配置其余详细信息,并创建 Cloudwatch Events 规则。

云管理员
任务描述所需技能
创建 Amazon ECR 存储库。

打开 Amazon ECR 控制台,选择要在其中创建存储库的 Amazon Web Services Region。选择存储库,然后选择创建存储库。根据要求配置存储库。

云管理员
撰写 Dockerfile。

登录 Docker,使用 其他信息 部分中的 “示例 Dockerfile” 和 “样本 entrypoint.sh 文件”构建 Dockerfile。

DevOps 工程师
创建 Docker 映像并将其推送到 Amazon ECR 存储库。

将 Dockerfile 构建至 Docker 映像,并将其推送至 Amazon ECR 存储库。有关此步骤的帮助,请参阅相关资源部分。

DevOps 工程师
任务描述所需技能
创建 AWS Batch 作业定义。

打开 AWS Batch 控制台,创建作业定义,其将 Amazon ECR 存储库的 Uniform Resource Identifier (URI) 包含为Image属性。

云管理员
配置 AWS Batch 作业队列。

在 AWS Batch 控制台,选择作业队列,然后选择创建队列。创建作业存储队列,直至 AWS Batch 在您的计算环境资源中运行这些任务。重要提示:请务必为 AWS Batch 编写逻辑,以将备份详细信息记录至 DynamoDB 清单表。

云管理员
任务描述所需技能
创建 Lambda 函数以搜索标签。

创建 Lambda 函数,用于在您的 PostgreSQL 数据库实例上搜索标签并识别备用备份。确保您的 Lambda 函数可以识别 bkp:AutomatedDBDump = Active标签和所有其他必需的标签。重要提示:Lambda 函数还必须能够将任务添加至 AWS Batch 作业队列中。

DevOps 工程师
创建基于时间 CloudWatch 的事件事件。

打开 Amazon CloudWatch 控制台并创建一个 CloudWatch 事件事件,该事件使用 cron 表达式定期运行您的 Lambda 函数。重要提示:所有计划的事件都使用 UTC 时区。

云管理员
任务描述所需技能
创建 Amazon KMS 密钥。

打开 Amazon KMS 控制台并创建 KMS 密钥,该密钥可用于加密存储在 AWS Secrets Manager 中的 Amazon RDS 证书。

云管理员
创建 AWS Secrets Manager 密钥。

打开 AWS Secrets Manager 控制台,将您的 Amazon RDS for PostgreSQL 数据库证书存储为机密。

云管理员
向 PostgreSQL 数据库实例添加所需的标签。

打开 Amazon RDS 控制台,为要自动备份的 PostgreSQL 数据库实例添加标签。您可以使用工具部分表格中的标签。如果您需要从同一 Amazon RDS 实例中的多个 PostgreSQL 数据库进行备份,请使用-d test:-d test1作为bkp:pgdumpcommand标签值。重要提示: testtest1是数据库名称。确保冒号 (:) 后没有空格。

云管理员
验证备份自动化。

若要验证备份自动化,您可以调用 Lambda 函数或等待备份计划开始。备份过程完成后,请检查 DynamoDB 清单表中是否包含适用于PostgreSQL 数据库实例的有效备份条目。如果其匹配,则表示备份自动化过程成功。

云管理员

相关资源

在 DynamoDB 中创建清单表

 

在 AWS Batch 中为失败作业事件创建 SNS 主题

 

推送 Docker 映像到 Amazon ECR 存储库

 

创建 AWS Batch 组件

 

创建 Lambda 函数

 

创建 CloudWatch 活动事件

 

测试备份自动化

其他信息

失败作业事件:

{ "detail-type": [ "Batch Job State Change" ], "source": [ "aws.batch" ], "detail": { "status": [ "FAILED" ] } }

示例 Dockerfile:

FROM alpine:latest RUN apk --update add py-pip postgresql-client jq bash && \ pip install awscli && \ rm -rf /var/cache/apk/* ADD entrypoint.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"]

entrypoint.sh 文件示例:

#!/bin/bash set -e DATETIME=`date +"%Y-%m-%d_%H_%M"` FILENAME=RDS_PostGres_dump_${RDS_INSTANCE_NAME} FILE=${FILENAME}_${DATETIME} aws configure --profile new-profile set role_arn arn:aws:iam::${TargetAccountId}:role/${TargetAccountRoleName} aws configure --profile new-profile set credential_source EcsContainer echo "Central Account access provider IAM role is: " aws sts get-caller-identity echo "Target Customer Account access provider IAM role is: " aws sts get-caller-identity --profile new-profile securestring=$(aws secretsmanager get-secret-value --secret-id $SECRETID --output json --query 'SecretString' --region=$REGION --profile new-profile) if [[ ${securestring} ]]; then echo "successfully accessed secrets manager and got the credentials" export PGPASSWORD=$(echo $securestring | jq --raw-output | jq -r '.DB_PASSWORD') PGSQL_USER=$(echo $securestring | jq --raw-output | jq -r '.DB_USERNAME') echo "Executing pg_dump for the PostGres endpoint ${PGSQL_HOST}" # pg_dump -h $PGSQL_HOST -U $PGSQL_USER -n dms_sample | gzip -9 -c | aws s3 cp - --region=$REGION --profile new-profile s3://$BUCKET/$FILE # in="-n public:-n private" IFS=':' list=($EXECUTE_COMMAND); for command in "${list[@]}"; do echo $command; pg_dump -h $PGSQL_HOST -U $PGSQL_USER ${command} | gzip -9 -c | aws s3 cp - --region=$REGION --profile new-profile s3://${BUCKET}/${FILE}-${command}".sql.gz" echo $?; if [[ $? -ne 0 ]]; then echo "Error occurred in database backup process. Exiting now....." exit 1 else echo "Postgresql dump was successfully taken for the RDS endpoint ${PGSQL_HOST} and is uploaded to the following S3 location s3://${BUCKET}/${FILE}-${command}.sql.gz" #write the details into the inventory table in central account echo "Writing to DynamoDB inventory table" aws dynamodb put-item --table-name ${RDS_POSTGRES_DUMP_INVENTORY_TABLE} --region=$REGION --item '{ "accountId": { "S": "'"${TargetAccountId}"'" }, "dumpFileUrl": {"S": "'"s3://${BUCKET}/${FILE}-${command}.sql.gz"'" }, "DumpAvailableTime": {"S": "'"`date +"%Y-%m-%d::%H::%M::%S"` UTC"'"}}' echo $? if [[ $? -ne 0 ]]; then echo "Error occurred while putting item to DynamoDb Inventory Table. Exiting now....." exit 1 else echo "Successfully written to DynamoDb Inventory Table ${RDS_POSTGRES_DUMP_INVENTORY_TABLE}" fi fi done; else echo "Something went wrong {$?}" exit 1 fi exec "$@"