前言
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 探测失败。
日志如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| """ ---------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 官方以及腾讯云官方都不做修改的情况下,只能通过修改源码重新编译来解决问题。
代码修改位置如下:
https://github.com/minio/minio/cmd/gateway/s3/gateway-s3.go
将其中的 randString 函数返回值修改为数字后缀,比如下图:
然后编译即可。
使用独立帐号体系
默认情况下,MinIO 自带一套帐号管理体系,不需要任何配置,但缺点是一旦服务重启则帐号信息丢失。
为了持久化存储帐号数据,需要配合 Etcd 服务。
Etcd部署参见:
https://github.com/etcd-io/etcd/releases
MinIO Gateway 启动方式如下:
1 2 3 4 5 6 7
| #!/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
启动方式如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
| #!/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,修改代码位置如下:
https://github.com/minio/minio/cmd/gateway-main.go
将下图所示地方改为 true:
然后重新编译即可。
下面是开启 Audit log。参见:https://github.com/minio/operator/tree/master/logsearchapi
按照文档步骤,启动 postgres 数据库,然后启动 logsearchapi 服务,这些都没有问题。
postgres启动:
1 2 3 4 5 6 7
| 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 命令也是需要下载源码然后编译的)
1 2 3 4 5
| 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 参数时,却会出现莫名奇妙的错误,一番尝试后放弃,改用其他方式。
将如下代码加入启动脚本即可:
1 2 3 4 5 6
| # 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"
|