使用 AWS Batch 對適用於 PostgreSQL 資料庫執行個體的 Amazon RDS 進行備份 - AWS Prescriptive Guidance

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

使用 AWS Batch 對適用於 PostgreSQL 資料庫執行個體的 Amazon RDS 進行備份

由基蘭庫瑪 ‧ 錢德拉瑟卡 (AWS) 創作

環境:PoC 或試驗

技能:容器與微服務;資料庫;DevOps

工作負載:所有其他工作負載

AWS 服務:亞馬遜 RDS; AWS Batch; Amazon CloudWatch; Amazon S3

Summary

備份 PostgreSQL 資料庫是一項重要工作,通常可以使用pg_dump 公用程式,它會使用 COPY 命令建立 PostgreSQL 資料庫的結構描述和資料傾印。不過,如果您需要定期備份多個 PostgreSQL 資料庫,此程序可能會變得重複。此模式描述如何自動執行 PostgreSQL 資料庫執行個體的 Amazon Relations Database Service (Amazon RDS) 定期備份。 

以時間為基礎的 Amazon CloudWatch Events 件事件會啟動搜尋特定備份的 AWS Lambda 函數套用至中繼資料的標籤Amazon RDS 上的 PostgreSQL 資料庫執行個體。如果資料庫執行個體具有BKB:自動設定傾印 = 作用中標籤和其他必要的備份標籤,則 Lambda 函數會針對每個資料庫備份提交個別任務至 AWS Batch。 

AWS Batch 會處理這些任務,並將備份資料上傳至 Amazon Simple Storage Service (Amazon S3) 儲存貯體。此模式使用碼頭檔和 entrypoint.sh 檔案來建置用於在 AWS Batch 處理任務中進行備份的 Docker 容器映像。備份程序完成後,AWS Batch 會將備份詳細資訊記錄到 Amazon DynamoDB 上的庫存表中。作為額外的保護,當 AWS Batch 中的任務失敗時,CloudWatch Events 事件會啟動 Amazon Simple Notification Service (Amazon SNS) 通知。 

先決條件和限制

先決條件

Architecture

技術堆疊

  • Amazon CloudWatch Events

  • Amazon DynamoDB

  • Amazon Elastic Container Registry (Amazon ECR)

  • Amazon RDS

  • Amazon SNS

  • Amazon S3

  • AWS Batch

  • AWS Key Management Service (AWS KMS)

  • AWS Lambda

  • AWS Secrets Manager

  • Docker

Tools

  • Amazon CloudWatch Events— CloudWatch Events 會交付近乎即時的系統事件串流,描述 AWS 資源中的變更。

  • Amazon DynamoDB— DynamoDB 是完全受管的 NoSQL 資料庫服務,可提供快速且可預期的效能,以及無縫的可擴展性。

  • Amazon ECR— Amazon Elastic Container Registry (Amazon ECR) 是受管 AWS 容器映像登錄檔服務,具安全性、可擴展性和可靠性。

  • Amazon RDS— Amazon Relational Database Service (Amazon RDS) 是一項 Web 服務,可以讓 AWS 雲端中關聯式資料庫的設定、操作和擴展更加簡單。

  • Amazon SNS— Amazon Simple Notification Service (Amazon SNS) 是受管服務,可將訊息交付到訂閱者。

  • Amazon S3— Amazon Simple Storage Service (Amazon S3) 是網際網路儲存服務。

  • AWS Batch— AWS Batch 可協助您在 AWS 雲端上執行批次運算工作負載。

  • AWS KMS— AWS Key Management Service (AWS KMS) 是受管服務,可讓您輕鬆地建立和控制用於加密資料的加密金鑰。

  • AWS Lambda— Lambda 是一項運算服務,可協助您執行程式碼,無需佈建或管理伺服器。

  • AWS Secrets Manager— Secrets Manager 可協助您將程式碼中硬式編碼的登入資料 (包括密碼),改成以程式設計方法透過 API 呼叫 Secrets Manager 來擷取秘密。

  • Docker— Docker 可協助開發人員輕鬆打包、運送和執行任何應用程式,做為輕量型、可攜式和自給自足的容器。

Amazon RDS 上的 PostgreSQL 資料庫執行個體必須具有標籤套用至其中繼資料。Lambda 函數會搜尋標記以識別應該備份的資料庫執行個體,而且通常會使用下列標記。

標籤

描述

BKB:自動設定傾印 = 作用中

將 Amazon RDS 資料庫執行個體識別為備份的候選項。

BKB: 自動備份機密 = <secret_name >

識別包含 Amazon RDS 登入憑證的 Secrets Manager 密碼。

BKB:自動設定的 DDD 傾印 3 儲存貯體 = <s3_bucket_name>

識別要傳送備份的 S3 儲存貯體。

BKB: 自動設定 BTP 傾印頻率

BKB: 自動設定重疊時間

識別應備份資料庫的頻率和時間。 

bk: pgdump 指令 = <pgdump_command>

識別需要採取備份的資料庫。

Epics

任務描述所需技能
在 DynamoDB 中建立表格。

登入 AWS 管理主控台,然後開啟 Amazon DynamoDB 主控台,然後建立表格。如需此故事和其他故事的協助,請參閱 < 相關資源 > 一節。

Cloud 管理員
確認已建立表格。

運行「AWS 描述的表格-表格名稱 <table-name> | grep 表格狀態」命令。如果該表存在,該命令將返回「表狀態」:「作用中」, "結果。

Cloud 管理員
任務描述所需技能
建立 SNS 主題。

開啟 Amazon SNS 主控台,選擇「主題」,然後建立名稱為「JobFailedAlert」的 SNS 主題。訂閱主題的有效電子郵件地址,然後檢查您的電子郵件收件匣以確認來自 AWS 通知的 SNS 訂閱電子郵件。

Cloud 管理員
為 AWS Batch 建立失敗的工作事件規則。

開啟 Amazon CloudWatch 主控台,選擇「事件」,然後選擇「建立規則」。選擇「顯示進階選項」,然後選擇「編輯」。對於「建置模式,以選取要讓目標處理的事件」,以取代現有文字,以從 < 其他資訊 > 一節中的「失敗的工作事件」程式碼。此程式碼定義了 AWS Batch 發生「失敗」事件時啟動的 CloudWatch 事件規則。

Cloud 管理員
新增事件規則目標。

在 [目標] 中,選擇 [新增目標],然後選擇 [JobFailedAlert] SNS 主題。設定剩餘的詳細資料並建立 Cloudwatch 事件規則。

Cloud 管理員
任務描述所需技能
建立 Amazon ECR 儲存庫。

開啟 Amazon ECR 主控台,然後選擇要建立儲存庫的 AWS 區域。選擇「儲存庫」,然後選擇「建立儲存庫」。根據您的需求配置儲存庫。

Cloud 管理員
寫一個 Dockerfile。

登錄到 Docker,並使用「其他信息」部分中的「示例碼頭文件」和「示例 entrypoint.sh 文件」來構建一個碼頭文件。

DevOps 工程師
建立一個 Docker 影像並將其推送到 Amazon ECR 儲存庫。

將 Docker 檔案建置到 Docker 影像中,並將其推送到 Amazon ECR 儲存庫。如需此故事的說明,請參閱 < 相關資源 > 一節。

DevOps 工程師
任務描述所需技能
建立 AWS Batch 任務定義。

開啟 AWS Batch 主控台並建立作業定義,其中包含 Amazon ECR 存放庫的統一資源識別碼 (URI) 做為屬性「影像」。

Cloud 管理員
設定 AWS Batch 任務佇列。

在 AWS Batch 主控台上,選擇「Job 佇列」,然後選擇「建立佇列」。建立儲存作業的作業佇列,直到 AWS Batch 在運算環境中的資源上執行作業為止。重要:請務必撰寫 AWS Batch 的邏輯,將備份詳細資訊記錄到 DynamoDB 庫存表中。

Cloud 管理員
任務描述所需技能
建立 Lambda 函數以搜尋標籤。

建立 Lambda 函數,以在 PostgreSQL 資料庫執行個體上搜尋標籤,並識別備份候選項。確保您的 Lambda 函數可以識別「BKB:自動 DDBDump = 活動」標籤和所有其他必需的標籤。重要:Lambda 函數也必須能夠將工作新增至 AWS Batch 工作佇列。

DevOps 工程師
建立以時間為基礎的 CloudWatch 事件活動。

開啟 Amazon CloudWatch 主控台並建立使用 cron 運算式定期執行 Lambda 函數的 CloudWatch 事件事件。重要:所有排定的事件都使用 UTC 時區。

Cloud 管理員
任務描述所需技能
創建一個亞馬遜 KMS 密鑰。

開啟 Amazon KMS 主控台並建立可用於加密 AWS Secrets Manager 中儲存的 Amazon RDS 登入資料的 KMS 金鑰。

Cloud 管理員
建立 AWS Secrets Manager 秘密。

開啟 AWS Secrets Manager 主控台,並將您的 Amazon RDS for PostgreSQL 資料庫登入資料作為秘密存放。

Cloud 管理員
將所需的標籤新增至 PostgreSQL 資料庫執行個體。

開啟 Amazon RDS 主控台,並將標籤新增至您要自動備份的 PostgreSQL 資料庫執行個體。您可以在「工具」部分中使用表格中的標籤。如果您需要從同一個 Amazon RDS 執行個體內的多個 PostgreSQL 資料庫進行備份,請使用「-d test ፦d test1」作為「bk: pgdump命令」標籤的值。重要提示:「測試」和「test1」是數據庫名稱。確定冒號 (:) 之後沒有任何空格。

Cloud 管理員
驗證備份自動化。

若要確認備份自動化,您可以叫用 Lambda 函數,或等待備份排程開始。備份程序完成後,請檢查 DynamoDB 詳細目錄表格是否具有 PostgreSQL 資料庫執行個體的有效備份項目。如果它們相符,則備份自動化程序就會成功。

Cloud 管理員

在 DynamoDB 中建立詳細目錄表

 

在 AWS Batch 中為失敗的任務事件建立 SNS 主題

 

建立一個 Docker 影像並將之推送到 Amazon ECR 儲存庫

 

建立 AWS Batch 處理元件

 

建立 Lambda 函數

 

建立 CloudWatch Events 事件

 

測試備份自動化

其他資訊

失敗的工作事件:

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

範例 Dockerfile (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 "$@"