Help us improve the AWS re:Post Knowledge Center by sharing your feedback in a brief survey. Your input can influence how we create and update our content to better support your AWS journey.
我該如何在 OpenSearch Service 上建立並排程手動快照?
我想為 Amazon OpenSearch Service 網域建立手動快照。我也想要定期自動執行該快照。
簡短描述
若要建立 OpenSearch Service 網域的手動快照,請先設定一個 Amazon Simple Storage Service (Amazon S3) 儲存貯體來存放快照資料。接著,將 S3 儲存貯體註冊為快照儲存庫。最後,使用已註冊的儲存庫來建立手動快照。您也可以使用 OpenSearch Dashboards,透過已註冊的儲存庫來擷取快照。
若要對 OpenSearch 2.1 以上的版本自動排程手動快照,請使用快照政策。對於較舊版本的 OpenSearch,請搭配 AWS Lambda 函式與 Amazon EventBridge Scheduler 使用。
解決方法
**注意:**如果您在執行 AWS Command Line Interface (AWS CLI) 命令時收到錯誤訊息,請參閱對 AWS CLI 錯誤進行疑難排解。此外,請確定您使用的是最新的 AWS CLI 版本。
先決條件:
- 您的網域需執行 OpenSearch 1.0 以上的版本。
- 您的使用者或角色的 AWS Identity and Access Management (IAM) 政策擁有管理儲存貯體所需的 CreateBucket 和 PutBucketPolicy 權限。
- 您的使用者或角色的 IAM 政策擁有建立 IAM 政策與角色所需的 IAMFullAccess 權限。
- 您的使用者或角色的 IAM 政策擁有註冊儲存庫所需的 ESHttpPut 權限。
設定 S3 儲存貯體
請完成下列步驟:
-
在與您的 OpenSearch Service 網域相同的 AWS 區域建立新儲存貯體。
-
使用 IAM 主控台 或 AWS CLI 建立 IAM 政策,授予存取 S3 儲存貯體所需的權限。
範例政策:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetBucketLocation" ], "Resource": [ "arn:aws:s3:::your-bucket-name" ] }, { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject", "iam:PassRole" ], "Resource": [ "arn:aws:s3:::your-bucket-name/*" ] } ] }**注意:**將 your-bucket-name 替換為您的儲存貯體名稱。
-
使用 IAM 主控台 或 AWS CLI 為 OpenSearch Service 建立 IAM 角色。
下列範例 create-role 命令會建立名為 TheSnapshotRole 的角色,並附加信任政策到該角色:aws iam create-role --role-name TheSnapshotRole --assume-role-policy-document '{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "opensearchservice.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }' -
使用 IAM 主控台 或 AWS CLI,將 Amazon S3 存取政策附加到角色。
-
使用 IAM 主控台 或 AWS CLI 建立具有 iam:PassRole 權限的政策。
範例政策:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iam:PassRole", "Resource": "arn:aws:iam::account-id:role/TheSnapshotRole" }, { "Effect": "Allow", "Action": "es:ESHttpPut", "Resource": "arn:aws:es:region:account-id:domain/domain-name/*" } ] }**注意:**將 account-id 替換為您的 AWS 帳戶 ID,將 region 替換為您的區域,並將 domain-name 替換為您的 OpenSearch Service 網域名稱。
-
執行下列 attach-user-policy 命令,將 iam:PassRole 政策附加至您設定用來使用 AWS CLI 的 IAM 使用者:
aws iam attach-user-policy --user-name YOUR_IAMUSERNAME --policy-arn arn:aws:iam::account-id:policy/PassRolePolicy**注意:**將 YOUR_IAMUSERNAME 替換為使用者名稱,並將 account-id 替換為您的帳戶 ID。
註冊快照儲存庫
若要註冊快照儲存庫,您必須使用 AWS 第 4 版簽署程序進行請求簽章。儲存庫名稱不能以 cs 開頭。此外,不建議從多個網域寫入同一儲存庫。設定為僅一個網域對儲存庫具有寫入權限。
在 Lambda 中使用 Python 註冊快照儲存庫。或者,若要使用 awscurl 與 AWS CLI 註冊快照儲存庫,請在您的執行個體上執行以下命令:
read -r ACCESS_KEY SECRET_KEY SESSION_TOKEN <<< $(aws sts get-session-token --query 'Credentials.[AccessKeyId,SecretAccessKey,SessionToken]' --output text) awscurl \ --access_key $ACCESS_KEY \ --secret_key $SECRET_KEY \ --session_token $SESSION_TOKEN \ --region us-west-2 \ --service es \ -X PUT \ -H "Content-Type: application/json" \ 'domain-endpoint/_snapshot/my-snapshot-repo' \ -d '{ "type": "s3", "settings": { "bucket": "bucketname", "region": "us-west-2", "role_arn": "arn:aws:iam::account-id:role/TheSnapshotRole" } }'
**注意:**將 my-snapshot-repo 替換為您的儲存庫名稱,將 bucketname 替換為您的儲存貯體名稱,並將 us-west-2 替換為您的區域。同時,將 domain-endpoint 替換為您的 OpenSearch Service 網域端點,將 account-id 替換為您的帳戶 ID,並將 TheSnapshotRole 替換為您的角色名稱。
若要安裝 awscurl,請執行以下命令:
pip install awscurl
如需更多資訊,請參閱 GitHub 網站上的 awscurl。
建立手動快照
使用 curl 命令擷取 OpenSearch Service 網域的手動快照。對於 OpenSearch 2.5 或更新版本,您可以使用 OpenSearch Dashboards。如需操作說明,請參閱 OpenSearch 網站上的擷取快照。
建立快照後,您可以在 S3 儲存貯體或透過 OpenSearch Dashboards 查看快照。
排程自動手動快照
對於 OpenSearch 2.1 或更新版本,您可以使用 API 或 OpenSearch Dashboards,透過已註冊的儲存庫建立快照政策。如需更多資訊,請參閱 OpenSearch 網站上的快照管理 API 以及建立 SM 政策。
對於 OpenSearch 2.1 之前的版本,請完成以下步驟來排程手動快照:
- 若您的 OpenSearch Service 網域位於虛擬私有雲端 (VPC),請在相同 VPC 中使用 Python 3.13 執行時期建立新的 Lambda 函式。
- 將包含 requests-aws4auth 的 AWSSDKPandas-Python313 層加入函式。如需更多資訊,請參閱 AWS SDK for pandas 網站上的 AWS Lambda 受管層,以及 Python 網站上的 requests-aws4auth。
- 在 Lambda 函式中輸入以下程式碼:
**注意:**將 domain-endpoint 替換為您的網域端點,但不要包含 https://。同時,將 my-snapshot-repo 替換為您的快照儲存庫,並將 us-west-2 替換為您的區域。import json import boto3 import requests from requests_aws4auth import AWS4Auth from datetime import datetime def lambda_handler(event, context): # OpenSearch endpoint and repository details host = 'domain-endpoint' repository = 'my-snapshot-repo' snapshot = f"snapshot-{datetime.now().strftime('%Y%m%d%H%m%S')}" region = 'us-west-2' service = 'es' # Get AWS credentials credentials = boto3.Session().get_credentials() awsauth = AWS4Auth( credentials.access_key, credentials.secret_key, region, service, session_token=credentials.token ) # API endpoint for creating snapshot url = f'https://{host}/_snapshot/{repository}/{snapshot}' # Snapshot creation parameters payload = { "indices": "*", "ignore_unavailable": True, "include_global_state": False } try: # Make the request response = requests.put( url, auth=awsauth, json=payload, headers={"Content-nt-Type": "application/json"} ) # Check if request was successful if response.status_code == 200: return { 'statusCode': 200, 'body': json.dumps({ 'message': 'Snapshot creation initiated successfully', 'snapshot_name': snapshot, 'response': response.json() }) } else: return { 'statusCode': response.status_code, 'body': json.dumps({ 'message': 'Failed to create snapshot', 'error': response.text }) } except Exception as e: return { 'statusCode': 500, 'body': json.dumps({ 'message': 'Error creating snapshot', 'error': str(e) }) } - 將以下權限附加至與 Lambda 函式關聯的角色:
**注意:**將 region 替換為您的區域,將 account-id 替換為您的帳戶 ID,將 my-snapshot-repo 替換為您的儲存庫名稱,並將 domain-name 替換為您的網域。{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "es:ESHttpPut", "es:DescribeElasticsearchDomain" ], "Resource": "arn:aws:es:region:account-id:domain/domain-name/*" } ] } - 使用 EventBridge Scheduler 依排程調用 Lambda 函式。
(選用) 刪除不需要的快照
對於由快照政策建立的手動快照,使用 max_age 參數或保留期間設定到期日期。如需更多資訊與操作說明,請參閱 OpenSearch 網站上的參數以及建立 SM 政策。
如果 Lambda 函式建立了手動快照,那麼您無法設定到期選項。請改用另一個 Lambda 函式刪除 OpenSearch 快照。
以下 Lambda 函式會刪除超過 30 天的 OpenSearch 快照:
import json import boto3 import requests from requests_aws4auth import AWS4Auth from datetime import datetime, timedelta import re def parse_date_from_snapshot_name(snapshot_name): # Pattern for format: snapshot-YYYY-MM-DDtHH-MM-SS try: # Skip "snapshot-" prefix and parse the date part date_str = snapshot_name[9:] # Remove "snapshot-" return datetime.strptime(date_str, '%Y-%m-%dt%H-%M-%S') except (ValueError, IndexError): return None def lambda_handler(event, context): # OpenSearch endpoint and repository details host = 'domain-endpoint' repository = 'my-snapshot-repo' region = 'us-west-2' service = 'es' # Get AWS credentials credentials = boto3.Session().get_credentials() awsauth = AWS4Auth( credentials.access_key, credentials.secret_key, region, service, session_token=credentials.token ) try: # First, get all snapshots list_url = f'https://{host}/_snapshot/{repository}/_all' list_response = requests.get( list_url, auth=awsauth, headers={"Content-Type": "application/json"} ) if list_response.status_code != 200: raise Exception(f"Failed to list snapshots: {list_response.text}") response_data = list_response.json() snapshots = response_data.get('snapshots', []) current_time = datetime.now() deletion_results = [] # Process each snapshot for snapshot in snapshots: snapshot_name = snapshot.get('snapshot') try: snapshot_date = parse_date_from_snapshot_name(snapshot_name) if snapshot_date and (current_time - snapshot_date).days > 30: # Delete snapshot delete_url = f'https://{host}/_snapshot/{repository}/{snapshot_name}' delete_response = requests.delete( delete_url, auth=awsauth, headers={"Content-Type": "application/json"} ) deletion_results.append({ 'snapshot': snapshot_name, 'status': 'deleted' if delete_response.status_code == 200 else 'failed', 'response': delete_response.text }) else: deletion_results.append({ 'snapshot': snapshot_name, 'status': 'skipped', 'reason': 'Not older than 30 days or date not found in name' }) except Exception as e: deletion_results.append({ 'snapshot': snapshot_name, 'status': 'error', 'error': str(e) }) return { 'statusCode': 200, 'body': json.dumps({ 'message': 'Snapshot deletion process completed', 'results': deletion_results }) } except Exception as e: return { 'statusCode': 500, 'body': json.dumps({ 'message': 'Error in snapshot deletion process', 'error': str(e) }) }
**注意:**將 domain-endpoint 替換為您的網域端點,但不要包含 https://,將 region 替換為您的區域,並將 my-snapshot-repo 替換為您的儲存庫名稱。最佳實務是將 Lambda 函式逾時設定為 60 秒。
對問題進行疑難排解
根據您收到的錯誤,採取以下動作。
「No permissions for [cluster:admin/snapshot/create]」錯誤
如果您在 OpenSearch Service 網域啟用了精細存取控制,則必須授予 Lambda 函式角色對 OpenSearch Service 的存取權。若未授予存取權限,那麼您將收到以下權限錯誤:
「"statusCode": 403, "body": "{"message": "Failed to create snapshot", "error": "{\"error\":{\"root_cause\":[{\"type\":\"security_exception\",\"reason\":\"no permissions for [cluster:admin/snapshot/create] and User [name=arn:aws:iam::123456789012:role/service-role/Lambda_ES_Snapshot-role」
若要解決此問題,請執行下列命令,以授予 Lambda 函式角色對 OpenSearch Service 的存取權:
awscurl \ --access_key ABCDE \ --secret_key EXAMPLESECRET\ --region us-west-2 \ --service es \ -X PUT \ -H "Content-Type: application/json" \ 'https://domain-endpoint/_plugins/_security/api/rolesmapping/all_access' \ -d '{"backend_roles": ["arn:aws:iam::account-id:role/service-role/Lambda_AOS_Snapshot-role"], "hosts": [], "users": ["master-user", "arn:aws:iam::account-id:user/second-primary-user" ]}'
**注意:**將 ABCDE 替換為您的存取金鑰,將 EXAMPLESECRET 替換為您的密碼,並將 us-west-2 替換為您的區域。同時,將 domain-endpoint 替換為您的 OpenSearch Service 網域端點,將 account-id 替換為您的帳戶 ID,並將 Lambda_AOS_Snapshot-role 替換為您的 Lambda 函式角色。
「AccessDeniedException」錯誤
若您收到「AccessDeniedException」錯誤訊息,則必須為存取 S3 儲存貯體的 IAM 角色設定信任關係。若要對此問題進行疑難排解,請使用 IAM 政策模擬器來確定必須更新 IAM 政策的哪一部分。
「S3Exception」錯誤
若收到「S3Exception: The bucket is in region 'us-west-1'」錯誤訊息,則必須將儲存貯體移至與 OpenSearch Service 網域相同的區域。
「SignatureDoesNotMatch」錯誤
若您收到「SignatureDoesNotMatch」錯誤訊息,則表示您的 AWS 憑證已過期,或您在簽章中使用了錯誤資訊。請將 AWS 憑證保持在最新狀態,並確保簽章中的區域正確。
「not authorized to perform: iam:PassRole」錯誤
若您未使用 AWS 第 4 版簽署程序,那麼您將收到以下錯誤訊息:
「Message":"User: anonymous is not authorized to perform: iam:PassRole on resource: arn:aws:iam::account-id:role/TheSnapshotRole because no resource-based policy allows the iam:PassRole action」
若要對此錯誤進行疑難排解,請參閱為什麼當我嘗試存取 OpenSearch Service 叢集時,會收到「User: anonymous is not authorized」錯誤?
如需更多疑難排解資訊,請參閱如何解決 OpenSearch Service 叢集中的手動快照錯誤?
相關資訊
運用快照管理功能,使用 OpenSearch Service 擷取自動快照
- 語言
- 中文 (繁體)

相關內容
- 已提問 7 個月前
- 已提問 2 年前
AWS 官方已更新 5 個月前