AWS Builder Center: Learn, Build and Connect with builders in the AWS community
AWS Builder Center is the official home for builders on AWS. Share and read what others are working on, follow people who inspire you, explore training and workshops, and find tools to support what you're building.
如何在 OpenSearch Service 中创建并计划手动快照?
我想为我的 Amazon OpenSearch Service 域创建手动快照。我还想定期自动运行该快照。
简短描述
要创建您的 OpenSearch Service 域的手动快照,请设置一个 Amazon Simple Storage Service (Amazon S3) 存储桶来存储快照数据。然后,将该 S3 存储桶注册为快照存储库。最后,使用已注册的存储库创建手动快照。您还可以使用 OpenSearch Dashboards 通过已注册的存储库创建快照。
要为 OpenSearch 2.1 以上的版本自动计划手动快照,请使用快照策略。对于早期的 OpenSearch 版本,请将 AWS Lambda 函数与 Amazon EventBridge 调度器结合使用。
解决方法
**注意:**如果您在运行 AWS 命令行界面 (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 网站上的 Take a snapshot(创建快照)。
创建快照后,您可以在 S3 存储桶中或通过 OpenSearch Dashboards 查看此快照。
计划自动手动快照
对于 OpenSearch 2.1 或更高版本,您可以使用 API 或 OpenSearch Dashboards,通过已注册的存储库创建快照策略。有关详细信息,请参阅 OpenSearch 网站上的 Snapshot management API(快照管理 API)和 Creating an SM policy(创建 SM 策略)。
对于 2.1 之前的 OpenSearch 版本,请完成以下步骤来计划手动快照:
- 如果您的 OpenSearch Service 域位于虚拟私有云 (VPC) 中,请在同一 VPC 中使用 Python 3.13 运行时创建一个新的 Lambda 函数。
- 将包含 requests-aws4auth 的 AWSSDKPandas-Python313 层添加到该函数中。有关详细信息,请参阅 AWS SDK for pandas 网站上的 AWS Lambda managed layers(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 调度器按计划调用 Lambda 函数。
(可选)删除不需要的快照
对于由快照策略创建的手动快照,请使用 max_age 参数或 Retention period(保留期)设置一个到期日期。有关详细信息和说明,请参阅 OpenSearch 网站上的 Parameters(参数)和 Creating an SM policy(创建 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 集群中的手动快照错误?
相关信息
- 语言
- 中文 (简体)
