为各类对象存储提供统一接口和高效客户端,支持常见操作,注重分布式数据库所需的效率与可靠性,含 YAML 配置和 Prometheus 指标,已在 Thanos 等大规模项目中应用。【此简介由AI生成】

Thanos 对象存储客户端
objstore 是一个 Go 模块,提供了统一的接口和高效客户端,以便与各种对象存储服务提供商协同工作。
功能特点:
- 支持对大多数流行对象存储执行常见操作,并具备明确的契约。
- 高效且可靠的性能,适用于分布式数据库在对象存储上的需求。
- 可选的内置基于 YAML 的配置定义,以保持配置的一致性。
- 可选的 Prometheus 指标仪器化,用于桶操作。
本模块经过实战检验,并被 Thanos、Loki、Cortex、Mimir、Tempo、Parca 等项目在高规模生产环境中使用。
贡献指南
我们非常欢迎贡献!详情请参考我们的 CONTRIBUTING.md。
社区
Thanos 是一个开源项目,我们重视并欢迎新的贡献者和社区成员。以下是与社区取得联系的方式:
- Slack: #thanos
- 问题跟踪器:GitHub Issues
采用者
查看 采用者列表。
背景
这个库最初作为 Thanos 的 objstore 包 被开发。Thanos 将对象存储作为指标及相关元数据的主要存储。最终,这个包被 Cortex、Loki、Mimir、Tempo、Parca 等其他项目所使用。
鉴于其可重用性,Thanos 社区将这个包提升为一个独立的 Go 模块,并减少了依赖。
维护者
如何使用 objstore
本模块的核心是 Bucket 接口:
// Bucket provides read and write access to an object storage bucket.
// NOTE: We assume strong consistency for write-read flow.
type Bucket interface {
io.Closer
BucketReader
// Upload the contents of the reader as an object into the bucket.
// Upload should be idempotent.
Upload(ctx context.Context, name string, r io.Reader) error
// Delete removes the object with the given name.
// If object does not exists in the moment of deletion, Delete should throw error.
Delete(ctx context.Context, name string) error
所有提供者实现都必须实现 Bucket 接口,该接口允许进行所有对象存储提供者所支持的通用读取和写入操作。如果您希望限制执行存储桶操作代码仅为读取权限(这是一个明智的主意,可以限制访问权限),您可以使用 BucketReader 接口:
// BucketReader provides read access to an object storage bucket.
type BucketReader interface {
// Iter calls f for each entry in the given directory (not recursive.). The argument to f is the full
// object name including the prefix of the inspected directory.
// Entries are passed to function in sorted order.
Iter(ctx context.Context, dir string, f func(string) error, options ...IterOption) error
// Get returns a reader for the given object name.
Get(ctx context.Context, name string) (io.ReadCloser, error)
// GetRange returns a new range reader for the given object name and range.
GetRange(ctx context.Context, name string, off, length int64) (io.ReadCloser, error)
// Exists checks if the given object exists in the bucket.
Exists(ctx context.Context, name string) (bool, error)
// IsObjNotFoundErr returns true if error means that object is not found. Relevant to Get operations.
IsObjNotFoundErr(err error) bool
// Attributes returns information about the specified object.
以下接口表示您的代码可以使用 objstore 客户端执行的对象存储操作。
工厂方法
通常,您有两种使用 objstore 模块的方式:
第一种是导入您需要的提供者,例如 github.com/thanos-io/objstore/providers/s3,并使用可用的构造函数(例如 NewBucket)来实例化。
第二种选项是使用工厂方法 NewBucket(logger log.Logger, confContentYaml []byte, reg prometheus.Registerer, component string) 来根据提供的 YAML 文件实例化对象存储客户端。该 YAML 文件通常具有以下格式:
type: <PROVIDER_TYPE>
config:
<PROVIDER_TYPE specific options>
具体选项取决于服务提供商,相关内容在以下各节中说明。
注意:所有代码片段均自动生成于代码,并保持最新。
查看Thanos 文档,了解 Thanos 如何使用此模块。
支持的提供商(客户端)
当前对象存储客户端实现:
| 提供商 | 成熟度 | 适用场景 | 在 CI 中自动测试 | 维护者 |
|---|---|---|---|---|
| Google Cloud Storage | 稳定 | 生产环境使用 | 是 | @bwplotka |
| AWS/S3(以及所有 S3 兼容存储,例如基于磁盘的 Minio) | 稳定 | 生产环境使用 | 是 | @bwplotka |
| Azure Storage Account | 稳定 | 生产环境使用 | 否 | @vglafirov,@phillebaba |
| OpenStack Swift | 贝塔(工作原型) | 生产环境使用 | 是 | @FUSAKLA |
| Tencent COS | 贝塔 | 生产环境使用 | 否 | @jojohappy,@hanjm |
| AliYun OSS | 贝塔 | 生产环境使用 | 否 | @shaulboozhiao,@wujinhu |
| Baidu BOS | 贝塔 | 生产环境使用 | 否 | @yahaa |
| 本地文件系统 | 稳定 | 测试和演示使用 | 是 | @bwplotka |
| Oracle Cloud Infrastructure Object Storage | 贝塔 | 生产环境使用 | 是 | @aarontams,@gaurav-05,@ericrrath |
某些对象存储不支持? 查看如何添加新客户端部分添加新客户端到 Thanos
注意:当前 Thanos 需要对象存储实现具备强一致性(写-读)以满足单例压缩的需求。
S3
Thanos 使用 minio 客户端 库将 Prometheus 数据上传到 AWS S3。
注意:S3 客户端是为 AWS S3 设计的,但可以配置为使用其他 S3 兼容的对象存储,例如 Ceph
S# 对象存储的 yaml 配置定义:
type: S3
config:
bucket: ""
endpoint: ""
region: ""
aws_sdk_auth: false
access_key: ""
insecure: false
signature_version2: false
secret_key: ""
put_user_metadata: {}
http_config:
idle_conn_timeout: 1m30s
response_header_timeout: 2m
insecure_skip_verify: false
tls_handshake_timeout: 10s
expect_continue_timeout: 1s
max_idle_conns: 100
max_idle_conns_per_host: 100
max_conns_per_host: 0
tls_config:
ca_file: ""
cert_file: ""
key_file: ""
server_name: ""
insecure_skip_verify: false
disable_compression: false
trace:
enable: false
list_objects_version: ""
bucket_lookup_type: auto
part_size: 67108864
sse_config:
type: ""
kms_key_id: ""
kms_encryption_context: {}
encryption_key: ""
sts_endpoint: ""
prefix: ""
至少,您需要为 bucket、endpoint、access_key 和 secret_key 键提供值。其余的键是可选的。
然而,如果设置 aws_sdk_auth: true,Thanos 将使用基于 已知环境变量 (AWS_PROFILE、AWS_WEB_IDENTITY_TOKEN_FILE 等) 和已知的 AWS 配置文件 (~/.aws/config) 的 AWS SDK for go 默认认证方法。如果启用此选项,则 bucket 和 endpoint 是必需的配置键。
prefix 字段可用于在您的 S3 存储桶中透明地使用前缀。这使得您能够将来自不同来源的区块分离到具有不同前缀的路径中,从而更容易理解发生了什么(例如,您无需使用 Thanos 工具即可知道哪些区块来自哪里)。
AWS 区域与端点的映射可在 这个链接 中找到。
请确保使用正确的签名版本。目前 AWS 需要 v4 签名,所以需要设置 signature_version2: false。如果您不指定它,将会收到 Access Denied 错误。另一方面,一些兼容 S3 的 API 使用 signature_version2: true。
您可以通过设置 http_config.idle_conn_timeout 和 http_config.response_header_timeout 键来配置 HTTP 客户端的超时设置。一般来说,如果您的日志中出现 timeout awaiting response headers 类似错误,您可能想要增加 http_config.response_header_timeout 的值。
请参阅 net/http 包中 Transport 类型 的文档,以获取关于每个选项具体作用的详细信息。
part_size 以字节为单位指定,指的是用于多部分上传的最小文件大小,因为某些自定义 S3 实现可能有不同的要求。值为 0 表示使用默认的 128 MiB 大小。
对于不支持 ListObjectsV2 的 S3 兼容 API(例如某些版本的 Ceph),请设置 list_objects_version: "v1"。默认值("")等同于 "v2"。
http_config.tls_config 允许配置 TLS 连接。请参阅 tls_config 文档,以获取关于每个选项具体作用的详细信息。
bucket_lookup_type 可以是 auto、virtual-hosted 或 path。关于它的更多信息,请阅读 这里。
出于调试和测试目的,您可以设置:
-
insecure: true来切换到不安全的 HTTP 而不是 HTTPS -
http_config.insecure_skip_verify: true来禁用 TLS 证书验证(例如,如果您的基于 S3 的存储使用自签名证书) -
trace.enable: true来启用 minio 客户端详细日志记录。每个请求和响应都将被记录到调试日志中,因此必须启用调试级别的日志记录才能使用此功能。
S3 服务器端加密
SSE 可以通过 sse_config 进行配置。SSE-S3、SSE-KMS 和 SSE-C 均受支持。
-
如果类型设置为
SSE-S3,则无需配置其他选项。 -
如果类型设置为
SSE-KMS,则必须设置kms_key_id。kms_encryption_context是可选的,因为 AWS 提供了默认的加密环境。 -
如果类型设置为
SSE-C,则必须使用encryption_key提供加密密钥的路径。
如果设置了 SSE 配置块但 type 不是 SSE-S3、SSE-KMS 或 SSE-C 之一,将引发错误。
您还需要为用户应用以下 AWS IAM 策略来访问 KMS 密钥:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "KMSAccess",
"Effect": "Allow",
"Action": [
"kms:GenerateDataKey",
"kms:Encrypt",
"kms:Decrypt"
],
"Resource": "arn:aws:kms:<region>:<account>:key/<KMS key id>"
}
]
}
凭据
默认情况下,Thanos 会尝试从以下来源检索凭据:
- 如果配置文件中同时存在
access_key和secret_key,则从配置文件中获取。 - 从标准的 AWS 环境变量中获取 -
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY。 - 从
~/.aws/credentials文件中获取。 - 从实例配置文件中检索 IAM 凭据。
注意:不支持从配置文件中获取访问密钥,而通过其他方法获取密钥(反之亦然)。
AWS 策略
适用于用户的示例 AWS IAM 策略:
- 对于部署(Thanos 服务的策略):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject",
"s3:DeleteObject",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::<bucket>/*",
"arn:aws:s3:::<bucket>"
]
}
]
}
(无桶策略)
为了测试策略,为 空置、未使用 的桶设置 S3 访问环境变量以及:
THANOS_TEST_OBJSTORE_SKIP=GCS,AZURE,SWIFT,COS,ALIYUNOSS,OCI
THANOS_ALLOW_EXISTING_BUCKET_USE=true
并运行以下命令:GOCACHE=off go test -v -run TestObjStore_AcceptanceTest_e2e ./pkg/...
- 关于测试(执行端到端测试的策略):
我们需要访问创建桶(CreateBucket)和删除桶(DeleteBucket)的功能,以及访问所有桶的权限:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject",
"s3:DeleteObject",
"s3:PutObject",
"s3:CreateBucket",
"s3:DeleteBucket"
],
"Resource": [
"arn:aws:s3:::<bucket>/*",
"arn:aws:s3:::<bucket>"
]
}
]
}
遵循此策略,您应能够设置环境变量 THANOS_TEST_OBJSTORE_SKIP=GCS,AZURE,SWIFT,COS,ALIYUNOSS,OCI 并取消设置 S3_BUCKET,然后使用 make test 命令运行所有测试。
关于 AWS 策略的详细信息,请参考:https://docs.aws.amazon.com/AmazonS3/latest/dev/using-with-s3-actions.html
STS 终端
如果您想使用从实例配置文件中检索到的 IAM 凭证,Thanos 需要通过 AWS STS 进行身份验证。为此,您可以指定自己的 STS 终端。
默认情况下,Thanos 将使用终端:https://sts.amazonaws.com 以及与 AWS 区域对应的终端。
GCS
要将 Google Cloud Storage 存储桶配置为对象存储,您需要设置 bucket 环境变量,使用 GCS 存储桶名称,并配置 Google 应用凭证。
例如:
type: GCS
config:
bucket: ""
service_account: ""
prefix: ""
使用 GOOGLE_APPLICATION_CREDENTIALS
应用凭证是通过 JSON 文件配置的,只需要指定存储桶,客户端会查找以下内容:
- 由环境变量
GOOGLE_APPLICATION_CREDENTIALS指定的 JSON 文件路径。 - gcloud 命令行工具所知的某个位置中的 JSON 文件。在 Windows 系统中,这是
%APPDATA%/gcloud/application_default_credentials.json。在其他系统中,这是$HOME/.config/gcloud/application_default_credentials.json。 - 在 Google App Engine 中,它使用
appengine.AccessToken函数。 - 在 Google Compute Engine 和 Google App Engine 管理的虚拟机中,它从元数据服务器获取凭证。(在这种情况下,提供的作用域将被忽略。)
您可以在 https://cloud.google.com/docs/authentication/production 了解如何获取应用凭证的 JSON 文件。
内联使用服务账户
另一种可能的方法是将服务账户直接内联到 Thanos 配置中,只需维护一个文件。此功能被添加,以便 Prometheus Operator 只需要处理一个密钥文件。
type: GCS
config:
bucket: "thanos"
service_account: |-
{
"type": "service_account",
"project_id": "project",
"private_key_id": "abcdefghijklmnopqrstuvwxyz12345678906666",
"private_key": "-----BEGIN PRIVATE KEY-----\...\n-----END PRIVATE KEY-----\n",
"client_email": "project@thanos.iam.gserviceaccount.com",
"client_id": "123456789012345678901",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/thanos%40gitpods.iam.gserviceaccount.com"
}
GCS 策略
注意: GCS 策略应应用于项目级别,而非存储桶级别。
部署时:
Storage Object Creator和Storage Object Viewer
测试时:
Storage Object Admin以具备创建和删除临时存储桶的能力。
为了测试策略是否按预期工作,请执行进入侧车容器的命令,例如:
kubectl exec -it -n <namespace> <prometheus with sidecar pod name> -c <sidecar container name> -- /bin/sh
然后测试您是否至少能够列出存储桶中的对象,例如:
thanos tools bucket ls --objstore.config="${OBJSTORE_CONFIG}"
Azure
若要在Thanos对象存储中使用Azure存储,您需要先通过Azure门户或使用Azure CLI创建存储账户。请遵循Azure存储文档中的指导:https://docs.microsoft.com/en-us/azure/storage/common/storage-quickstart-create-account
配置文件的格式如下:
type: AZURE
config:
storage_account: ""
storage_account_key: ""
container: ""
endpoint: ""
user_assigned_id: ""
max_retries: 0
reader_config:
max_retry_requests: 0
pipeline_config:
max_tries: 0
try_timeout: 0s
retry_delay: 0s
max_retry_delay: 0s
http_config:
idle_conn_timeout: 0s
response_header_timeout: 0s
insecure_skip_verify: false
tls_handshake_timeout: 0s
expect_continue_timeout: 0s
max_idle_conns: 0
max_idle_conns_per_host: 0
max_conns_per_host: 0
tls_config:
ca_file: ""
cert_file: ""
key_file: ""
server_name: ""
insecure_skip_verify: false
disable_compression: false
msi_resource: ""
prefix: ""
若使用 msi_resource,身份验证将通过系统分配的管理身份进行。对于 Azure 而言,其值应为 https://<storage-account-name>.blob.core.windows.net。
若使用 user_assigned_id,身份验证将通过用户分配的管理身份进行。在采用 user_assigned_id 时,msi_resource 默认为 https://<storage_account>.<endpoint>。
通用的 max_retries 将被用作 pipeline_config 的 max_tries 及 reader_config 的 max_retry_requests 的值。为了实现更精细的控制,可以忽略 max_retries(设为 0),并设置特定的重试值。
OpenStack Swift
Thanos 使用 ncw/swift 客户端将 Prometheus 数据上传至 OpenStack Swift。
以下是示例配置文件,用于指导 Thanos 使用 OpenStack swift 容器作为对象存储。注意,如果使用了用户、项目或租户的 name,则还必须指定其通过 ID 或名称指定的域。在 官方文档 中可以找到各种 OpenStack 身份验证的示例。
默认情况下,OpenStack Swift 对文件大小有 5 GiB 的限制。Thanos 索引文件通常大于此限制。为了解决这个问题,Thanos 使用 静态大对象(SLO),将其作为段上传。默认情况下,这些段被放置在相同容器的 segments 目录下。使用 SLO 的默认限制为 1 GiB,这也是段的最大大小。如果您不想为段使用相同的容器(最佳实践是使用 <container_name>_segments 以避免污染容器对象列表),可以使用 large_file_segments_container_name 选项覆盖默认值,将段放入其他容器。在极少数情况下,您可以通过将 use_dynamic_large_objects 设为 true 来切换到 动态大对象(DLO),但请谨慎使用,因为它更依赖于最终一致性。
type: SWIFT
config:
auth_version: 0
auth_url: ""
username: ""
user_domain_name: ""
user_domain_id: ""
user_id: ""
password: ""
domain_id: ""
domain_name: ""
application_credential_id: ""
application_credential_name: ""
application_credential_secret: ""
project_id: ""
project_name: ""
project_domain_id: ""
project_domain_name: ""
region_name: ""
container_name: ""
large_object_chunk_size: 1073741824
large_object_segments_container_name: ""
retries: 3
connect_timeout: 10s
timeout: 5m
use_dynamic_large_objects: false
prefix: ""
腾讯云对象存储(COS)
若要使用腾讯云对象存储(COS)作为存储仓库,首先需要申请一个腾讯账号并创建一个对象存储桶。请注意,详细步骤请参考腾讯云文档:https://cloud.tencent.com/document/product/436
为了配置腾讯账号使用COS作为存储仓库,您需要在文件中以YAML格式设置以下参数:
type: COS
config:
bucket: ""
region: ""
app_id: ""
endpoint: ""
secret_key: ""
secret_id: ""
http_config:
idle_conn_timeout: 1m30s
response_header_timeout: 2m
insecure_skip_verify: false
tls_handshake_timeout: 10s
expect_continue_timeout: 1s
max_idle_conns: 100
max_idle_conns_per_host: 100
max_conns_per_host: 0
tls_config:
ca_file: ""
cert_file: ""
key_file: ""
server_name: ""
insecure_skip_verify: false
disable_compression: false
prefix: ""
secret_key 和 secret_id 字段是必须的。http_config 字段是可选的,用于优化 HTTP 传输设置。配置必需的存储桶信息有两种方式:
- 提供关键字
bucket、region和app_id的值。 - 当您想指定 VPC 内部端点时,提供
endpoint关键字的 URL 格式。更多关于端点的详细信息,请参考 endpoint 文档。
阿里云 OSS
为了使用阿里云 OSS 对象存储,您首先需要在阿里云上创建一个存储桶,并设置适当的存储类别、访问控制列表(ACLs),并获取访问密钥。详情请访问 https://www.alibabacloud.com/product/oss。
阿里云 OSS 对象存储的 YAML 配置定义:
type: ALIYUNOSS
config:
endpoint: ""
bucket: ""
access_key_id: ""
access_key_secret: ""
prefix: ""
百度BOS
为了使用百度BOS对象存储,您需要先申请一个百度账号并创建一个对象存储桶。更多详细内容,请参考百度云文档。百度BOS对象存储的yaml配置定义如下:
type: BOS
config:
bucket: ""
endpoint: ""
access_key: ""
secret_key: ""
prefix: ""
文件系统
当用户希望在本地的文件系统中存储和访问存储桶时,会使用这种存储类型。我们将文件系统视为与对象存储相同的方式,因此即便是我们可能在本地拥有文件,所有针对远程存储桶的优化同样适用。
注意: 这种存储类型是实验性的,并且可能效率不高。不建议在生产环境中将其作为指标的主要存储。特别是目前没有计划支持类似NFS的分布式文件系统。这主要适用于测试和演示。
文件系统“对象存储”的YAML配置定义:
type: FILESYSTEM
config:
directory: ""
prefix: ""
Oracle 云基础设施对象存储
要将 Oracle 云基础设施(OCI)对象存储配置为 Thanos 对象存储,您需要为 OCI 租户提供适当的认证凭证。Thanos 的 OCI 对象存储客户端实现支持使用默认密钥对或实例主体认证。
API 签名密钥
默认的 API 签名密钥认证提供程序利用与 OCI 命令行界面(CLI)相同的配置,通常存储在 $HOME/.oci/config 或通过以字符串 OCI_CLI 开头的变量名。您还可以使用以 TF_VAR 开头的环境变量。如果多处找到了相同的配置,提供程序将优先选择第一个。
以下示例配置提供程序以查找用于认证的现有 API 签名密钥:
type: OCI
config:
provider: "default"
bucket: ""
compartment_ocid: ""
part_size: "" // Optional part size to override the OCI default of 128 MiB, value is in bytes.
max_request_retries: "" // Optional maximum number of retries for a request.
request_retry_interval: "" // Optional sleep duration in seconds between retry requests.
http_config:
idle_conn_timeout: 1m30s // Optional maximum amount of time an idle (keep-alive) connection will remain idle before closing itself. Zero means no limit.
response_header_timeout: 2m // Optional amount of time to wait for a server's response headers after fully writing the request.
tls_handshake_timeout: 10s // Optional maximum amount of time waiting to wait for a TLS handshake. Zero means no timeout.
expect_continue_timeout: 1s // Optional amount of time to wait for a server's first response headers. Zero means no timeout and causes the body to be sent immediately.
insecure_skip_verify: false // Optional. If true, crypto/tls accepts any certificate presented by the server and any host name in that certificate.
max_idle_conns: 100 // Optional maximum number of idle (keep-alive) connections across all hosts. Zero means no limit.
max_idle_conns_per_host: 100 // Optional maximum idle (keep-alive) connections to keep per-host. If zero, DefaultMaxIdleConnsPerHost=2 is used.
max_conns_per_host: 0 // Optional maximum total number of connections per host.
disable_compression: false // Optional. If true, prevents the Transport from requesting compression.
client_timeout: 90s // Optional time limit for requests made by the HTTP Client.
实例主体提供者
例如:
type: OCI
config:
provider: "instance-principal"
bucket: ""
compartment_ocid: ""
您也可以像在 Default Provider 示例中一样,包含任何可选配置。
原始提供者
例如:
type: OCI
config:
provider: "raw"
bucket: ""
compartment_ocid: ""
tenancy_ocid: ""
user_ocid: ""
region: ""
fingerprint: ""
privatekey: ""
passphrase: "" // Optional passphrase to encrypt the private API Signing key
您还可以像 Default Provider 示例中那样,包含任何可选配置。
如何向 Thanos 添加新的客户端?
以下清单可以帮助您将新的 Go 代码客户端添加到支持的提供程序:
- 在
./providers/<provider>下创建新目录 - 实现 objstore.Bucket 接口
- 为测试目的添加
NewTestBucket构造函数,用于创建和删除临时存储桶。 - 在 ForeachStore 方法 中使用创建的
NewTestBucket,以确保我们可以在新提供程序上运行测试。(在 PR 中) - 对您的提供程序运行 TestObjStoreAcceptanceTest 以确保其符合要求。修复发现的任何错误,直到测试通过。(在 PR 中)
- 将客户端实现添加到 factory 代码中的工厂中。(在每个命令中使用尽可能少的标志)
- 将客户端结构配置添加到 cfggen 中,以允许配置自动生成。
至此,任何人都可以通过规范使用您的提供程序。
Introduction
为各类对象存储提供统一接口和高效客户端,支持常见操作,注重分布式数据库所需的效率与可靠性,含 YAML 配置和 Prometheus 指标,已在 Thanos 等大规模项目中应用。【此简介由AI生成】
Customize my domain