自架服務 S3 MinIO Rust Garage 物件儲存

MinIO 封存之後 S3 替代品的分叉路:Garage 用 CRDT 跳過 RAFT,把物件儲存塞進幾臺跨地的 VPS

MinIO 社群版在 2026 年 4 月被標記為封存,自架者開始分流到 RustFS、SeaweedFS、Ceph RGW 跟 Garage 幾個方向。本文解析 Garage 的 Dynamo-style CRDT 架構為何刻意不走 RAFT,replication mode 2 和 3 的實務選擇,以及它為什麼適合跨地的小型 VPS 部署,而不是用來追 MinIO 的吞吐量。

MinIO 社群版的 GitHub repo 在 2026 年 4 月 25 日被標記為封存,距離 2025 年 10 月停止發布預先編譯好的 binary 跟 Docker image 大約半年。原本的政策管理、site replication、lifecycle rule 都移到付費版 AIStor 後面,社群版剩下的程式碼就擱著不再維護。目前自架 S3 的人大致分流到四個方向:Ceph RGW 給本來就有 Ceph 的團隊、SeaweedFS 給重視檔案系統介面的 homelab、RustFS 給想追吞吐量的、Garage 給跨地點小型部署。

Garage 這個名字在中文圈能見度不高,但在歐洲自架社群已經跑了四五年。它由法國的 Deuxfleurs 自架協會開發,用 Rust 寫、單一靜態 binary、AGPL-3.0 授權,2.0 在 2025 年 6 月釋出,到 2026 年 4 月的 2.3.0 把 admin API、多 token 權限、website redirection 這些實務功能補齊。對於原本在 MinIO 上跑幾個 bucket 的使用者,它值得被認真看待,但得先認清它要解的問題跟 MinIO 不同。

Garage 不打算當 MinIO 的直接替代

把 Garage 跟 MinIO 擺在一起比較吞吐量,結論幾乎都是 MinIO 贏,這沒什麼好爭的。MinIO 支援 erasure coding,可以用 N+M 的方式把資料切片分散,儲存效率跟容錯能力都比單純複製好;S3 endpoint 的覆蓋也更齊全,從 object lock、lifecycle rule 到 KMS 整合幾乎無所不包。Garage 刻意不走 erasure coding,只做 duplication,S3 endpoint 的實作也挑過,很多比較冷門的 API 就直接跳過。

這個取捨不是能力問題,是定位問題。Deuxfleurs 這群人想解的場景是:三四個分散在不同城市、不同 ISP 的小機器,用家用 FTTH 的網路連在一起,當作一個 S3 cluster 使用。這個情境下,erasure coding 會變成痛苦來源——節點之間的網路延遲高、不穩定、頻寬還可能被 ISP 限速,重建一個切片要跨公網拉大量資料,恢復時間不如直接複製。Garage 選擇把簡單性放在第一位,接受儲存效率低一點,換到的是「一臺 VPS 掛掉半天,另外兩臺照常服務、照常寫入」的操作體驗。

這也是為什麼拿 Garage 去跑高吞吐量的 CI artifact storage、或者放在同一個機房的三臺高速機器上,發揮空間相當有限。那種場景 RustFS 跟 MinIO 比較適合。

跳過 RAFT 這件事到底換到什麼

多數分散式儲存系統在 metadata 層跑 RAFT 或類似的共識演算法:Ceph 用 Paxos 變種、MinIO 的 cluster coordination 也仰賴 leader election。Garage 選了另一條路,整個系統只用 CRDT(Conflict-free Replicated Data Type)跟 Dynamo-style 的 consistent hashing ring 來協調,沒有 leader、沒有 quorum vote、沒有誰在等誰的 heartbeat。

這個決定帶來的好處有三個,都跟地理分散有關。

第一是請求可以在任何節點獨立處理。RAFT cluster 的寫入必須走 leader,leader 離得遠就卡住;Garage 的任何節點都能接寫入請求,然後根據 hashing ring 把資料轉送給該負責的 replica。對於客戶端分布在不同地區的場景,就近接入的延遲差距很直接。

第二是對高延遲網路的容忍度。RAFT 要求節點之間的 round-trip time 不能太誇張,不然 heartbeat timeout 一直觸發、cluster 一直在重新選舉。CRDT 不管這個,節點之間同步得慢一點也只是收斂慢一點,不會觸發 cluster 層級的失能。

第三是拓撲變更的簡潔。加節點、換磁碟、重新分配 zone 權重,在 Garage 都是調整 cluster layout 這個 CRDT,確認後 apply,整個過程不需要讓 cluster 停下來投票。2.0 之後 layout 的版本化更徹底,staging 跟 apply 分開,誤操作可以回滾。

代價是最終一致性不是強一致性。寫入會回 200 OK 之後,另一臺 replica 可能幾毫秒到幾秒之內才拿到資料。Garage 用 quorum read 來補償:replication mode 3 預設讀兩份、寫兩份,大多數時候拿到最新的資料,但極短時間窗內有可能讀到舊版本。如果應用要求的是「寫入後立刻讀到最新值」,Garage 不是合適工具。

複製模式該選哪一個

Garage 的 replication mode 影響整個 cluster 的拓撲設計,一旦選了就很難改,值得花點時間想清楚。

**Mode 1(none)**只有本地開發或刻意沒有備援的場景會用,一臺機器掛掉資料就不見。Mode 2 把資料存兩份,單一節點故障時可以降級成唯讀。Mode 3 存三份,容許兩個節點或兩個 zone 失效,寫入也不中斷。還有 mode 2-dangerous 跟 mode 3-degraded 兩個變體,前者讓第二份複寫改成非同步(犧牲一致性換可用性),後者把 read quorum 降到 1(接受可能讀到舊資料)。

實務上,三臺機器以上的部署幾乎都該選 mode 3。多出來的儲存成本換到的是「任何一臺 VPS 歇業一天、cluster 完全無感」的運維體感,對於會把機器放在三個不同雲商或三個不同機房的場景,這是整個設計的核心價值。

Zone 的概念是另一層保護:節點標記所屬 zone 後,Garage 會優先把三份複本放在三個不同 zone。常見的做法是用機房、城市或 ISP 當 zone 分類。要注意一件事,mode 3 需要至少三個 zone 才能發揮完整效果,如果只有兩個 zone、把三臺機器硬塞進去,容錯模型就退化成 mode 2。

2.x 系列把實用性補齊

Garage 一路到 1.x 都偏向「能跑就好」的狀態,2.0 之後才明顯往生產環境靠。幾個 2.x 系列累積下來的變動值得注意。

Admin API 整個換掉。 1.x 的 admin API 路徑含糊,動詞跟名詞混在一起;2.0 改成每個操作直接放在路徑裡,/v2/GetClusterStatus、/v2/AddKey 這種 RPC 風格。CLI 從直接呼叫內部函式改成 HTTP client,所有能從 CLI 做的事也能從 API 做,整合進 Terraform 或 Ansible 的工作量大幅下降。

多 admin token 跟 scope。 以前只有一個 master token 寫在設定檔,誰拿到就能動整個 cluster。2.0 之後支援多個 token、每個 token 可以限定 scope 跟過期時間。CI 流程要產一個暫時 key 做備份、監控系統要一個只能讀 metrics 的 token,都不必再把 master token 塞進去。

Website redirection 跟 access key 過期。 原本 Garage 的 static website hosting 只能提供檔案,redirect 要靠外層的 reverse proxy 做。2.x 把 S3 的 website redirection rule 支援補上,整個 bucket 可以直接扛 404 導向跟路徑改寫。Access key 支援過期時間也是補上這個洞——臨時 key 不會因為忘記撤銷而永遠有效。

2.3.0 的 introspect endpoint。 這個版本(2026 年 4 月)加了可以回報目前連線中的 access key 的 endpoint,稽核紀錄跟 debug 容易很多。helm chart 也在這個版本修到可用,Kubernetes 部署的門檻跟著降低。

在 VPS 上實際跑一套的幾個決定

單節點玩看看最簡單,docker run 加一份 TOML 設定檔,三分鐘內 S3 endpoint 可以回應。但要跨 VPS 跑 cluster,有幾個決定要在起手時先定好。

節點之間的通訊 預設走 TCP,沒有加密,公網部署一定要套 WireGuard 或 Tailscale 把節點連成一個 overlay。Garage 自己不處理節點間 TLS,官方的建議就是用 VPN。這個比 MinIO 的 cluster TLS 設定簡單,但也意味著 VPN 鏈結成了單點故障——WireGuard tunnel 斷了,Garage 就以為節點不見了。要避免這個,常見的做法是用兩條獨立的 overlay(例如 WireGuard mesh 搭 Tailscale subnet router),讓節點間至少有一條備援路徑。

磁碟配置 可以用多顆磁碟當 data path,Garage 會自己分配。但它沒有做 RAID 層的事,單一磁碟壞掉等於這個節點上的某些資料片段消失,依靠的是另一個節點上有另一份複本。對於 VPS 上通常只有一個 virtual disk 的場景,這個設計夠用;要在實體機上跑的話,建議先用 ZFS 或 mdadm 把磁碟堆成一個邏輯 volume 再給 Garage,少一層需要 Garage 處理的失效路徑。

客戶端存取 走標準 S3 SDK 或 CLI 工具,aws s3、rclone、restic、s3cmd 都能用。要注意 Garage 預設把 bucket 當成 path-style 處理(http://endpoint/bucket/key),不是 virtual-host style(http://bucket.endpoint/key);某些老舊 SDK 預設只支援後者,呼叫前要先確認。

備份策略 的常見組合是 restic 加 Garage。restic 本身是 content-addressable 的加密去重備份工具,寫到 S3 相容的後端剛好,加上 Garage 自己做 cross-site replication,整套備份不只是「有備份」,而是「備份有異地複本」。要在同一臺 VPS 上同時跑應用跟 Garage 節點,記得把備份的 target bucket 放在另一個節點負責的位置,否則單機掛掉連備份都拿不到。

什麼時候別選 Garage

誠實講,Garage 不是萬能選項。幾個場景直接避開會比較省時間。

要高吞吐量、單一機房、十幾 TB 以上的工作負載,MinIO(如果還在用)或 RustFS 比較合適,erasure coding 的儲存效率跟成熟度優勢在這種場景很明顯。要跟 Kubernetes 深度整合、動態 provisioning PVC 的場景,Ceph RGW 搭 Rook 的生態系還是最完整,Garage 的 helm chart 補到 2.3 才算可用。

需要完整 S3 功能面——例如 object lock legal hold、SSE-KMS 跟外部 KMS 整合、進階的 ACL——Garage 的實作深度不夠,MinIO 或 AWS 原生才是答案。要把 Garage 當成一般檔案系統分享給使用者,體感也不太對:那個場景 SeaweedFS 的 filer 層或 NextCloud 之類比較合用。

Garage 的甜蜜點很明確:三到五臺跨地的小型 VPS,每臺容量在幾百 GB 到幾 TB 之間,S3 用在備份、照片、容器 image registry、靜態網站 artifact 這類相對冷的工作負載,希望任何一臺 VPS 歇業時服務不中斷。符合這個描述的部署,Garage 是這個領域目前最省心的選擇。

MinIO 的封存不是一個突發事件,是整個商業開源模型持續調整的一個節點。對自架社群來說,重要的不是找到「下一個 MinIO」,而是認清不同工具要解決不同層次的問題。Garage 選了一條窄而深的路,剛好對應到一群長期被忽略的使用者。


要在幾臺 VPS 上跑 Garage 這類跨地點複製的服務,底層網路穩定、原生支援 IPv6、跨機房延遲可控是三個關鍵條件。NCSE Network 在臺灣是方電訊機房的 VPS 搭配自有 AS 的 IP Transit,提供 IPv6 雙堆疊與多線路 BGP 選路,適合當成 Garage cluster 的其中一個節點,或者 WireGuard overlay 的入口點。有興趣可以到 ncse.tw 看規格與線路資訊。

需要穩定的雲端主機?

NCSE Network 提供企業級 VPS,7 天免費試用,臺灣是方電訊機房,99% SLA 保證。

查看 VPS 方案 →