工程

在 Elastic Cloud 上从 AWS Elasticsearch 迁移到 Elasticsearch 服务

访问 Elastic Stack 的所有功能

作为一名解决方案架构师,我经常被问到如何将 Elastic 部署从 Amazon Elasticsearch 服务(AWS ES) 转移到 Elasticsearch 服务。 我之所以被问及这个问题,主要是因为用户希望利用 Elastic 提供的所有功能、操作专长和支持,而这些都是 Amazon 无法提供的。本实践指南将带您从 Elastic 网站了解众所周知的“直接迁移”到 Elasticsearch 服务。

要开始使用 Elasticsearch 服务,我们有一个免费的 14 天试用允许您创建部署。您可以选择云提供商 AWS 或 GCP,以及希望 Elastic 在哪个地区运行您的部署。 AWS 用户可以直接从 AWS 市场添加 Elasticsearch 服务,相应费用将集成到您的 AWS 账单中。

我们在开源发行版的基础上增加了许多功能,如 CanvasAPM无监督 Machine Learning冻结索引SQL安全性(超越基本 IAM 策略防护和仅边界防护)和部署模板,这些都是 Elastic Cloud 上的 Elasticsearch 服务所独有的的。我们一直在增加更多独特的功能。要详细了解我们的服务与 AWS Elasticsearch 相比如何,请随时查看我们的 AWS Elasticsearch 比较页面

从 AWS Elasticsearch 迁移到 Elastic Cloud 上的 Elasticsearch 服务

本指南介绍了如何从 AWS ES 迁移到 Elastic Cloud上的 Elasticsearch 服务,具有较强的技术性,需要一些编程经验才能理解。AWS ES 集群通常被配置到 VPC,但是它们也可以被放在面向公众的端点上。为了使本指南在两种情况下通用,我们使用了 Python AWS 软件开发工具包。您可以使用任何具有 AWS SDK 的语言(例如,Java、Ruby、Go 等),不过下面只提供了以 Python 编写的示例。

本指南分为两部分:

注意:如果您已经将 AWS 集群手动快照到 S3,您可以跳到第二部分。

在我们开始之前,理解下面的 IAM 安全步骤很重要。首先,为了将 AWS ES 群集快照到 S3,您的 AWS ES 群集需要权限才能写入私有 S3 存储时段。这要求 IAM 角色和策略具有必要的权限。此外,我们需要将 IAM 策略附加到 IAM 用户(如有必要,创建一个)。我们的脚本使用 IAM 用户与您的 AWS ES 集群进行对话,您的 Elastic 管理部署使用 IAM 用户从您的 S3 存储时段中读取快照。

第一部分 - S3 快照

本指南的第一部分涉及设置 IAM 角色、策略和用户,以便将您的 AWS ES 群集快照发送到 S3。此过程的 AWS 文档可在以下位置找到:使用 Amazon Elasticsearch 服务 索引快照。如果您遇到问题了,它可以作为参考。

您将需要注意我们将使用的几个变量。将下表复制并粘贴到笔记文件中,您可以在本指南中引用它。这将使您很容易填写特定于您的迁移的值。

DescriptionVariableValue
AWS ES Domain ARN DOMAIN_ARN
AWS ES Endpoint URL ES_ENDPOINT
AWS ES Region ES_REGION
AWS S3 Bucket Name S3_BUCKET_NAME
AWS S3 Region S3_REGION_NAME
AWS IAM Role ARN ROLE_ARN
AWS IAM Access Key ID ACCESS_KEY
AWS IAM Secret Access Key SECRET_KEY
AWS ES Snapshot Repository SNAPSHOT_REPO my-snapshot-repo
AWS ES Snapshot Name SNAPSHOT_NAME my-snapshot

您可以更改 SNAPSHOT_REPO 和 SNAPSHOT_NAME 的值,或者使用提供的示例(即“my-snapshot-repo” 和 “my-snapshot”)。

第 1 步-获取您的 AWS ES 信息

我们需要一些关于您的 AWS 集群的基本信息,以便将它快照到 S3。

  1. 在 AWS 控制台中,转到Elasticsearch 服务
  2. 选择要拍摄快照的群集域
  3. 将“Domain ARN”值复制到您的笔记文件 (DOMAIN_ARN)
  4. 将“Endpoint” URL 复制到您的笔记文件 (ES_ENDPOINT)
  5. 请注意您的 AWS ES 服务集群位于哪个 AWS ES 区域(如 us-east-1)

这些信息将在以下 IAM 策略创建和向集群发出命令时使用。

步骤2 -创建 AWS ESS3 时段

我们需要创建一个 S3 存储时段来存储您的快照。

重要说明: 您的 S3 时段必须与 AWS ES 群集在同一区域。您将能够从那里恢复到任何地区或云提供商(AWS 或 GCP)的 Elastic 管理的部署。

  1. 在 AWS 控制台中,转到 S3 服务
  2. 创建一个私人 S3 时段
    注意: 如果您保留默认值,您的存储时段将是私有且安全的
  3. 将存储时段的名称复制到您的笔记文件中(S3 存储时段名称)
  4. 将时段的区域复制到您的笔记文件(S3 区域名称)

当我们向 Elasticsearch 注册快照存储库时,会用到这些信息。

步骤 3 - 创建 IAM 角色

接下来,我们将创建一个角色,授权 Amazon Elasticsearch 服务 在 S3 拍摄快照。

  1. 在 AWS 控制台中,转到 IAM 服务
  2. 选择“Roles”
  3. 选择 “Create role”
  4. 选择“EC2”作为将使用这个新角色的服务(我们稍后将更改它)
  5. 选择“Next:Permissions”
  6. 暂时将角色上的策略留空
  7. 选择“Next:Tags”
  8. 选择“Next:Review”
  9. 命名角色:TheSnapshotRole
  10. 选择 “Create role”
  11. 从角色列表中,选择我们刚刚创建的角色:TheSnapshotRole
  12. 选择“Trust relationships”
  13. 选择“Edit trust relationship”
  14. 将以下内容复制并粘贴到信任关系中(替换现有内容)

    {
     "Version":"2012-10-17",
      "Statement": [{
        "Effect":"Allow",
        "Principal": {
          "Service": "es.amazonaws.com"
        },
        "Action": "sts:AssumeRole"
      }]
    }
    
  15. 选择“Update Trust Policy”
  16. 选择“Permissions”
  17. 选择“Add inline policy”
  18. 选择 JSON 选项卡
  19. 复制并粘贴以下 JSON(替换现有内容)
  20. 用正确的值替换 S3_BUCKET_NAME(两处)

    {
      "Version":"2012-10-17",
      "Statement": [{
          "Action": [
            "s3:ListBucket"
          ],
          "Effect":"Allow",
          "Resource": [
            "arn:aws:s3:::S3_BUCKET_NAME"
          ]
        },
        {
          "Action": [
            "s3:GetObject",
            "s3:PutObject",
            "s3:DeleteObject"
          ],
          "Effect":"Allow",
          "Resource": [
            "arn:aws:s3:::S3_BUCKET_NAME/*"
          ]
        }
      ]
    }   
  21. 选择 “Review policy”
  22. 给策略命名:TheSnapshotS3Policy
  23. 选择 “Create policy”
  24. 将“Role ARN”值复制到您的笔记文件 (ROLE_ARN)

我们刚刚创建了一个具有内嵌策略的 IAM 角色,可以读写您的 S3 时段。

步骤 4 - 创建 IAM 策略

我们需要创建一个新的 IAM 策略,该策略具有承担上述角色的权限,以便注册快照存储库。

  1. 在 AWS 控制台中,转到 IAM 服务
  2. 选择“Policies”
  3. 选择 “Create policy”
  4. 选择 JSON 选项卡
  5. 复制并粘贴以下 JSON(替换现有内容)
  6. 用正确的值替换 ROLE_ARN
  7. 用正确的值替换 DOMAIN_ARN
  8. 用正确的值替换 S3_BUCKET_NAME(两处)

    {
      "Version":"2012-10-17",
      "Statement": [
        {
          "Effect":"Allow",
          "Action": "iam:PassRole",
          "Resource":"ROLE_ARN"
        },
        {
          "Effect":"Allow",
          "Action": "es:ESHttpPut",
          "Resource":"DOMAIN_ARN/*"
        }
      ]
    }
    
  9. 选择 “Review policy”
  10. 给策略命名:TheSnapshotPolicy
  11. 选择 “Create policy”

我们刚刚创建了一个 IAM 策略,允许 IAM 角色与您的 AWS ES 域进行对话。

步骤 5 - 创建 IAM 用户

如果您还没有 IAM 用户,我们需要创建一个,并让它访问您的私人 S3 时段。如果您确实有 IAM 用户,您可以简单地将以下 IAM 策略附加到该用户。

  1. 在 AWS 控制台中,转到 IAM 服务
  2. 选择“Users”
  3. 选择“Add user”
  4. 命名用户:TheSnapshotUser
  5. 选中“Programmatic access”框
  6. 选择“Next:Permissions”
  7. 选择“Attach existing policies directly”框
  8. 通过键入“TheSnapshot”过滤策略
  9. 选中策略“TheSnapshotPolicy”旁边的复选框
  10. 选择“Next:Tags”
  11. 选择“Next:Review”
  12. 选择“Create user”
  13. 将“Access key ID”值复制到您的笔记文件 (ACCESS_KEY)
  14. 选择“Secret access key”下的“Show”
  15. 将“Secret Access Key”值复制到您的笔记文件 (SECRET_KEY)
  16. 选择“Close”
  17. 从用户列表中,选择我们刚刚创建的用户:TheSnapshotUser
  18. 选择“Add inline policy”
  19. 选择 JSON 选项卡
  20. 复制并粘贴以下 JSON(替换现有内容)
  21. 用正确的值替换 S3_BUCKET_NAME(两处)

    {
      "Version":"2012-10-17",
      "Statement": [{
          "Action": [
            "s3:ListBucket"
          ],
          "Effect":"Allow",
          "Resource": [
            "arn:aws:s3:::S3_BUCKET_NAME"
          ]
        },
        {
          "Action": [
            "s3:GetObject",
            "s3:PutObject",
            "s3:DeleteObject"
          ],
          "Effect":"Allow",
          "Resource": [
            "arn:aws:s3:::S3_BUCKET_NAME/*"
          ]
        }
      ]
    }
    
  22. 选择 “Review policy”
  23. 给策略命名:TheSnapshotUserS3Policy
  24. 选择 “Create policy”

我们刚刚创建了一个 IAM 用户,可以手动拍摄快照并从中读取。

步骤 6 -配置 Python AWS SDK

在运行手动快照之前,我们需要向您的部署注册一个快照存储库。这需要向您的 AWS ES 群集发送签名请求。最简单的方法之一是使用 Python AWS SDK。您可以使用另一个 AWS SDK(例如,Java、Ruby、Go等)。不过下面的例子使用了 Python AWS SDK。

我们将使用 Python 的软件包安装程序 PIP (pip3) 安装 Python AWS SDK。这需要安装 Python v3。如果您没有安装 Python v3,只需安装 pip3 即可获得它。您的操作系统的包管理器将自动安装 Python v3,因为它是 pip3 的依赖项。如果卡住,请参考 Python 安装文档

安装 pip3

要将 pip3 安装在Red Hat 和衍生物上,请使用 yum:

$ sudo yum -y install python3-pip

有可能一些 Fedora 发行版对 pip3 包装的标签不同:

$ sudo yum -y install python36-pip

如果以上两个包名都不起作用,您可以搜索:

$ yum search pip

Debian 衍生物如 Ubuntu上,使用 apt-get:

$ sudo apt-get -y install python3-pip

安装 Python AWS SDK

一旦安装了pip3,您就可以安装名为 boto3 的 Python AWS SDK:

$ pip3 install --user boto3 requests_aws4auth
收集 boto3
...
已成功安装 boto3-1.9.106 requests-aws4auth-0.9 ...

注意: 如果指定-用户标志,则不需要根访问。

我们需要创建一个 ~/.aws 目录保存我们的 AWS 凭据。运行以下命令创建目录:

$ mkdir ~/.aws

用您最喜欢的编辑器创建一个名为 credentials 的文件。为了简单起见,我们将使用 nano

$ nano ~/.aws/credentials

将以下内容复制并粘贴到文件中,替换两个大写变量。

[default]
aws_access_key_id = ACCESS_KEY
aws_secret_access_key = SECRET_KEY

使用 ctrl+x 退出 nano,并按照提示保存文件。

接下来,我们将编写一些 Python 脚本来执行我们需要的任务。

步骤 7 - 手动快照 AWS ES

让我们使用 Python 脚本运行一个快速测试,列出我们的 AWS ES 集群中的索引。这将确保我们的 AWS 凭据正常工作,并证明我们可以与集群对话。

用您最喜欢的编辑器创建一个名为 indices.py 的文件。为了简单起见,我们将使用 nano

$ nano indices.py

复制并粘贴以下内容,用您的值替换二个大写变量:

导入 boto3,请求
来自 requests_aws4auth import AWS4Auth
host = 'ES_ENDPOINT'
region = 'ES_REGION'
creds = boto3.Session().get_credentials()
auth = AWS4Auth(creds.access_key, creds.secret_key, region, 'es', session_token=creds.token)
print("Listing Indices from AWS ES ...")
req = requests.get(host + '/_cat/indices?v', auth=auth)
print("HTTP Response Code: " + str(req.status_code) + '\n' + req.text)

使用 ctrl+x 退出 nano,并按照提示保存文件。

运行 Python 脚本。

$ python3 indices.py

您的输出应该类似于以下内容:

Listing Indices from AWS ES ...
HTTP 响应代码:200
health status index     uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   testindex yME2BphgR3Gt1ln6n03nHQ   5   1          1            0      4.4kb          4.4kb

现在用您最喜欢的编辑器创建一个名为 register.py 的文件。

$ nano register.py

复制并粘贴以下内容,用您的值替换七个大写变量:

导入 boto3,请求
来自 requests_aws4auth import AWS4Auth
host = 'ES_ENDPOINT'
region = 'ES_REGION'
repo_name = 'SNAPSHOT_REPO'
snapshot_name = 'SNAPSHOT_NAME'
s3_region_name = 'S3_REGION_NAME'
s3_bucket_name = 'S3_BUCKET_NAME'
role_arn = 'ROLE_ARN'
creds = boto3.Session().get_credentials()
auth = AWS4Auth(creds.access_key, creds.secret_key, region, 'es', session_token=creds.token)
headers = {"Content-Type": "application/json"}
payload = {
        "type": "s3",
        "settings": {
                "region": s3_region_name,
                "bucket": s3_bucket_name,
                "role_arn": role_arn
        }
}
print("Registering Snapshot with AWS ES ...")
url = host + '/_snapshot/' + repo_name
req = requests.put(url, auth=auth, json=payload, headers=headers)
print("HTTP Response Code: " + str(req.status_code) + '\n' + req.text)

使用 ctrl+x 退出 nano,并按照提示保存文件。

运行 Python 脚本。

$ python3 register.py

您的输出应该类似于以下内容:

Registering Snapshot with AWS ES ...
HTTP 响应代码:200
{"acknowledged":true}

现在用您最喜欢的编辑器创建一个名为 snapshot.py 的文件。

$ nano snapshot.py

复制并粘贴以下内容,用您的值替换四个大写变量:

导入 boto3,请求
来自 requests_aws4auth import AWS4Auth
host = 'ES_ENDPOINT'
region = 'ES_REGION'
repo_name = 'SNAPSHOT_REPO'
snapshot_name = 'SNAPSHOT_NAME'
creds = boto3.Session().get_credentials()
auth = AWS4Auth(creds.access_key, creds.secret_key, region, 'es', session_token=creds.token)
print("Starting Snapshot with AWS ES ...")
url = host + '/_snapshot/' + repo_name + '/' + snapshot_name
req = requests.put(url, auth=auth)
print("HTTP Response Code: " + str(req.status_code) + '\n' + req.text)

使用 ctrl+x 退出 nano,并按照提示保存文件。

运行 Python 脚本。

$ python3 snapshot.py

您的输出应该类似于以下内容:

使用 AWS ES 启动快照...
HTTP 响应代码:200
{"accepted":true}

注意: 拍摄快照所需的时间随着 AWS ES 域的大小而增加。根据 AWS 文档,长时间运行的快照操作有时会显示“504 GATEWAY_TIMEOUT”。他们的文档说您可以忽略这个错误,只需等待快照成功完成。

最后,让我们检查一下快照的状态。创建一个名为 status.py 的文件。

$ nano status.py

复制并粘贴以下内容,用您的值替换四个大写变量:

导入 boto3,请求
来自 requests_aws4auth import AWS4Auth
host = 'ES_ENDPOINT'
region = 'ES_REGION'
repo_name = 'SNAPSHOT_REPO'
snapshot_name = 'SNAPSHOT_NAME'
creds = boto3.Session().get_credentials()
auth = AWS4Auth(creds.access_key, creds.secret_key, region, 'es', session_token=creds.token)
print("Getting Status of Snapshot with AWS ES ...")
url = host + '/_snapshot/' + repo_name + '/' + snapshot_name + '?pretty'
req = requests.get(url, auth=auth)
print("HTTP Response Code: " + str(req.status_code) + '\n' + req.text)

使用 ctrl+x 退出 nano,并按照提示保存文件。

运行 Python 脚本。

$ python3 status.py

您的输出应该类似于以下内容:

使用 AWS ES 获取快照状态...
HTTP 响应代码:200
{
  "snapshots" : [ {
    "snapshot" : "my-snapshot",
    "uuid" :"ClYKt5g8QFO6r3kTCEzjqw",
    "version_id" :6040299,
    "version" :"6.4.2",
    "indices" : [ "testindex" ],
    "include_global_state" : true,
    "state" :"SUCCESS",
    "start_time" :"2019-03-03T14:46:04.094Z",
    "start_time_in_millis" :1551624364094,
    "end_time" :"2019-03-03T14:46:04.847Z",
    "end_time_in_millis" :1551624364847,
    "duration_in_millis" :753,
    "failures" : [ ],
    "shards" : {
      "total" :5,
      "failed" :0,
      "successful" :5
    }
  } ]
}

如果您看到“state”:“SUCCESS”,那么您已经成功地为 S3 拍摄了快照,并为第二部分做好了准备!

第二部分 - 从 S3 恢复

本指南的第二部分涉及从 S3 的手动快照恢复 Elastic 管理部署。

您可以为指南的这一部分在 AWS 或 GCP 中提供 Elastic 管理部署。

步骤 1 -调整部署规模

您在 Elastic Cloud 上的 Elasticsearch 服务 中创建的部署应该具有与您的 AWS ES 集群相同的资源量。使用滑块并增加数据节点的数量,以反映 AWS 环境中集群的大小。继续之前保存您的更改。

步骤 2 - 添加自定义存储库

在您的 Elastic 管理的部署(不是您的 AWS ES 集群)中,打开 Kibana 并转到“Dev Tools”。

将以下 API 调用复制并粘贴到开发工具中,替换五个变量:

PUT /_snapshot/SNAPSHOT_REPO
{
  "type": "s3",
  "settings": {
    "bucket":"S3_BUCKET_NAME",
    "region":"S3_REGION_NAME",
    "access_key":"ACCESS_KEY",
    "secret_key":"SECRET_KEY",
    "compress": true
  }
}

执行请求。

您应该会得到以下响应:

{
  "acknowledged": "true"
}

您快完成了。

步骤 3 - 从 S3 恢复

最后,是从我们刚刚注册的快照存储库中恢复的时候了。

将以下 API 调用复制并粘贴到开发工具中,替换两个变量:

POST /_snapshot/SNAPSHOT_REPO/SNAPSHOT_NAME/_restore

您应该会得到以下响应:

{
  "accepted": "true"
}

您可以通过以下方式检查恢复进度:

GET /_snapshot/SNAPSHOT_REPO/SNAPSHOT_NAME/_status

如果您看到 "state":"SUCCESS”,您的恢复已成功完成:

{
  "snapshots": [
    {
      "snapshot": "my-snapshot",
      "repository": "my-snapshot-repo",
      "state":"SUCCESS",
      ...
    }
  ]
}

祝贺您完成了从 AWS ES 到 Elasticsearch 服务 的“直接式”迁移。

总结

现在,您已经使用了Elastic Cloud 上的 Elasticsearch 服务,不仅可以利用 AWS ES 上没有的功能,而且您还可以放心,因为您的部署是由创建 Elastic Stack 的专家维护的。如果您一路上遇到任何问题,Elastic 支持团队的专家都会提供帮助。 如果您还没有使用 Elastic Cloud 上的 Elasticsearch 服务,请使用 14 天免费试用,如果您有任何问题,请随时联系我们。