RustFS部署以及迁移¶
一. 部署RustFS¶
RustFS在7上部署
1. 事先准备¶
a. 准备存放数据的磁盘
先添加一块
# 首先,需要查看磁盘系统的情况:
[root@7 ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sr0 11:0 1 12G 0 rom
nvme0n1 259:0 0 80G 0 disk
├─nvme0n1p1 259:1 0 1G 0 part /boot
└─nvme0n1p2 259:2 0 79G 0 part
├─rl-root 253:0 0 51.7G 0 lvm /
├─rl-swap 253:1 0 2G 0 lvm [SWAP]
└─rl-home 253:2 0 25.3G 0 lvm /home
nvme0n2 259:3 0 10G 0 disk
# 格式化磁盘
[root@7 ~]# mkfs.xfs -i size=512 -n ftype=1 -L RUSTFS0 /dev/nvme0n2
meta-data=/dev/nvme0n2 isize=512 agcount=4, agsize=655360 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=1, sparse=1, rmapbt=0
= reflink=1 bigtime=1 inobtcount=1 nrext64=0
data = bsize=4096 blocks=2621440, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0, ftype=1
log =internal log bsize=4096 blocks=16384, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
b. 挂载磁盘
# 注: 此时尚未写 rustfs.service, 这里的 daemon-reload 无意义可省略;
# tee -a 是追加写入, 重复执行本段会给 /etc/fstab 添加重复行, 重跑前先清理旧行
mkdir -p /data/rustfs0
cat << 'EOF'|tee -a /etc/fstab
LABEL=RUSTFS0 /data/rustfs0 xfs defaults,noatime,nodiratime 0 0
EOF
mount -a
c. 配置用户
# 注: 服务文件将以 User=root 运行, 这里创建的 rustfs-user 实际不会被使用,
# 实验环境可跳过本步。若希望以低权限用户运行, 需同步把服务文件改为
# User=rustfs-user / Group=rustfs-user, 并 chown /var/log/rustfs。
groupadd -r rustfs-user
useradd -M -r -g rustfs-user rustfs-user
chown rustfs-user:rustfs-user /data/rustfs*
2. 下载安装包¶
# 下载地址
wget https://dl.rustfs.com/artifacts/rustfs/release/rustfs-linux-x86_64-musl-latest.zip
unzip rustfs-linux-x86_64-musl-latest.zip
chmod +x rustfs
mv rustfs /usr/local/bin/
# 【必做】从家目录 mv 来的二进制 SELinux 上下文是 admin_home_t,
# systemd 启动会报 203/EXEC 无法执行, 需重置为 bin_t (Rocky 默认 Enforcing)
restorecon /usr/local/bin/rustfs
3. 配置环境变量和存储目录,写服务文件¶
# 单机单盘模式
tee /etc/default/rustfs <<EOF
RUSTFS_ACCESS_KEY=rustfsadmin
RUSTFS_SECRET_KEY=rustfsadmin
RUSTFS_VOLUMES="/data/rustfs0"
RUSTFS_ADDRESS=":9000"
RUSTFS_CONSOLE_ENABLE=true
RUST_LOG=error
RUSTFS_OBS_LOG_DIRECTORY="/var/log/rustfs/"
EOF
# 创建存储目录 (/opt/tls 本示例未配置 TLS, 无需创建)
sudo mkdir -p /data/rustfs0 /var/log/rustfs
sudo chmod -R 750 /data/rustfs* /var/log/rustfs
# 写入服务文件
sudo tee /etc/systemd/system/rustfs.service <<EOF
[Unit]
Description=RustFS Object Storage Server
Documentation=https://rustfs.com/docs/
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
NotifyAccess=main
User=root
Group=root
WorkingDirectory=/usr/local
EnvironmentFile=-/etc/default/rustfs
ExecStart=/usr/local/bin/rustfs \$RUSTFS_VOLUMES
LimitNOFILE=1048576
LimitNPROC=32768
TasksMax=infinity
Restart=always
RestartSec=10s
OOMScoreAdjust=-1000
SendSIGKILL=no
TimeoutStartSec=30s
TimeoutStopSec=30s
NoNewPrivileges=true
ProtectHome=true
PrivateTmp=true
PrivateDevices=true
ProtectClock=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictSUIDSGID=true
RestrictRealtime=true
# service log configuration
# 注意: 不要设置 StandardOutput/StandardError 指向 RUSTFS_OBS_LOG_DIRECTORY 相同目录!
# RustFS 自身滚动日志会写到 /var/log/rustfs/rustfs.log, 若 systemd 的 stdout 也重定向
# 到同名文件, 程序启动会 FATAL 报 "Log sink conflict" 而失败。
# 正确做法: 不设置这两行, 让 stdout 走默认 journald, 查看日志用: journalctl -u rustfs
[Install]
WantedBy=multi-user.target
EOF
4. 启动服务¶
二. 访问验证并做基础配置¶
浏览器输入http://192.168.100.106:9001

默认的用户名密码均为rustfsadmin
注: 修改密码的方法是编辑 /etc/default/rustfs 中的RUSTFS_ACCESS_KEY/RUSTFS_SECRET_KEY,这里就不再做了
同样创建bucket

添加访问密钥

访问密钥为3QIQj4C4BFHauXewkaFa;密钥为1GNmqKaBoVIMV7lXFOV0fqKI5LcpcNuavWPesLDZ
三. 将MinIO的数据迁移至RustFS¶
因为mc工具在5上,我们就全程在5上操作了
1. 给5上的mc添加认证¶
# (待 RustFS 部署完成、在其网页创建 Access Key 后) 配置 RustFS 连接
# 有了这个别名, mc 才能把 MinIO 的数据搬到 RustFS
mc alias set rustfs http://192.168.100.106:9000 \
3QIQj4C4BFHauXewkaFa 1GNmqKaBoVIMV7lXFOV0fqKI5LcpcNuavWPesLDZ
2. 确认两端的桶¶
[root@5 ~]# mc ls myminio/ # 源:MinIO 上的桶(test-bucket)
mc ls rustfs/ # 目标:RustFS 上的桶(test-bucket-rust)
[2026-09-04 08:22:00 CST] 0B test-bucket/
[2026-09-04 10:09:06 CST] 0B test-bucket-rust/
3. 全量同步¶
[root@5 ~]# mc mirror --overwrite myminio/test-bucket rustfs/test-bucket-rust
...bucket/logs/app.log: 85.00 MiB / 85.00 MiB ┃▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓┃ 85.94 MiB/s 0s[root@5 ~]# ░░░░░░░░░░░░░░░░░░░░▓┃
4. 校验完整性¶
[root@5 ~]# # 抽查对象,两端 md5 一致才算迁移完整
mc cat myminio/test-bucket/docs/report1.pdf | md5sum
mc cat rustfs/test-bucket-rust/docs/report1.pdf | md5sum
efc242e9123476f5c160c20bbe8fddd4 -
efc242e9123476f5c160c20bbe8fddd4 -
或者用以下脚本逐个检查
# 主机5,逐个对象对比两端 md5
for f in docs/report1.pdf docs/report2.pdf images/photo1.jpg images/photo2.jpg logs/app.log; do
src=$(mc cat myminio/test-bucket/$f | md5sum | awk '{print $1}')
dst=$(mc cat rustfs/test-bucket-rust/$f | md5sum | awk '{print $1}')
[ "$src" = "$dst" ] && echo "✅ $f" || echo "❌ $f 不一致"
done
5. 增量同步¶
若同步时没停机,有新写入内容,则可以在此时进行停机进行增量同步
# 关闭服务
systemctl stop minio
# 增量同步
mc mirror --overwrite myminio/test-bucket rustfs/test-bucket-rust
6. 完整业务切换¶
1) 让mc改成连接RustFS¶
# 主机5:给"新后端"配个别名(也可直接沿用 rustfs)
mc alias set minio-new http://192.168.100.106:9000 \
3QIQj4C4BFHauXewkaFa 1GNmqKaBoVIMV7lXFOV0fqKI5LcpcNuavWPesLDZ
# 业务端以后就访问: http://192.168.100.106:9000, 桶 test-bucket-rust
mc ls minio-new/test-bucket-rust
2) 验证 RustFS 能正常对外服务(读写都测)¶
[root@5 ~]# mc ls --recursive rustfs/test-bucket-rust
[2026-09-04 10:37:26 CST] 5.0MiB STANDARD docs/report1.pdf
[2026-09-04 10:37:27 CST] 20MiB STANDARD docs/report2.pdf
[2026-09-04 10:37:26 CST] 2.0MiB STANDARD images/photo1.jpg
[2026-09-04 10:37:26 CST] 8.0MiB STANDARD images/photo2.jpg
[2026-09-04 10:37:27 CST] 50MiB STANDARD logs/app.log
3) 测试写入能力¶
# 写入一个简单文件
[root@5 ~]# echo "switch-over test" | mc pipe rustfs/test-bucket-rust/verify.txt
0 B / ? ┃░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▓┃17 bytes -> `rustfs/test-bucket-rust/verify.txt`
# 查看是否写入
[root@5 ~]# mc cat rustfs/test-bucket-rust/verify.txt
switch-over test
# 删除
[root@5 ~]# mc rm rustfs/test-bucket-rust/verify.txt
Removed `rustfs/test-bucket-rust/verify.txt`.
4) 下线MinIO¶
5) 彻底卸载MinIO服务¶
此时MinIO的数据还在本机保存,先保存几天,方便随时出现故障后进行切回
等确保数据无误后,就可以彻底清除MinIO了
四. 总结¶
1. 整体架构¶
| 组件 | 角色 | 本实验部署位置 |
|---|---|---|
| MinIO | 对象存储服务端(源仓库) | 主机5 192.168.100.103:9000 |
| RustFS | 对象存储服务端(目标仓库) | 主机7 192.168.100.106:9000 |
| mc | 客户端命令行工具(搬运工) | 主机5(装在哪台都行) |
两个服务端 + 一个客户端工具,这就是完整架构。三者可各占一台主机,也可同机(同机注意两个服务端默认都监听 9000/9001,需错开端口)。
2. 三个关键概念¶
- mc 是"工具",不是"服务"
- 不常驻、无端口、不占资源,只是可执行文件;
- 装在哪台机器都行,只要网络能直达两个服务端、且持有正确的 Access Key;
- mc 连谁取决于
alias:每个 alias = 一个地址 + 一套 Access Key(myminio→MinIO、rustfs→RustFS)。 -
MinIO 与 RustFS 之间没有自动连接,mc 是唯一的搬运工。
-
对象存储必须走 API,不能当普通文件夹用
- 合法入口:mc / 网页控制台 / SDK(都是 S3 API);
- 不要对数据目录(
/data/minio、/data/rustfs0)直接用 shell 的ls/rm/mkdir/touch——那是服务端内部格式(.minio.sys/.rustfs.sys等),直接改动会损坏数据; -
只有"物理备份/迁移"(整目录 tar/rsync)才直接碰数据目录,且必须先停服务。
-
迁移和备份命令相同,区别在终点
- 核心命令都是
mc mirror --overwrite 源 目标; - 备份:MinIO 继续用,定期复制到 RustFS 当保险;
- 迁移:数据搬完后业务切换到 RustFS,最终下线 MinIO。
3. 迁移流程速览(MinIO → RustFS)¶
- 全量同步:
mc mirror --overwrite myminio/test-bucket rustfs/test-bucket-rust - 校验完整性:两端对象 md5 全部一致
- 停写 + 最后一次增量同步(补停写窗口的差异)
- 业务切换:客户端 endpoint 从
103:9000改为106:9000 - 验证 RustFS 读写正常
- 确认无误后下线 MinIO,源数据保留几天作为回滚保险再清理
4. 本实验踩过的坑(RockyLinux + SELinux 环境)¶
| 报错/现象 | 根因 | 解决 |
|---|---|---|
MinIO 服务 217/USER |
服务文件 User=minio-user 不存在 |
先 useradd 创建该用户 |
RustFS 209/STDOUT |
日志目录用非标准 /var/logs,SELinux 上下文是 var_t |
改用标准 /var/log/rustfs |
RustFS 203/EXEC |
二进制从家目录 mv 进来,上下文是 admin_home_t |
restorecon /usr/local/bin/rustfs |
RustFS Log sink conflict |
服务文件 StandardOutput 与自身滚动日志同名 |
不设置该行,走 journald |
| mc 下载下来是 141 字节 | dl.min.io 需跟随重定向 |
curl -fSL;主机上不了 github 就本机下载后 scp |
排查口诀:systemd 报 Permission denied 但权限正常 → 99% 是 SELinux(
getenforce/ls -Z/ 查audit.log)。
5. 心得¶
- "在 MinIO 还是 RustFS 上操作"是伪命题:只要一台装有 mc、且能连两端的机器即可发起迁移/备份;
- 迁移前务必做 md5 校验,切换后保留源数据几天再清理,才是安全的"后悔药"。