S3 存储库

编辑

您可以使用 AWS S3 作为 快照/恢复 的存储库。

如果您正在寻找 AWS 上 Elasticsearch 的托管解决方案,请访问 https://elastic.ac.cn/cloud/

入门

编辑

要注册 S3 存储库,在创建存储库时将类型指定为 s3。存储库默认使用 ECS IAM 角色 凭据进行身份验证。您也可以使用 Kubernetes 服务帐户 进行身份验证。

唯一必须设置的是存储桶名称。

resp = client.snapshot.create_repository(
    name="my_s3_repository",
    repository={
        "type": "s3",
        "settings": {
            "bucket": "my-bucket"
        }
    },
)
print(resp)
const response = await client.snapshot.createRepository({
  name: "my_s3_repository",
  repository: {
    type: "s3",
    settings: {
      bucket: "my-bucket",
    },
  },
});
console.log(response);
PUT _snapshot/my_s3_repository
{
  "type": "s3",
  "settings": {
    "bucket": "my-bucket"
  }
}

客户端设置

编辑

您用于连接到 S3 的客户端具有一些可用的设置。这些设置的格式为 s3.client.CLIENT_NAME.SETTING_NAME。默认情况下,s3 存储库使用名为 default 的客户端,但这可以使用 存储库设置 client 进行修改。例如:

resp = client.snapshot.create_repository(
    name="my_s3_repository",
    repository={
        "type": "s3",
        "settings": {
            "bucket": "my-bucket",
            "client": "my-alternate-client"
        }
    },
)
print(resp)
const response = await client.snapshot.createRepository({
  name: "my_s3_repository",
  repository: {
    type: "s3",
    settings: {
      bucket: "my-bucket",
      client: "my-alternate-client",
    },
  },
});
console.log(response);
PUT _snapshot/my_s3_repository
{
  "type": "s3",
  "settings": {
    "bucket": "my-bucket",
    "client": "my-alternate-client"
  }
}

大多数客户端设置可以添加到 elasticsearch.yml 配置文件,但安全设置除外,您需要将其添加到 Elasticsearch 密钥库。有关创建和更新 Elasticsearch 密钥库的更多信息,请参阅 安全设置

例如,如果您想使用特定凭据访问 S3,请运行以下命令将这些凭据添加到密钥库。

bin/elasticsearch-keystore add s3.client.default.access_key
bin/elasticsearch-keystore add s3.client.default.secret_key
# a session token is optional so the following command may not be needed
bin/elasticsearch-keystore add s3.client.default.session_token

如果您想改用实例角色或容器角色来访问 S3,则应将这些设置保留为空。您可以通过从密钥库中删除这些设置来切换回使用实例角色或容器角色的默认设置,方法如下:

bin/elasticsearch-keystore remove s3.client.default.access_key
bin/elasticsearch-keystore remove s3.client.default.secret_key
# a session token is optional so the following command may not be needed
bin/elasticsearch-keystore remove s3.client.default.session_token

所有 此存储库类型的客户端安全设置都是 可重新加载的。您可以在节点启动之前定义这些设置,或者在定义设置后调用 节点重新加载安全设置 API 以将其应用于正在运行的节点。

重新加载设置后,用于传输快照内容的内部 s3 客户端将使用密钥库中的最新设置。任何现有的 s3 存储库以及任何新创建的存储库都将获取存储在密钥库中的新值。

正在进行的快照/恢复任务不会被客户端安全设置的 重新加载 抢占。该任务将使用操作启动时构建的客户端完成。

以下列表包含可用的客户端设置。必须存储在密钥库中的那些被标记为“安全”且 可重新加载;其他设置属于 elasticsearch.yml 文件。

access_key (安全可重新加载)
S3 访问密钥。如果设置,则还必须指定 secret_key 设置。如果未设置,客户端将改用实例或容器角色。
secret_key (安全可重新加载)
S3 密钥。如果设置,则还必须指定 access_key 设置。
session_token (安全可重新加载)
S3 会话令牌。如果设置,则还必须指定 access_keysecret_key 设置。
endpoint
要连接到的 S3 服务端点。默认为 s3.amazonaws.com,但 AWS 文档 列出了替代的 S3 端点。如果您使用的是 与 S3 兼容的服务,则应将其设置为服务的端点。
protocol
用于连接到 S3 的协议。有效值为 httphttps。默认为 https。使用 HTTPS 时,此存储库类型将使用 JVM 范围的信任库验证存储库的证书链。请确保根证书颁发机构使用 JVM 的 keytool 工具位于此信任库中。如果您有 S3 存储库的自定义证书颁发机构并使用 Elasticsearch 捆绑的 JDK,则每次升级 Elasticsearch 时都需要重新安装 CA 证书。
proxy.host
要通过其连接到 S3 的代理的主机名。
proxy.port
要通过其连接到 S3 的代理的端口。
proxy.scheme
用于代理连接到 S3 的方案。有效值为 httphttps。默认为 http。此设置允许指定用于与代理服务器通信的协议。
proxy.username (安全可重新加载)
用于连接到 proxy.host 的用户名。
proxy.password (安全可重新加载)
用于连接到 proxy.host 的密码。
read_timeout
(时间值) Elasticsearch 在关闭连接之前,将等待通过已建立的开放连接接收下一字节数据的最大时间。默认值为 50 秒。
max_connections
与 S3 的并发连接的最大数量。默认值为 50
max_retries
S3 请求失败时要使用的重试次数。默认值为 3
use_throttle_retries
是否应限制(即应退避)重试。必须为 truefalse。默认为 true
path_style_access
是否强制使用路径样式访问模式。如果为 true,则将使用路径样式访问模式。如果为 false,则 AWS Java SDK 将自动确定访问模式(有关详细信息,请参阅 AWS 文档)。默认为 false

7.07.17.27.3 版本中,所有存储桶操作都使用 现已弃用 的路径样式访问模式。如果您的部署需要路径样式访问模式,则在升级时应将此设置设置为 true

disable_chunked_encoding
是否应禁用分块编码。如果为 false,则启用分块编码,并在适当的地方使用。如果为 true,则禁用分块编码,不会使用,这可能意味着快照操作会消耗更多资源并需要更长时间才能完成。仅当您使用不支持分块编码的存储服务时,才应将其设置为 true。有关详细信息,请参阅 AWS Java SDK 文档。默认为 false
region
允许指定要使用的签名区域。对于大多数用例,无需手动指定此设置。通常,SDK 会正确猜测要使用的签名区域。它应被视为专家级设置,以支持需要 v4 签名 并使用除默认 us-east-1 之外的区域的与 S3 兼容的 API。默认为空字符串,这意味着 SDK 将尝试自动确定正确的签名区域。
signer_override
允许指定 S3 客户端用于对请求进行签名的签名算法的名称。对于大多数用例,无需指定此设置。它应被视为专家级设置,以支持不支持 SDK 为其自动确定的签名算法的与 S3 兼容的 API。有关详细信息,请参阅 AWS Java SDK 文档。默认为空字符串,这意味着不会使用任何签名算法覆盖。

存储库设置

编辑

s3 存储库类型支持许多设置,以自定义如何在 S3 中存储数据。这些可以在创建存储库时指定。例如:

resp = client.snapshot.create_repository(
    name="my_s3_repository",
    repository={
        "type": "s3",
        "settings": {
            "bucket": "my-bucket",
            "another_setting": "setting-value"
        }
    },
)
print(resp)
const response = await client.snapshot.createRepository({
  name: "my_s3_repository",
  repository: {
    type: "s3",
    settings: {
      bucket: "my-bucket",
      another_setting: "setting-value",
    },
  },
});
console.log(response);
PUT _snapshot/my_s3_repository
{
  "type": "s3",
  "settings": {
    "bucket": "my-bucket",
    "another_setting": "setting-value"
  }
}

支持以下设置:

bucket

(必需) 要用于快照的 S3 存储桶的名称。

存储桶名称必须符合 Amazon 的 S3 存储桶命名规则

client
要用于连接到 S3 的 S3 客户端 的名称。默认为 default
base_path

指定存储库数据在其存储桶内的路径。默认为空字符串,这意味着存储库位于存储桶的根目录。此设置的值不应以 / 开头或结尾。

配置Elastic Cloud Enterprise的快照存储库时,请勿设置base_path。Elastic Cloud Enterprise会自动为每个部署生成base_path,以便多个部署可以共享同一个存储桶。

chunk_size
(字节值) Elasticsearch在创建快照时写入存储库的对象的最大大小。大于chunk_size的文件将被分成几个较小的对象。Elasticsearch也可能将文件拆分为多个对象以满足其他约束,例如max_multipart_parts限制。默认为5TB,这是AWS S3中对象的 最大大小
compress
设置为true时,元数据文件将以压缩格式存储。此设置不影响默认情况下已压缩的索引文件。默认为true
max_restore_bytes_per_sec
(可选,字节值) 每个节点的最大快照恢复速率。默认为无限制。请注意,恢复也通过恢复设置进行限制。
max_snapshot_bytes_per_sec
(可选,字节值) 每个节点的最大快照创建速率。默认为每秒40mb。请注意,如果设置了托管服务的恢复设置,则默认为无限制,并且速率还会通过恢复设置进行额外限制。
readonly

(可选,布尔值) 如果为true,则存储库为只读。集群可以从存储库检索和恢复快照,但不能写入存储库或在其中创建快照。

只有具有写入权限的集群才能在存储库中创建快照。连接到存储库的所有其他集群都应将readonly参数设置为true

如果为false,则集群可以写入存储库并在其中创建快照。默认为false

如果使用多个集群注册相同的快照存储库,则只有一个集群应该具有对存储库的写入权限。多个集群同时写入存储库可能会损坏存储库的内容。

server_side_encryption
设置为true时,文件将使用AES256算法在服务器端加密。默认为false
buffer_size
(字节值) 低于此阈值时,将使用单个请求上传块。超过此阈值,S3存储库将使用AWS分块上传API将块分成几部分,每部分长度为buffer_size,并在其自己的请求中上传每一部分。请注意,不允许设置低于5mb的缓冲区大小,因为它会阻止使用分块上传API,并可能导致上传错误。也不可能设置大于5gb的缓冲区大小,因为这是S3允许的最大上传大小。默认为100mb或JVM堆的5%,取较小值。
max_multipart_parts
(整数) Elasticsearch在单个对象的多分块上传期间写入的最大部分数。大于buffer_size × max_multipart_parts的文件将被分成几个较小的对象。Elasticsearch也可能将文件拆分为多个对象以满足其他约束,例如chunk_size限制。默认为10000,这是AWS S3中多分块上传的最大部分数
canned_acl
S3存储库支持所有S3预定义ACLprivatepublic-readpublic-read-writeauthenticated-readlog-delivery-writebucket-owner-readbucket-owner-full-control。默认为private。您可以使用canned_acl设置指定预定义ACL。当S3存储库创建存储桶和对象时,它会将预定义ACL添加到存储桶和对象中。
storage_class
设置写入到存储库的对象的S3存储类。值可以是standardreduced_redundancystandard_iaonezone_iaintelligent_tiering。默认为standard。有关更多信息,请参见S3存储类
delete_objects_max_size
(整数) 设置用于DeleteObjects请求的最大批量大小,介于1到1000之间。默认为1000,这是AWS DeleteObjects API支持的最大数量。
max_multipart_upload_cleanup_size
(整数) 设置在每次快照删除的批处理中清理可能悬空的多部分上传的最大数量。默认为1000,这是AWS ListMultipartUploads API支持的最大数量。如果设置为0,则Elasticsearch将不会尝试清理悬空的多部分上传。

如以下文档中所述,在存储库设置中定义客户端设置的选项已被弃用,将在未来版本中删除。

除了上述设置外,您还可以指定存储库设置中的所有非安全客户端设置。在这种情况下,在存储库设置中找到的客户端设置将与存储库使用的命名客户端的客户端设置合并。客户端设置和存储库设置之间的冲突将通过存储库设置优先于客户端设置来解决。

例如

resp = client.snapshot.create_repository(
    name="my_s3_repository",
    repository={
        "type": "s3",
        "settings": {
            "client": "my-client",
            "bucket": "my-bucket",
            "endpoint": "my.s3.endpoint"
        }
    },
)
print(resp)
const response = await client.snapshot.createRepository({
  name: "my_s3_repository",
  repository: {
    type: "s3",
    settings: {
      client: "my-client",
      bucket: "my-bucket",
      endpoint: "my.s3.endpoint",
    },
  },
});
console.log(response);
PUT _snapshot/my_s3_repository
{
  "type": "s3",
  "settings": {
    "client": "my-client",
    "bucket": "my-bucket",
    "endpoint": "my.s3.endpoint"
  }
}

这将设置一个存储库,该存储库使用客户端my_client_name中的所有客户端设置,但endpoint除外,endpoint由存储库设置覆盖为my.s3.endpoint

S3存储类

编辑

Amazon S3支持各种存储类,每种存储类都提供不同的操作特性。例如,某些类的每月每字节存储成本较低,但每次请求的成本较高,其他类的可用性保证可能会有所不同。

您可以使用storage_class存储库设置指定Elasticsearch用于存储数据对象的存储类。

更改现有存储库上的storage_class设置只会影响新创建对象的存储类,从而导致混合使用存储类。

您可以使用S3生命周期策略来调整存储库中现有对象的存储类,但您不能将对象转换到不受支持的类(例如Glacier类),并且您不能使对象过期。如果您使用Glacier存储类或其他不受支持的存储类或对象过期,则可能会永久丢失对存储库内容的访问权限。

您可以使用intellligent_tiering存储类来自动管理对象的类,但您不能启用可选的归档访问或深度归档访问层。如果您使用这些层,则可能会永久丢失对存储库内容的访问权限。

有关S3存储类的更多信息,请参见AWS存储类指南

推荐的S3权限

编辑

为了将Elasticsearch快照过程限制在所需的最小资源,我们建议结合使用Amazon IAM和预先存在的S3存储桶。这是一个示例策略,它允许快照访问名为“snaps.example.com”的S3存储桶。这可以通过AWS IAM控制台进行配置,方法是创建自定义策略并使用类似于此的策略文档(将snaps.example.com更改为您的存储桶名称)。

{
  "Statement": [
    {
      "Action": [
        "s3:ListBucket",
        "s3:GetBucketLocation",
        "s3:ListBucketMultipartUploads",
        "s3:ListBucketVersions"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::snaps.example.com"
      ]
    },
    {
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject",
        "s3:AbortMultipartUpload",
        "s3:ListMultipartUploadParts"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::snaps.example.com/*"
      ]
    }
  ],
  "Version": "2012-10-17"
}

您可以通过在存储桶中指定前缀来进一步限制权限,在此示例中,名为“foo”。

{
  "Statement": [
    {
      "Action": [
        "s3:ListBucket",
        "s3:GetBucketLocation",
        "s3:ListBucketMultipartUploads",
        "s3:ListBucketVersions"
      ],
      "Condition": {
        "StringLike": {
          "s3:prefix": [
            "foo/*"
          ]
        }
      },
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::snaps.example.com"
      ]
    },
    {
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject",
        "s3:AbortMultipartUpload",
        "s3:ListMultipartUploadParts"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::snaps.example.com/foo/*"
      ]
    }
  ],
  "Version": "2012-10-17"
}

存储桶需要存在才能注册快照的存储库。如果您没有创建存储桶,则存储库注册将失败。

使用IAM角色对Kubernetes服务帐户进行身份验证
编辑

如果您想使用Kubernetes服务帐户进行身份验证,则需要在S3存储库配置目录中添加指向$AWS_WEB_IDENTITY_TOKEN_FILE环境变量的符号链接(应由Kubernetes pod自动设置),以便存储库可以对服务帐户具有读取权限(存储库无法读取其配置目录之外的任何文件)。例如

mkdir -p "${ES_PATH_CONF}/repository-s3"
ln -s $AWS_WEB_IDENTITY_TOKEN_FILE "${ES_PATH_CONF}/repository-s3/aws-web-identity-token-file"

必须在所有数据和主节点上创建符号链接,并且elasticsearch用户可以读取该符号链接。默认情况下,Elasticsearch使用uid:gid 1000:0以用户elasticsearch运行。

如果存在符号链接,则所有没有显式client凭据的S3存储库都将默认使用它。

AWS VPC带宽设置

编辑

AWS实例将S3端点解析为公共IP。如果Elasticsearch实例位于AWS VPC的私有子网中,则所有到S3的流量都将通过VPC的NAT实例。如果您的VPC的NAT实例是一个较小的实例大小(例如t2.micro)或正在处理大量网络流量,则您的S3带宽可能会受到该NAT实例的网络带宽限制的影响。相反,我们建议创建一个VPC端点,该端点允许连接到位于AWS VPC私有子网中的实例中的S3。这将消除VPC的NAT实例的网络带宽施加的任何限制。

位于AWS VPC公共子网中的实例将通过VPC的互联网网关连接到S3,并且不会受到VPC的NAT实例的带宽限制。

与S3兼容的服务

编辑

许多存储系统提供与S3兼容的API,而s3存储库类型允许您使用这些系统来代替AWS S3。为此,您应将s3.client.CLIENT_NAME.endpoint设置设置为系统的端点。此设置接受IP地址和主机名,并且可能包含端口。例如,端点可以是172.17.0.2172.17.0.2:9000

默认情况下,Elasticsearch使用HTTPS与您的存储系统通信,并使用JVM范围的信任库验证存储库的证书链。确保JVM范围的信任库包含存储库的条目。如果您希望使用不安全的HTTP通信而不是HTTPS,请将s3.client.CLIENT_NAME.protocol设置为http

MinIO是提供与S3兼容的API的存储系统的示例。s3存储库类型允许Elasticsearch与MinIO支持的存储库以及存储在AWS S3上的存储库一起工作。其他与S3兼容的存储系统也可能与Elasticsearch一起工作,但这些存储系统不在Elasticsearch测试套件的范围内。

许多系统,包括一些来自知名存储厂商的系统,声称提供与 S3 兼容的 API,但实际上并没有完全模拟 S3 的行为。如果您使用此类系统进行快照,请考虑使用基于标准协议(如 NFS)的共享文件系统存储库来访问您的存储系统。 s3 存储库类型要求与 S3 完全兼容。特别是,它必须支持相同的 API 端点集、相同的参数,在发生故障时返回相同的错误,并且即使在多个节点并发访问时,也必须提供至少与 S3 一样好的一致性和性能。您需要与您的存储系统供应商合作,以解决遇到的任何不兼容性问题。除非您可以证明在使用真正的 AWS S3 存储库时存在相同的问题,否则请不要报告涉及声称与 S3 兼容的存储系统的 Elasticsearch 问题。

您可以使用存储库分析 API对存储系统的适用性进行一些基本检查。如果此 API 未成功完成或指示性能较差,则您的存储系统与 AWS S3 不完全兼容,因此不适合用作快照存储库。但是,这些检查不能保证完全兼容。

大多数存储系统都可以配置为记录其与 Elasticsearch 交互的详细信息。如果您正在调查疑似与 AWS S3 不兼容的问题,通常最简单的方法是收集这些日志并将其提供给您的存储系统供应商进行进一步分析。如果从存储系统发出的日志中无法清楚地看出不兼容性,请通过设置日志级别com.amazonaws.request 记录器的日志级别设置为 DEBUG,从而配置 Elasticsearch 记录其对 S3 API 的每个请求。

为了防止在日志中泄露敏感信息(例如凭据和密钥),除非启用了不安全的网络跟踪日志记录,否则 Elasticsearch 会拒绝以高详细程度配置此记录器。为此,您必须通过将系统属性 es.insecure_network_trace_enabled 设置为 true 来显式地在每个节点上启用它。

启用后,您可以配置 com.amazonaws.request 记录器

resp = client.cluster.put_settings(
    persistent={
        "logger.com.amazonaws.request": "DEBUG"
    },
)
print(resp)
response = client.cluster.put_settings(
  body: {
    persistent: {
      'logger.com.amazonaws.request' => 'DEBUG'
    }
  }
)
puts response
const response = await client.cluster.putSettings({
  persistent: {
    "logger.com.amazonaws.request": "DEBUG",
  },
});
console.log(response);
PUT /_cluster/settings
{
  "persistent": {
    "logger.com.amazonaws.request": "DEBUG"
  }
}

收集集群中所有节点上分析失败期间的 Elasticsearch 日志,并将其与分析响应一起共享给您的存储系统供应商,以便他们可以使用这些日志来确定问题所在。有关更多信息,包括有关可用于获取更详细日志的其他记录器的详细信息,请参阅AWS Java SDK 文档。完成收集供应商所需的日志后,将记录器设置恢复为 null 以返回到默认日志配置并再次禁用不安全的网络跟踪日志记录。有关更多信息,请参阅记录器集群更新设置

线性化寄存器实现

编辑

S3 存储库的线性化寄存器实现基于多部分上传 API 的强一致性语义。Elasticsearch 首先创建一个多部分上传以指示其执行线性化寄存器操作的意图。然后,Elasticsearch 列出并取消同一寄存器的所有其他多部分上传。然后,Elasticsearch 尝试完成上传。如果上传成功完成,则比较和交换操作是原子的。