1. 探求 minio 和 s3 兼容性
调研使用minio
替换s3
的可行性分析. 根据现有业务特点测试内容如下:
- 对象操作: 可以使用现有的 s3 sdk 操作 minio 文件对象
- putObject
- deleteObject
- copyObject
- getObject
- headObject
- presignedUrl
- 对象事件: minio 的 bucket 可以添加事件监控对象操作
- 上传
- 删除
- awscli: 可以使用现有 s3 工具(awscli)操作 minio
- 生命周期: 可以设置生命周期, 例如自动过期删除
以上操作如可以通过 aws s3 sdk 和其他工具顺利操作 minio, 则证明可行.
2. 搭建环境
使用 docker-compose 启动搭建环境, 有两个主要的服务:
- minio 服务
- webhook 服务: 通过调研 minio 支持 Bucket 通知事件, 通知对象有很多种: AMQP/MQTT/NATS/Kafka/Mysql/PostgreSQL/Redis/Webhook 等, 这里选择 webhook
docker-compose.yaml 如下:
1 | version: "3.8" |
2.1 webhook 服务
因为 minio 部署在 docker 中, 为了 webhook 可以访问方便, 所以这里也把 webhook 服务部署到 docker, 让 wehhook 容器和 minio 容器在同一个网络下. webhook 相关代码如下:
webhook.js
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
27
28
29
30
31
32
33
34
35
36
37
38const express = require("express");
const jwt = require("jsonwebtoken");
const app = express();
app.use(express.json()); // for parsing application/json
app.use(express.urlencoded({ extended: true }));
const port = 6000;
const secret = "minio webhook secret";
app.post("/webhook", (req, res) => {
if (req.headers.authorization?.startsWith("Bearer")) {
const token = req.headers.authorization.split(" ")[1];
// 验证token
const data = jwt.verify(token, secret);
console.log("verify data: ", data);
// 获取参数, 例如删除对象事件如下:
/**
* 上传事件:
* {"EventName":"s3:ObjectCreated:Put","Key":"vd-main/Tile_+002_+002.mtl","Records":[{"eventVersion":"2.0","eventSource":"minio:s3","awsRegion":"","eventTime":"2024-01-05T11:26:33.408Z","eventName":"s3:ObjectCreated:Put","userIdentity":{"principalId":"minioadmin"},"requestParameters":{"principalId":"minioadmin","region":"","sourceIPAddress":"192.168.65.1"},"responseElements":{"x-amz-id-2":"dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af9251148b658df7ac2e3e8","x-amz-request-id":"17A76FE05CEBA939","x-minio-deployment-id":"c56dc51b-4b0a-41c0-ab16-7b990c2d51ad","x-minio-origin-endpoint":"http://172.19.0.2:9000"},"s3":{"s3SchemaVersion":"1.0","configurationId":"Config","bucket":{"name":"vd-main","ownerIdentity":{"principalId":"minioadmin"},"arn":"arn:aws:s3:::vd-main"},"object":{"key":"Tile_%2B002_%2B002.mtl","size":210,"eTag":"775ff5def9531772a2bb12853cd46fce","contentType":"application/octet-stream","userMetadata":{"content-type":"application/octet-stream"},"sequencer":"17A76FE05CF3469B"}},"source":{"host":"192.168.65.1","port":"","userAgent":"MinIO (linux; arm64) minio-go/v7.0.66 MinIO Console/(dev)"}}]}
* 删除事件:
* {"EventName":"s3:ObjectRemoved:Delete","Key":"vd-main/Tile_+002_+002.mtl","Records":[{"eventVersion":"2.0","eventSource":"minio:s3","awsRegion":"","eventTime":"2024-01-05T11:27:59.964Z","eventName":"s3:ObjectRemoved:Delete","userIdentity":{"principalId":"minioadmin"},"requestParameters":{"principalId":"minioadmin","region":"","sourceIPAddress":"127.0.0.1"},"responseElements":{"content-length":"164","x-amz-id-2":"dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af9251148b658df7ac2e3e8","x-amz-request-id":"17A76FF48418FD2E","x-minio-deployment-id":"c56dc51b-4b0a-41c0-ab16-7b990c2d51ad","x-minio-origin-endpoint":"http://172.19.0.2:9000"},"s3":{"s3SchemaVersion":"1.0","configurationId":"Config","bucket":{"name":"vd-main","ownerIdentity":{"principalId":"minioadmin"},"arn":"arn:aws:s3:::vd-main"},"object":{"key":"Tile_%2B002_%2B002.mtl","sequencer":"17A76FF4843A978E"}},"source":{"host":"127.0.0.1","port":"","userAgent":"MinIO (linux; arm64) minio-go/v7.0.66 MinIO Console/(dev)"}}]}
*/
console.log(JSON.stringify(req.body));
// TODO: 添加自定义业务
}
res.end();
});
app.listen(port, () => {
const token = jwt.sign(
{
user: 1,
},
secret
);
console.log(`token: ${token}`);
console.log(`webhook start at ${port}`);
});Dockerfile
1
2
3
4
5
6
7
8from node
WORKDIR /app
COPY ./webhook.js ./webhook.js
RUN npm install express jsonwebtoken
CMD node webhook.js
⚠️ 注意: 这两个文件的位置要和 docker-compose.yaml 中的 miniowebhook build 地址一样
2.2 启动服务
1 | docker compose up -d |
3. 测试
3.1 测试对象操作
使用 typescript 脚本测试对象的各种操作:
1 | import { PutObjectCommand, GetObjectCommand, S3 } from "@aws-sdk/client-s3"; |
运行该脚本查看测试结果是否 OK.
3.2 测试对象事件
这里需要一些操作: 1. 添加事件; 2. 将事件绑定到 bucket. 可以通过控制台配置, 配置方式如下:
‼️ 注意: Auth Token 可以自己使用
jsonwebtoken
生成一个不过期的 jwt token, 用于在 webhook 服务中验证来源是否合法
手动上传文件/删除文件查看 webhook 容器日志检查事件是否 OK
3.3 aws-cli 操作
添加 aws profile:
1 | [default] |
添加 credentials:
1 | [default] |
ℹ️ AK/SK 也可以从 http://localhost:9001/access-keys 中生成一份
测试 awscli 命令如下:
1 | -> aws s3 ls |
3.4 生命周期
通过控制台配置生命周期:
4. 总结
minio 基本上可以替换 s3, 并且在 s3 对象操作和事件上也有比较好的兼容, 推荐在云下使用.