天覆云适配Minio对象存储附件

天覆云搭建 MinIO 作为 S3 存储对接附件

本文记录一种常见方案:以 Ubuntu 24.04 上自建 MinIO,作为 S3 兼容对象存储,然后让附件读写切换到 MinIO。同时也说明已有平台附件如何从原存储迁移到新 MinIO 中。

一、整体架构

切换前:

1
2
天覆云
└── 默认内置文件存储 / 内置 MinIO

切换后:

1
2
3
4
天覆云
└── sc 文件服务
└── S3 API
└── 自建 MinIO

天覆云文件服务会通过 S3 协议访问 MinIO。只要对象的 bucket 映射和文件 key 保持一致,已有附件通常不需要修改数据库,只需要把对象文件迁移过去,并正确配置 s3-config.json

二、准备信息

假设环境如下:

1
2
3
4
服务器:<SERVER_IP>
MinIO 服务器:<MINIO_SERVER_IP>
MinIO S3 API 端口:9000
MinIO Console 管理端口:9001

注意:

  • 9000 是 S3 API 端口,给天覆云程序访问。
  • 9001 是 MinIO Web Console 管理端口,给管理员浏览器访问。
  • 天覆云的 bucketEndPoint 必须填写 S3 API 地址,不要填写 Console 地址。
  • 如果你对外映射了其他端口,例如 5405:9000,那配置里就要写 http://<MINIO_SERVER_IP>:5405

三、安装 Docker 和 Docker Compose

Ubuntu 24.04 推荐使用 Docker 官方 APT 源安装 Docker Engine 和 Compose 插件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
sudo apt update
sudo apt install -y ca-certificates curl

sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

sudo tee /etc/apt/sources.list.d/docker.sources >/dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

sudo systemctl enable --now docker
docker version
docker compose version

四、部署 MinIO

创建目录:

1
2
3
sudo mkdir -p /data/minio/data
sudo mkdir -p /data/minio/config
cd /data/minio

创建 .env 文件:

1
2
3
4
sudo tee .env >/dev/null <<'EOF'
MINIO_ROOT_USER=you_admin_account
MINIO_ROOT_PASSWORD=you_password
EOF

生产环境请务必把 MINIO_ROOT_PASSWORD 改成高强度密码。

创建 docker-compose.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
sudo tee docker-compose.yaml >/dev/null <<'EOF'
version: "3.8"

services:
minio:
image: minio/minio:latest
container_name: minio
restart: always
ports:
- "9000:9000"
- "9001:9001"
environment:
MINIO_ROOT_USER: you_account
MINIO_ROOT_PASSWORD: "you_password"
volumes:
- ./data:/data
- ./config:/root/.minio
command:
server /data --console-address ":9001"

启动 MinIO:

1
2
sudo docker compose up -d
sudo docker ps

验证 MinIO API:

1
curl -I http://127.0.0.1:9000/minio/health/live

如果返回 HTTP/1.1 200 OK,说明 MinIO API 正常。

浏览器访问:

1
http://<MINIO_SERVER_IP>:9001

登录账号密码就是 .env 里的:

1
2
MINIO_ROOT_USER
MINIO_ROOT_PASSWORD

五、天覆云需要哪些 bucket

天覆云当前主要使用 4 个逻辑 bucket:

1
2
3
4
mdmedia
mdpic
mdpub
mdoc

六、配置对接 MinIO

在服务器上,找到微服务目录。常见路径是:

1
cd /data/mingdao/script

创建 S3 配置目录:

1
mkdir -p /data/mingdao/script/volume/s3

创建 s3-config.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
tee /data/mingdao/script/volume/s3/s3-config.json >/dev/null <<'EOF'
{
"mode": 1,
"accessKeyID": "you_admin_account",
"secretAccessKey": "you_password",
"bucketEndPoint": "http://<MINIO_SERVER_IP>:9000",
"bucketName": {
"mdmedia": "bucketName",
"mdpic": "bucketName",
"mdpub": "bucketName",
"mdoc": "bucketName"
},
"region": "1",
"addressingModel": 1
}
EOF

这里有两个非常重要的点。

第一,bucketEndPoint 要带协议:

1
"bucketEndPoint": "http://<MINIO_SERVER_IP>:9000"

如果你的 MinIO 没有配置 HTTPS,就不要写 https://

第二,自建 MinIO 使用 IP 地址访问时,必须加:

1
"addressingModel": 1

这个参数会让天覆云使用 path-style 访问方式:

1
http://<MINIO_SERVER_IP>:9000/mdmedia/xxx.jpg

如果不加这个参数,程序可能会自动把 bucket 拼到 endpoint 前面,变成:

1
http://bucketName.<MINIO_SERVER_IP>:9000/xxx.jpg

如果 endpoint 是 IP 地址,就会出现类似这样的 DNS 错误:

1
lookup mdmedia.192.168.1.10 on 127.0.0.11:53: no such host

七、挂载 s3-config.json 到 sc 容器

编辑 docker-compose.yaml,找到 sc 服务,添加挂载:

1
2
3
4
5
services:
sc:
volumes:
- ./volume/data/:/data/
- ./volume/s3/s3-config.json:/usr/local/file/s3-config.json

核心是这一行:

1
- ./volume/s3/s3-config.json:/usr/local/file/s3-config.json

天覆云文件服务会从容器内的这个路径读取 S3 配置:

1
/usr/local/file/s3-config.json

修改后重启微服务:

1
2
cd /home/skyinfor/mdy
bash service.sh restartall

验证配置是否已经挂载进容器:

1
docker exec -it script-sc-1 sh -lc 'cat /usr/local/file/s3-config.json'

八、验证新附件是否写入 MinIO

1、进入平台页面,上传一个附件或图片,然后在 MinIO web界面中查看对应 bucketName下 是否出现新文件。如果新上传的文件已经进入 MinIO,说明附件已经成功切换到自建 S3 存储。
2、登录平台查看头像,应用icon是否正常显示

九、已有天覆云附件如何迁移到新 MinIO

如果是已经运行了一段时间的天覆云,切换 S3 前必须迁移历史附件。迁移原则是:

1
2
3
4
1、内网/公网之间网络互通
2、保证磁盘空间有可用冗余
3、停止服务
4、检查kafka工作流是否有堆积消息

前置条件

1、检查单机版本老环境的 kafka 队列有无消息堆积

1
docker exec -it $(docker ps | grep mingdaoyun-sc | awk '{print $1}') bash

2、检查当前容器内是否有 minio 进程

1
ps aux|grep [m]inio
  • 如果有输出,代表当前容器内运行的文件存储服务是 V2 版本
  • 如果没有输出,代表代表当前容器内运行的文件存储服务是 V1 版本
  • 后续迁移文件存储服务时,V1 与 V2 的迁移步骤会有不同
    3、检查 kafka 工作流队列有无堆积
    1
    /usr/local/kafka/bin/kafka-consumer-groups.sh --bootstrap-server ${ENV_KAFKA_ENDPOINTS:=127.0.0.1:9092} --describe --group md-workflow-consumer | awk '{count+=$6}END{print count}'
  • 仅输出 0 代表无堆积,可以立刻停止微服务
  • 输出的数字大于 0 代表当前队列中有工作流消息待消费
  • 如果在队列中有未消费的数据时停止了微服务,在做完数据迁移,新环境会有某些工作流一直显示排队数字不消失,这些显示排队的流程不会继续消费

在安装管理器所在目录执行停止微服务命令

1
2
cd /home/skyinfor/mdy
bash service.sh stopall

启动临时容器

单独启动挂载数据目录的容器

1
docker run -itd --entrypoint bash --rm -v /data/mingdao/script/volume/data/:/data/ 788b6f437789
  • 788b6f437789 为存储组件 sc 的镜像ID,可通过 docker images 查看

进入刚启动的临时容器

1
docker exec -it 363625b14db6 bash

在临时容器内分别启动 mysql、mongodb、file

1
2
3
source /entrypoint.sh  && mysqlStartup &
source /entrypoint.sh && mongodbStartup &
source /entrypoint.sh && filev1Run &

如果容器内运行的文件存储服务是 V2 版本,也要额外启动下 minio 服务

1
2
echo "127.0.0.1 sc" >> /etc/hosts
source /entrypoint.sh && minioStartup &

1. 使用 mc 迁移 bucket

在临时创建的容器内配置集群环境文件存储信息

1
2
mc alias set minio_old  http://127.0.0.1:9010 mdstorage eBxExGQJNhGosgv5FQJiVNqH
mc alias set minio_new http://你的ip:9000 you_account you_password
  • minio_old 中的地址、认证信息无需修改
  • minio_new 中的IP与端口及认证信息注意替换为实际新环境的 minio 服务的访问地址与认证信息

开始迁移:

1
2
3
4
mc mirror minio_old/mdmedia minio_new/you_bucketName
mc mirror minio_old/mdoc minio_new/you_bucketName
mc mirror minio_old/mdpic minio_new/you_bucketName
mc mirror minio_old/mdpub minio_new/you_bucketName

十、常见问题排查

1. 报错:lookup bucket.ip on 127.0.0.11 no such host

例如:

1
lookup jsmdy.10.250.1.162 on 127.0.0.11:53: no such host

原因是程序使用了 virtual-host-style,把 bucket 拼到了 endpoint 前面:

1
jsmdy.10.250.1.162

IP 地址不能这样解析。

解决方法是在 s3-config.json 中增加:

1
"addressingModel": 1

并确保 endpoint 是:

1
"bucketEndPoint": "http://10.250.1.162:9000"

2. 报错:wrong version number

通常是把 HTTP 的 MinIO 配成了 HTTPS。

例如 MinIO 实际是:

1
http://10.250.1.162:9000

但配置成了:

1
https://10.250.1.162:9000

解决方法:没有配置 TLS 时,bucketEndPoint 使用 http://

3. 连接失败 connection refused

检查端口是不是写错了。

MinIO 默认:

1
2
9000:S3 API
9001:Console 管理后台

天覆云要访问的是 S3 API 端口,不是 Console 端口。

4. AccessDenied 或 SignatureDoesNotMatch

通常是以下原因:

  • access key 写错
  • secret key 写错
  • bucket 权限不足
  • endpoint 写错
  • 服务器时间偏差太大

可以先在服务器或 sc 容器内测试:

1
curl -I http://<MINIO_SERVER_IP>:9000/minio/health/live

再用 mc 测试账号是否能访问:

1
2
mc alias set new http://<MINIO_SERVER_IP>:9000 <ACCESS_KEY> <SECRET_KEY>
mc ls new

十一、生产环境建议

  1. 不要在公网暴露 MinIO Console,或者至少限制访问 IP。
  2. MinIO root 账号只用于管理,建议使用单独的 access key。
  3. MinIO 数据目录要做磁盘监控和备份。
  4. 切换 S3 前,先完整迁移历史附件。
  5. 切换后上传、预览、下载都验证无误,再下线旧文件存储。
  6. 使用 IP 访问自建 MinIO 时,一定要配置 "addressingModel": 1
  7. bucketEndPoint 一定要写 S3 API 地址,不要写 MinIO Console 地址。

十二、最终配置示例

MinIO 使用 4 个独立 bucket 时,推荐配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"mode": 1,
"accessKeyID": "mdy_s3_admin",
"secretAccessKey": "ChangeMe_StrongPassword_2026",
"bucketEndPoint": "http://<MINIO_SERVER_IP>:9000",
"bucketName": {
"mdmedia": "saas",
"mdpic": "saas",
"mdpub": "saas",
"mdoc": "saas"
},
"region": "1",
"addressingModel": 1
}

如果 MinIO API 通过宿主机端口映射成了 5405,则写成:

1
"bucketEndPoint": "http://<MINIO_SERVER_IP>:5405"

记住:这里必须是 API 端口,不是 Console 端口。迁移完成后重启微服务,访问平台即可。

-------------本文结束感谢您的阅读-------------
0%