第 129 期·对象存储·Rust·Apache-2.0
背景不用多解释。MinIO 社区版这几年一直在往回收:许可从 Apache-2.0 换成 AGPLv3;2025 年上半年把社区版 Web 控制台里的用户、策略、桶、配置管理整块删掉,只留下一个对象浏览器(据 Blocks and Files 等公开报道,官方给的理由是维护两套控制台成本太高,而缺乏专人维护的管理界面本身会引入安全风险);随后社区版停止在 Docker Hub 发布镜像与预编译二进制;到 2025 年 12 月 3 日,社区仓库被置为维护模式。对已经在用的人来说,这已经不是技术问题,而是我依赖的东西正在被一点点拿走。
一、它到底是做什么的
项目是 rustfs/rustfs,用 Rust 写的分布式对象存储,仓库主题里直接把 minio、s3、object-storage、ai-native 都挂上了。README 开头把自己的定位讲得很直白:
RustFS is a high-performance, distributed object storage system built in Rust—one of the most loved programming languages worldwide. RustFS combines the simplicity of MinIO with the memory safety and raw performance of Rust.
接着它把许可这件事单独拎出来讲了一句:
Unlike other storage systems, RustFS is released under the permissible Apache 2.0 license, avoiding the restrictions of AGPL.
功能面上,README 用一张状态表把能力分成两档:标成 Available 的是已经随包发布、并且有 CI 门禁覆盖的;标成 Preview 的是要靠开关打开、或者只在受限范围内承诺兼容。已经可用的那一档相当齐:单机与分布式、版本控制、Bitrot 保护、Object Lock(WORM)、Healing 与 Scanner、服务端加密、Bucket 复制、生命周期管理、生命周期分层到远端 S3、Bucket 配额、IAM 与策略、OIDC 单点登录、多租户、Web 控制台、K8s Helm Chart、事件通知,另有 OpenStack Swift API 与 Keystone 认证。
服务端加密这块它单独写了一句限定:KMS 后端里 Vault(KV2 与 Transit)和 AWS KMS 可以用于生产,而 Local 与 Static 两个后端只供开发和测试。换句话说,想开加密又不想把密钥交出去之前,先确认自己的 KMS 后端属于哪一档。
默认端口沿用对象存储的惯例:9000 给 S3 接口,9001 给 Web 控制台。它对外强调的是能与 MinIO、Ceph 之类已有的 S3 平台共存、并支持迁移。
二、怎么用:一条 docker run,加一次 chown
README 的快速开始给了六条路(一键脚本、Docker、源码构建、Helm、Nix、x-cmd),最省事的是 Docker 那条。但它在命令之前先加了一段提醒,这段提醒正是最容易踩的地方:容器不是以 root 跑的,而是以非 root 用户 rustfs(UID 与 GID 都是 10001)运行,所以每一个绑定挂载的宿主目录都必须对 10001 可写,否则启动会直接以权限拒绝告终。
README 给出的原命令是这样,注意 chown 那行不是可选步骤:
# Create data and logs directories mkdir -p data logs # Change the owner of these directories chown -R 10001:10001 data logs # Using latest version docker run -d -p 9000:9000 -p 9001:9001 -v $(pwd)/data:/data -v $(pwd)/logs:/logs rustfs/rustfs:latest # Using specific version docker run -d -p 9000:9000 -p 9001:9001 -v $(pwd)/data:/data -v $(pwd)/logs:/logs rustfs/rustfs:1.0.0-rc.6
如果在用 podman,README 给的是同一套参数,只在挂载上加两个标志位让 podman 自己处理属主:
podman run -d -p 9000:9000 -p 9001:9001 -v $(pwd)/data:/data:Z,U -v $(pwd)/logs:/logs:Z,U rustfs/rustfs:latest
用 Compose 的话,仓库根目录里那份简化版文件是:
docker compose -f docker-compose-simple.yml up -d
起来之后的三步 README 也写好了:浏览器打开 9001 端口进控制台,默认账号密码是 rustfsadmin 与 rustfsadmin,进去建一个桶,然后从控制台上传对象,或者直接用 S3 客户端接。这里顺一句:默认口令等于没有口令,控制台别裸暴露在公网。
另外 README 还给了两条容易忽略的前提。一是单机单盘部署只能作为独立本地路径存在,既不能原地扩容、也不能当作一个 Pool 加进已有集群,要换多盘拓扑只能新起一套再从 S3 迁数据;二是想开 webhook 通知的话,从 1.0.0-beta.11 起,指向私有网络或容器网络的 webhook 端点默认是被拦的,必须把 scheme://host:port 这个精确来源写进 RUSTFS_OUTBOUND_ALLOW_ORIGINS 才放行。
需要说明:本文未安装、未实机验证,以上步骤均为 README 原文转述,实际操作请以官方文档为准。
三、优点:许可干净,控制台没被砍,协议面更宽
- 许可是 Apache-2.0:这是它跟 MinIO 最大的分野。Apache-2.0 没有网络使用即触发的传染条款,把对象存储嵌进自己的服务或产品里,不用先找法务评估要不要开源自己的代码;
- 控制台功能完整:README 的对比表把自己这一列写成功能完整的控制台,把对照那一列写成功能有限或缺少关键能力。对照 MinIO 社区版被砍到只剩对象浏览器这件事,这一条的实用价值比任何性能数字都高;
- Rust 单二进制:部署面小,没有运行时依赖,容器镜像里不用再塞一层虚拟机或 JVM;
- 协议面比同类宽:除了 S3,还给了 OpenStack Swift API 与 Keystone 认证,另有 FTPS、WebDAV、SFTP 这些非 S3 通道,老系统对接时有得选;
- 与现役 S3 平台共存:官方强调可以和 MinIO、Ceph 共存与迁移,这意味着可以先用一套新的跑影子流量,而不是一次性切换;
- 发版节奏密:从 beta 到 rc 再到 preview,最近这十个 Release 基本是一周一版,修复是能等到的。
四、缺点:它自己还没到 GA,而数据类项目最怕的就是这个
先说最硬的一条:抓到的最近十个 Release 全部标记为预发布,一个正式版都没有,而 issue 里最新的几条正指着当前版本。这一点在下面单独一节展开。除了版本状态,还有几类问题是这段时间的问题单里反复出现的:
- 版本之间会出现回归:#7702 报告 1.0.0-rc.6 在 S3 突发流量之后申请的内存一直不释放,1 GiB 限额的实例当晚就被 OOMKilled,而同一个实例在 rc.5 上连续九晚是稳的。这类问题意味着升级要敢回滚、也要有回滚的版本;
- 数据完整性类的报错还没绝迹:#7674 说 part missing or corrupt 在补丁之后又换了一条代码路径复现,且观察不到 CompleteMultipartUpload 调用;#7362 说 ListObjectVersions 在 100 条处截断,却既不返回 IsTruncated 也不返回 NextKeyMarker,依赖这个接口做版本保留清理的流程会静默做错;
- 大集群的运维面还不稳:#7108 说持续写入的集群上用量统计一直算不准,一个十几万对象的桶被报成三十几个;#6969 说 40 节点集群滚动升级之后 Scanner 拒绝运行;
- 复制功能是最薄的一环:#6825 说一个 6 GiB 的分片对象复制被标记为 FAILED 且从未到达,服务端日志里找不到对应记录;#6824 与 #6822 分别描述了向通用 S3 目标复制时会重复出多余版本与删除标记、以及删掉一个非当前版本会把目标端当前对象一起藏掉;
- 默认口令是个真问题:控制台默认账号密码就是 rustfsadmin 两个同样的词,文档没有在快速开始里给出强制改密的步骤;
- 挂载权限这道坎每次都会绊人:容器以 10001:10001 运行,宿主目录没改属主就是启动即失败,data、logs、以及开启 TLS 时的证书目录都要照做;
- 官方链接也会失手:#7885 报告官网上的 docker-compose.yml 地址返回 404。
五、挖到底:它现在到底算第几版
这一节是本期最值得单独看的核实结果,因为它决定你敢不敢上生产。GitHub 的最新发行端点返回 404,而发行列表里最近十个版本无一例外都标着 prerelease,最新的一个叫 1.0.0-preview.4,就是今天发出来的。换句话说,一个功能表上已经写着分布式、纠删码、复制、KMS 的项目,至今没有对外发布过 GA 版本。版本号本身也还是 beta 与 rc 与 preview 三种后缀轮着用。
| 版本 | 发布时间 | 状态 | 包形态 |
| 1.0.0-preview.4 | 09-16 | prerelease | 仅 zip(Linux 四种组合 + macOS + Windows) |
| 1.0.0-rc.6 | 09-11 | prerelease | zip + deb + rpm + SBOM |
| 1.0.0-rc.5 | 09-02 | prerelease | zip + deb + rpm + SBOM |
| 1.0.0-rc.4 | 08-28 | prerelease | 仅 zip(这一版没有 deb 与 rpm) |
| 1.0.0-rc.1 | 08-08 | prerelease | 首次带上 deb 与 rpm |
平台覆盖也有个明确的缺口:我看到的这十个 Release 里,macOS 只有 aarch64 一种包,没有 Intel 的 x86_64 包,也没有出现 Universal 命名;Windows 只有 x86_64。Linux 是最全的,x86_64 与 aarch64 各有 gnu 与 musl 两份。用 Intel Mac 的人只能自己从源码编,或者退回到容器里跑。
还有一个细节值得单独拎出来,因为它是纯粹的下载陷阱:从 rc.1 到 rc.6 这几版的附件里同时挂着两批文件,一批名字里带具体版本号,比如 rustfs-linux-x86_64-gnu-v1.0.0-rc.6.zip;另一批名字里写的是 latest,比如 rustfs-linux-x86_64-gnu-latest.zip。这两批文件都挂在同一个 Release 下,而最新的 preview.4 里反而只有带版本号的一批;要拿最新的构建就得进最新那个 Release 页,而不是在旧版本的页面里点名字里带 latest 的那个包。同一个版本号还有三种拼法:zip 里写 v1.0.0-rc.6,deb 包里写成 1.0.0.rc.6,rpm 里写成 1.0.0_rc.6。自动化脚本按名字匹配的话,这三处都得覆盖。
六、最终效果:你能拿到什么,以及要付什么
把 RustFS 跑起来之后,你得到的是一套自己完全掌握的 S3 端点:控制台功能是齐的,CI 里的构建产物、备份归档、K8s 的存储后端、AI 训练用的数据集,都可以走同一套 S3 API,而不用为 AGPL 去找法务评估。许可干净加上控制台完整,这两条正好打在 MinIO 社区版的痛处上。代价则集中在两处:一是它还没 GA,二是它对集群运维的要求不低 —— 复制、扫描、用量统计这些正是问题单里最活跃的地方,小规模单机用不太容易撞上,集群一上就开始考人。
谁适合现在就用:
- 手上是单机或小规模双机部署,数据有别的副本兜底,愿意钉住具体版本跑的人;
- 因为许可问题必须从 MinIO 社区版迁走,业务又不想改动 S3 调用方的那一套接口的人;
- 需要一个完整 Web 控制台来交给不太熟的同事操作的团队;
- 已经在用 Kubernetes,想直接用现成 Helm Chart 起一套的人。
谁不适合:
- 把关键数据的唯一副本押上去 —— 一个还没有 GA、issue 里正出现内存不释放与复制丢对象的项目,不适合承担这个角色;
- 用法重度依赖 ListObjectVersions 做版本保留、或者重度依赖跨站点复制的人,先等 #7362 与 #6825 关闭;
- 用 Intel Mac 做本地验证的人,官方没有给这一档的包;
- 希望装完就忘、不想读问题单的人。
下期预告:既然这期拆了 MinIO 的替代品,下一篇把自建对象存储横向摆一次 —— RustFS、MinIO 社区版、SeaweedFS、Garage 这几个放在同一张表里,对比它们的许可、部署门槛、控制台成色和迁移路径,讲清哪一种场景该选谁。
