跳转至

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. 启动服务

# 重新加载服务配置
systemctl daemon-reload
# 启动服务
systemctl enable --now rustfs

二. 访问验证并做基础配置

浏览器输入http://192.168.100.106:9001

alt text

默认的用户名密码均为rustfsadmin

注: 修改密码的方法是编辑 /etc/default/rustfs 中的RUSTFS_ACCESS_KEY/RUSTFS_SECRET_KEY,这里就不再做了

同样创建bucket

alt text

添加访问密钥

alt text

访问密钥为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

systemctl stop minio
systemctl disable minio

5) 彻底卸载MinIO服务

此时MinIO的数据还在本机保存,先保存几天,方便随时出现故障后进行切回

等确保数据无误后,就可以彻底清除MinIO了

dnf remove -y minio
rm -rf /data/minio /etc/default/minio

四. 总结

1. 整体架构

组件 角色 本实验部署位置
MinIO 对象存储服务端(源仓库) 主机5 192.168.100.103:9000
RustFS 对象存储服务端(目标仓库) 主机7 192.168.100.106:9000
mc 客户端命令行工具(搬运工) 主机5(装在哪台都行)

两个服务端 + 一个客户端工具,这就是完整架构。三者可各占一台主机,也可同机(同机注意两个服务端默认都监听 9000/9001,需错开端口)。

2. 三个关键概念

  1. mc 是"工具",不是"服务"
  2. 不常驻、无端口、不占资源,只是可执行文件;
  3. 装在哪台机器都行,只要网络能直达两个服务端、且持有正确的 Access Key;
  4. mc 连谁取决于 alias:每个 alias = 一个地址 + 一套 Access Key(myminio→MinIO、rustfs→RustFS)。
  5. MinIO 与 RustFS 之间没有自动连接,mc 是唯一的搬运工。

  6. 对象存储必须走 API,不能当普通文件夹用

  7. 合法入口:mc / 网页控制台 / SDK(都是 S3 API);
  8. 不要对数据目录(/data/minio、/data/rustfs0)直接用 shell 的 ls/rm/mkdir/touch——那是服务端内部格式(.minio.sys/.rustfs.sys 等),直接改动会损坏数据;
  9. 只有"物理备份/迁移"(整目录 tar/rsync)才直接碰数据目录,且必须先停服务。

  10. 迁移和备份命令相同,区别在终点

  11. 核心命令都是 mc mirror --overwrite 源 目标;
  12. 备份:MinIO 继续用,定期复制到 RustFS 当保险;
  13. 迁移:数据搬完后业务切换到 RustFS,最终下线 MinIO。

3. 迁移流程速览(MinIO → RustFS)

  1. 全量同步:mc mirror --overwrite myminio/test-bucket rustfs/test-bucket-rust
  2. 校验完整性:两端对象 md5 全部一致
  3. 停写 + 最后一次增量同步(补停写窗口的差异)
  4. 业务切换:客户端 endpoint 从 103:9000 改为 106:9000
  5. 验证 RustFS 读写正常
  6. 确认无误后下线 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 校验,切换后保留源数据几天再清理,才是安全的"后悔药"。