前言
MinIO Gateway 是一款可以代理 S3、Azure、Nas、HDFS 等服务的软件。可以让用户以兼容 S3 的方式来访问所代理的服务。
具体介绍见:https://docs.min.io/docs/minio-gateway-for-s3.html
使用场景
一、一套代码支持不同对象存储产品。
当前市面常见的对象存储产品有:
- 阿里云 OSS
- 腾讯云 COS
- 华为云 OBS
- Amazon S3
- 开源 MinIO
如果你的服务需要使用对象存储,但不同的场景下使用的对象存储服务并不一致,为了避免增加代码开发中适配多种产品的复杂性,
可以使用 MinIO Gateway 做一层代理,代码中仅需支持 MinIO 的访问方式即可。
二、避免大量开通云服务子帐号。
在公司内部,当我们使用云服务商的对象存储产品时,是必须开通云产品的子帐号才能访问的。而子帐号的开通和管理其实并不是
很方便,并且还没办法接入比如 LDAP 等帐号管理系统。此时也可以将对象存储服务用 MinIO Gateway 做一层代理,然后通过 Gateway
来管理对象存储服务的帐号,支持各种帐号管理方式。比如 Keycloak、 LDAP、内部用户等。
具体参见:https://docs.min.io/docs/minio-sts-quickstart-guide
MinIO Gateway 搭建
基本搭建步骤参考官方文档:https://docs.min.io/docs/minio-gateway-for-s3.html
可以使用 docker 或者二进制文件等方式启动 Gateway 服务。
下面说点不一样的
MinIO 编译
编译很简单,MinIO 使用 Go 语言开发,所以需要安装 Go,参见:https://go.dev/doc/install
然后源码中已经有写好的 Makefile,直接执行 make 即可。
适配腾讯云 COS
MinIO Gateway 在启动时会随机生成一个 Bucket 名称,然后利用检查 Bucket 是否存在的 API 确认 S3 服务是否可用,期待的返回状态码是 404,
但腾讯云 COS 强制每个 Bucket 的名字后缀为一串数字 ID,如果不符合格式,则响应 400,导致 MinIO Gateway 探测失败。
日志如下:
"""
---------START-HTTP---------
GET /probe-bucket-sign-99lrqve1qm4x/?location= HTTP/1.1
Host: cos.ap-beijing.myqcloud.com
User-Agent: MinIO (darwin; amd64) minio-go/v7.0.20
Authorization: AWS4-HMAC-SHA256 Credential=AKID2uWrwlJabKnzwd3CCwPbWBZhZBWZLr64/20220118/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=**REDACTED**
X-Amz-Content-Sha256: UNSIGNED-PAYLOAD
X-Amz-Date: 20220118T155622Z
Accept-Encoding: gzip
HTTP/1.1 400 Bad Request
Content-Length: 437
Connection: keep-alive
Content-Type: application/xml
Date: Tue, 18 Jan 2022 15:56:25 GMT
Server: tencent-cos
<?xml version='1.0' encoding='utf-8' ?>
<Error>
<Code>InvalidURI</Code>
<Message>Could not parse the specified URI.</Message>
<Resource>cos.ap-beijing.myqcloud.com/probe-bucket-sign-99lrqve1qm4x</Resource>
</Error>
---------END-HTTP---------
"""
在 MinIO 官方以及腾讯云官方都不做修改的情况下,只能通过修改源码重新编译来解决问题。
代码修改位置如下:
将其中的 randString 函数返回值修改为数字后缀,比如下图:
然后编译即可。
使用独立帐号体系
默认情况下,MinIO 自带一套帐号管理体系,不需要任何配置,但缺点是一旦服务重启则帐号信息丢失。
为了持久化存储帐号数据,需要配合 Etcd 服务。
Etcd部署参见:
MinIO Gateway 启动方式如下:
#!/bin/sh
export MINIO_ROOT_USER="Access Key"
export MINIO_ROOT_PASSWORD="Access Secret"
export _MINIO_SERVER_DEBUG=off # 是否开启DEBUG 仅为了查看日志 on|off
export MINIO_ETCD_ENDPOINTS=http://localhost:2379 # 使用 ETCD 持久化存储内部用户
export MINIO_ETCD_PATH_PREFIX=minio/ # ETCD 中存储的数据的前缀
./minio gateway s3 https://cos.ap-beijing.myqcloud.com --console-address 0.0.0.0:9100
不过这种方式有个缺点,新创建的 MinIO Gateway 账密是明文存储在 Etcd 中的。。。
解决办法如下:
-
控制 Etcd 的访问权限,避免被其他人访问。
-
使用 MinIO 自己的加密方式,参考:https://docs.min.io/docs/minio-kms-quickstart-guide.html。但加密这个功能,加密的地方有点多,而且有点小BUG,比如展示出来的S3文件列表不全。。。所以我放弃了。
集成 LDAP
官方文档:https://github.com/minio/minio/blob/master/docs/sts/ldap.md
启动方式如下:
#!/bin/sh
export MINIO_ROOT_USER="Access Key"
export MINIO_ROOT_PASSWORD="Access Secret"
export _MINIO_SERVER_DEBUG=off # 是否开启DEBUG 仅为了查看日志 on|off
export MINIO_IDENTITY_LDAP_SERVER_ADDR="LDAP服务器:LDAP服务端口"
export MINIO_IDENTITY_LDAP_LOOKUP_BIND_DN="{LDAP 帐号}" # 例如 cn=readonly,dc=test,dc=com 仅用只读帐号即可
export MINIO_IDENTITY_LDAP_LOOKUP_BIND_PASSWORD="{LDAP 密码}"
export MINIO_IDENTITY_LDAP_USER_DN_SEARCH_BASE_DN='ou=People,dc=test,dc=com' # 搜索域
export MINIO_IDENTITY_LDAP_USER_DN_SEARCH_FILTER='(uid=%s)' # 用来过滤登录的帐号 %s会被填充用户名
export MINIO_IDENTITY_LDAP_TLS_SKIP_VERIFY=on
export MINIO_IDENTITY_LDAP_SERVER_INSECURE=on
export MINIO_IDENTITY_LDAP_SERVER_STARTTLS=off
./minio gateway s3 https://cos.ap-beijing.myqcloud.com --console-address 0.0.0.0:9100
集成 LDAP 的好处就是不用单独开通帐号即可使用,但比较麻烦的是,只能通过命令行 mc 来对用户进行授权。而且当需要给公司外部人员开通帐号时,也必须得开通 LDAP 帐号,可能面临一定的风险。
集成 Audit Log 功能(审计日志)
默认情况下,当仅仅使用 MinIO 的 Gateway 功能时,Admin API 以及很多特性比如 Audit log 都是没有开放的。
这个时候就又到了改代码重新编译的时候。
首先是启用 Admin API,修改代码位置如下:
将下图所示地方改为 true:
然后重新编译即可。
下面是开启 Audit log。参见:https://github.com/minio/operator/tree/master/logsearchapi
按照文档步骤,启动 postgres 数据库,然后启动 logsearchapi 服务,这些都没有问题。
postgres启动:
docker run -d \
--name postgres \
-p 5432:5432 \
-e POSTGRES_PASSWORD="xxx" \
-e PGDATA=/var/lib/postgresql/data/pgdata \
-v /data/postgres:/var/lib/postgresql/data \
postgres:14.1 -c "log_statement=all"
logsearchapi启动(注意 logsearchapi 命令也是需要下载源码然后编译的)
export LOGSEARCH_PG_CONN_STR="postgres://postgres:xxx@localhost/postgres?sslmode=disable"
export LOGSEARCH_AUDIT_AUTH_TOKEN=logsearch_audit
export MINIO_LOG_QUERY_AUTH_TOKEN=logsearch_query
export LOGSEARCH_DISK_CAPACITY_GB=5
./logsearchapi
但当我尝试使用 mc admin 命令设置 aduit_webhook 参数时,却会出现莫名奇妙的错误,一番尝试后放弃,改用其他方式。
将如下代码加入启动脚本即可:
# audit log 功能
export MINIO_AUDIT_WEBHOOK_ENABLE_1="on" # audit log 功能
export MINIO_AUDIT_WEBHOOK_ENDPOINT_1="http://localhost:8080/api/ingest?token=logsearch_audit" # audit log 功能
export MINIO_LOG_QUERY_URL="http://localhost:8080"
export MINIO_LOG_QUERY_AUTH_TOKEN="logsearch_query"
export LOGSEARCH_QUERY_AUTH_TOKEN="logsearch_query"