
RustFS 是用 Rust 从头写的分布式对象存储,S3 全兼容,企业级功能也齐;一条 Docker 命令跑起来,会 AWS SDK 就会用它。
它凭什么火
RustFS 的定位很直白:把 MinIO 简单好用的部分留下,把短板补齐。
MinIO 在国内的私有云和内部平台里用得很多,但它采用 AGPL 许可,集成进商业产品时有额外的合规顾虑,所以不少团队开始找替代方案,RustFS 是其中讨论度比较高的一个。
- 性能上,Rust 实现没有 GC 停顿,官方压测对比 MinIO 优势明显;
- 许可上,Apache 2.0,商用没什么顾虑;
- 功能上,纠删码、Bitrot 防护、自动修复、WORM、SSE 加密和 KMS、生命周期分层、复制、Web 控制台、K8s Helm 一个不缺。
展开说一句:纠删码和 Bitrot 防护管的是数据可靠性,坏盘换新后能自动修复;WORM 和 SSE 面向合规、加密场景;生命周期分层可以把长时间不访问的数据自动迁到更便宜的后端;站点复制用来做异地容灾。对大多数内部平台来说,这些能力已经够用,不需要再自己拼一套。
选 Rust 也不只是营销话术。对象存储的瓶颈大多在磁盘和网络,但语言层面的 GC 停顿、内存占用会直接反映到尾延迟上,没有 GC 意味着 P99 更稳。对线上服务来说,这种确定性往往比峰值吞吐更有价值。
装起来也不复杂。官方仓库里 Helm chart、Docker Compose 示例,跟着现成文件改就行,这一点对运维同学比较友好。
一条命令跑起来
先建目录并授权。镜像里的 RustFS 以非 root 用户 rustfs(UID/GID 10001)运行,bind mount 挂进去的目录必须对它可写,否则启动时会直接报权限错误:
bash
mkdir -p /opt/rustfs/data /opt/rustfs/log && chown -R 10001:10001 /opt/rustfs/data /opt/rustfs/log
docker run -d -p 9000:9000 -p 9001:9001 \
-v /opt/rustfs/data:/data -v /opt/rustfs/logs:/logs rustfs/rustfs:latest
9000 是 S3 API 端口,9001 是 Web 控制台。浏览器打开 http://localhost:9001,默认账号密码都是 rustfsadmin,登录后就能建 bucket、传文件。默认密码上线前必须改,账号密钥可以用 RUSTFS_ACCESS_KEY、RUSTFS_SECRET_KEY 两个环境变量指定。

容器起来后可以用 docker ps 确认状态,docker logs 里会打印数据目录初始化和端口监听的信息;控制台能正常登录,基本就说明这套部署没问题了。
两个小建议:生产环境别用 latest 标签,换成具体版本号,出问题方便回滚;数据和日志目录都要持久化,容器重建、升级时数据才不会丢。
如果本机有多块盘,RUSTFS_VOLUMES 支持展开写法,/data/disk{0...3} 会被解析成 4 个独立目录,每块盘挂一个:
bash
docker run -d -p 9000:9000 -p 9001:9001 \
-e RUSTFS_VOLUMES="/data/disk{0...3}" \
-v /mnt/disk1:/data/disk0 -v /mnt/disk2:/data/disk1 \
-v /mnt/disk3:/data/disk2 -v /mnt/disk4:/data/disk3 \
rustfs/rustfs:latest
不用 Docker 的话,官方也有裸机一键脚本:curl -O https://rustfs.com/install_rustfs.sh && bash install_rustfs.sh。
SDK 接入:会 AWS SDK,就会用它
标准 S3 兼容 = 任何 AWS SDK、aws-cli、mc 只改 endpoint 就能用,分片上传、预签名 URL 这些常见能力也都支持。以 Python 为例,先装 SDK:
bash
pip install boto3
装好之后就能直接用:
python
import boto3
from botocore.config import Config
s3 = boto3.client("s3",
endpoint_url="http://localhost:9000",
aws_access_key_id="rustfsadmin", aws_secret_access_key="rustfsadmin",
region_name="us-east-1",
config=Config(s3={"addressing_style": "path"})) # 关键一行
s3.upload_file("hello.txt", "demo", "hello.txt")
那行 addressing_style 必须设成 path。默认的 virtual-host 风格会把 bucket 名拼进域名,本地部署解析不到,直接报 NoSuchBucket 或者 301,这也是从 MinIO 迁过来的同学最常问的问题。示例里的 demo 是 bucket 名,第一次使用前要先建好,控制台里点一下就行。
习惯命令行的可以换 aws-cli,效果一样:
bash
pip install awscli
export AWS_ACCESS_KEY_ID=rustfsadmin
export AWS_SECRET_ACCESS_KEY=rustfsadmin
export AWS_DEFAULT_REGION=us-east-1
aws --endpoint-url http://localhost:9000 s3 mb s3://demo
aws --endpoint-url http://localhost:9000 s3 cp hello.txt s3://demo/
aws --endpoint-url http://localhost:9000 s3 ls s3://demo
Go / Java / Node / Rust 同理,改 endpoint、开 path-style,代码一行不用动。
如果用 mc 更顺手,配置一条 alias 就能用:mc alias set rustfs http://localhost:9000 rustfsadmin rustfsadmin,之后的 mc ls、mc cp、mc mirror 都是现成的。
从单机到集群
单机跑通之后,往集群扩就是换一行配置:把 RUSTFS_VOLUMES 从本地路径改成节点地址列表,比如
bash
RUSTFS_VOLUMES=http://node{1...4}:9000/data/rustfs{0...3}
表示 4 个节点、每节点 4 块盘。扩容、下线、节点恢复都在这套拓扑上做,控制台里能看到节点和磁盘的状态,换盘之后数据会自动重建,不用手工搬。K8s 环境可以直接用官方 Helm chart,集群拓扑会按集群信息自动生成。
对外提供服务之前,还有三个收尾动作:改掉默认密钥(RUSTFS_ACCESS_KEY / RUSTFS_SECRET_KEY)、挂上 TLS 证书(RUSTFS_TLS_PATH)、把指标接进现有监控(自带指标采集,支持 OTLP 导出)。
从 MinIO 迁过来的团队,常见做法是先把 RustFS 跑起来,用 mc mirror 这类工具把数据拷过来,业务侧改完 endpoint 后逐步切换流量,新旧集群并行一段时间,验证没问题再下线旧的。整个迁移过程里,对上层应用来说只是换了个地址。
几个常见问题
容器启动后立刻退出,日志里报 permission denied:基本是挂载目录的属主不对。回到第一步把 data、logs 改成 10001:10001,或者运行容器时用 --user 指定当前用户。
调用报 NoSuchBucket 或 301:先检查客户端有没有开 path-style。boto3 是 addressing_style 配置,其他语言 SDK 也是类似的选项,本地部署报这两个错误,十有八九是这里。
控制台打不开:确认 9001 端口映射了、防火墙放行了。如果暂时用不到控制台,可以在启动参数里加 RUSTFS_CONSOLE_ENABLE=false,只留 9000 上的 S3 API。
数据存在哪、会不会丢:对象全部落在挂载进容器的 /data 目录,容器删了数据还在,只有宿主目录被删才会丢。日志建议也持久化到 /logs,排查问题时方便。
还要不要再做备份:存储本身有冗余和自动修复,但对付不了误删和整个机房故障,重要数据的异地副本、版本控制该配还是要配。
谁适合用
AI 数据湖团队、自建私有云的公司、跑 K8s 的运维:部署一条命令,迁移只换 endpoint。数据量不大时一台机器几块盘就能起步,后面慢慢加节点,架构不用推倒重来;已经在用 MinIO 的团队想换个许可更宽松的方案,改个 endpoint 就能先跑起来对比。
写在最后
从单机到多节点多盘、扩容下线、分层归档,整条链路都齐,官方文档也有中文版。项目迭代节奏挺快,Helm chart、监控、TLS 这些周边都在持续补齐,遇到问题直接去 GitHub 上提 issue 就行。