自架服務 bootc RHEL 10 Fedora 不可變 OS OCI

apt-get 升級每次都在賭 initramfs 不炸:bootc 把整臺 Linux 收進 OCI 映像檔,RHEL 10 image mode GA 讓 podman push 直接變成伺服器升級

bootc 2026 年隨 RHEL 10 image mode 正式 GA 走進主流,把整個 Linux 作業系統包括 kernel 打包成 OCI 映像檔,podman push 到 registry 就是伺服器升級。本文拆解 bootc 的 A/B ostree 架構、跟 rpm-ostree 的斷層、Debian/Ubuntu 支援進度,以及在 VPS 上部署時該用不該用的判斷條件。

VPS 上跑一組穩定服務最頭痛的環節從來不是安裝,是升級。apt-get upgrade 一跑下去,systemd 換版本、libssl 動一次依賴樹,遇上一顆過期的 initramfs 或一個 hook 執行順序搞錯就是重開機起不來——這故事在自架社群裡年年重演,備份、快照、預先 rollback 準備得再周全,動手前依舊是在賭。bootc 這個 2026 年隨 RHEL 10 image mode 正式 GA 走進主流的專案,把賭注從系統升級這條路徑上整段拆掉:整個 Linux 作業系統,kernel、bootloader、驅動、userspace 全部打包成 OCI 映像檔,podman push 到 registry 就是伺服器升級指令。

bootc 的上游是 bootc-dev/bootc,Rust 寫的 CLI 工具,MPL 授權。它跟 Fedora 那個 rpm-ostree 的關係最容易讓人搞混——底層依舊是同一套 OSTree,差別在鏡像的傳輸與定義方式從 rpm 套件樹改成了 OCI 容器映像。Red Hat 從 RHEL 9.4 開始推 bootc,RHEL 10 把 image mode 正式標為 GA、Fedora bootc 從 41 版起成為官方變體,Rocky Linux、AlmaLinux、CentOS Stream 都提供對應的 bootc 基底映像。

從 rpm-ostree 走了十五年才收成的東西

Fedora Silverblue 從 2018 年開始把 OSTree 這套「檔案系統原子升級」的想法推上桌面,走了七年到現在仍舊算小眾——原因是它跟開發者熟悉的容器生態完全脫節。系統管理員得學一整套 rpm-ostree 指令:rpm-ostree upgraderpm-ostree installrpm-ostree deployostree admin status,每個指令都對應 OSTree 內部的 commit 概念,跟 podman、docker 那邊不共用任何心智模型。

bootc 拿掉這層抽象,直接說:Containerfile 就是 OS 定義。FROM quay.io/centos-bootc/centos-bootc:stream10 拉一份基底映像,RUN dnf install nginx tailscale 加上要的套件,COPY nginx.conf /etc/nginx/nginx.conf 塞設定進去,最後 podman build -t registry.example.com/servers/web:v42 打包,podman push 送上 registry。目標機器只要跑 bootc update 就會拉最新映像、staged 到 B 分區、下次開機生效。

跟 Docker container 的差別在於,這支映像檔不是拿去 podman run 起容器的——bootc 直接把整份映像 rebase 到本地磁碟,變成 OS 的下一個部署槽位。同一支 Containerfile 可以用 bootc-image-builder 額外產出 qcow2、ISO、AMI 等磁碟格式,配到 VPS 商的自訂映像上傳流程裡直接開新機,本地開發跟雲端部署共用同一份定義。

A/B 部署跟 atomic rollback 的實際細節

底下的 OSTree 用 A/B 兩個部署槽位撐住 atomic 這件事。假設目前跑的是 deployment A,bootc update 拉來新映像後,OSTree 把它解到 B 槽位,A 完整不動。bootloader 的 GRUB config 更新指向 B,下次開機從 B 起來。B 起來後發現有問題,bootc rollback 一行指令把 default 換回 A,重開機就回到升級前的狀態,整個回滾流程平均不到兩分鐘。

/etc/var 是唯一的可寫路徑,其他全部唯讀。/etc 的處理是 3-way merge:新映像的 /etc 預設值、舊部署的 /etc 預設值、當前實際內容三方比對,管理員手改過的檔案會保留、沒改過的則跟隨新版。/var 完全由主機保留,映像升級不動它。這對跑資料庫、儲存服務的伺服器很關鍵——PostgreSQL 的 data directory、Docker Registry 的儲存路徑不會因為 OS 升級被覆蓋。

kernel 更新在 bootc 底下的流程跟傳統發行版是斷層式的差別。傳統 dnf update kernel 是解 rpm、寫進 /boot、跑 dracut 重建 initramfs,中間任何一步失敗都可能開不了機。bootc 這邊 kernel 跟 initramfs 都是映像檔的一部分,構建階段就已經在 CI 環境驗證過,目標機器只是把整份映像檔複製到 B 槽位。initramfs 損毀、GRUB 錯亂這類災難在這個模型底下難度成本高很多。

Containerfile 定義 OS 這件事在維運上的意義

實務上 bootc 把伺服器組態管理這件事從 Ansible/Puppet/Chef 這一整代工具搬到 CI/CD pipeline。過去要維護 20 臺 VPS 的一致性得寫一套 Ansible playbook,每次改動先 --check--diff 再套用,還得處理某臺機器 apt cache 卡住這類邊界狀況。bootc 底下,Containerfile 進 git、GitHub Actions 觸發 podman build、推 registry,每臺機器排 systemd timer 定時跑 bootc update,一致性由映像檔的 digest 保證。

這個模型對 immutable infrastructure 那套「機器是家畜不是寵物」的理念是完整實現。要換版本就是換映像 tag、要 rollback 就是換回舊 tag、要新增節點就是拿磁碟映像開新 VM。GitOps 那套「宣告式 desired state」從 Kubernetes 資源層延伸到 OS 層。

要提醒的是這條路線不適合過去習慣 dnf install 隨時裝套件的伺服器維運模式。bootc 有 bootc usr-overlay 這個暫時性的可寫層,但重開機會消失,設計上只是為了臨時 debug。長期要裝的東西必須進 Containerfile。這是有意的取捨——把「當下手動改了什麼」這個組態飄移的最大來源直接堵住。

跟 Talos、Flatcar 差在哪

自架 immutable OS 的選項不止 bootc 一個,Talos 跟 Flatcar 是同賽道另外兩條路,定位相當不同。

Talos 是 Kubernetes 節點專用 OS,SSH 拔掉、所有管理走 API、根檔案系統掛成 SquashFS 唯讀。強項是完全鎖死的攻擊面,缺點是只能跑 Kubernetes——想在同一臺機器跑一支獨立的 nginx、跑一支 tailscale daemon、或跑任何非容器化的傳統服務都做不到。

Flatcar Container Linux 是 CoreOS 血脈的直接繼承者,走 dual-partition A/B ext4 掛載,root 可寫、/usr 唯讀。它比較像「附贈容器 runtime 的通用 Linux」,保留 shell 跟 SSH,SSH 進去可以修東西。這條路線適合過渡期——習慣 SSH 進去 debug 的團隊可以先搬 Flatcar 再談完整 immutable。

bootc 定位介於這兩者之間:完整的通用型 OS(能跑非容器化的 systemd unit、能直接裝 nginx 起服務),但升級模型走完整 immutable。SSH 預設保留,能進去看,但改的東西不能長期保留。RHEL 10 用 image mode 推的就是這條路,Fedora bootc 是社群版本。

決策上的建議清楚:Kubernetes 節點選 Talos、要一般伺服器搭配 immutable 升級選 bootc、暫時還離不開 SSH 手動改東西的過渡期選 Flatcar。三者不是同一條路的競爭替代品,而是同一個大方向上的三種切片。

目前在 VPS 上部署的實際限制

bootc 在 2026 年 9 月的狀態下已經算得上 production ready,但幾個限制值得提前知道。

多發行版支援還在收斂。RHEL 10、Fedora bootc、Rocky Linux、AlmaLinux、CentOS Stream 是第一批完整支援,Debian bootc 專案存在但還在 experimental 階段、Ubuntu 官方尚無 bootc 基底映像,社群版本要自己編。對想在 Debian 13 或 Ubuntu 26.04 生態繼續走的團隊來說是實際障礙——短期內只能靠 Fedora/RHEL 系走這條路。

RPM overlay 這個功能在 bootc 底下被有意壓縮。rpm-ostree 允許 rpm-ostree install foo 動態加套件到當前部署,但 bootc 明確不鼓勵這種用法——要加東西進 Containerfile 重新構建。這對「每臺伺服器角色略有差異」的場景需要重新設計:要嘛做多份 Containerfile,要嘛把差異用 systemd unit、config 掛載處理。

VPS 商的自訂映像上傳流程是另一個環節。bootc-image-builder 產出的 qcow2 / raw / AMI 檔案,需要 VPS 商支援自訂映像上傳——不是每家都提供這個功能,或提供了但有大小限制。走 bootc 之前先確認手上 VPS 方案的自訂映像流程能不能過關。

什麼場景該選 bootc

放下概念上的優雅,判斷標準務實。

一組 VPS 跑相同角色的服務、需要保證機器之間一致性、常常因為升級卡住重開不能開機——這是 bootc 的甜蜜點。CI/CD pipeline 已經在跑 Docker 映像構建的團隊,把 OS 塞進同一套流水線幾乎沒有額外學習成本。

單獨一臺 VPS 跑幾個雜項服務、每次升級要進去手動調東西、依賴一堆非官方 apt/dnf repo、要跑客製 kernel 模組——這條路不划算,繼續用 Debian/Ubuntu 傳統模型比較省事。

過去用 Ansible / SaltStack 管十幾臺 VPS 的團隊值得認真評估遷移。Ansible 的 idempotent 假設在實際跑起來邊界狀況一堆,bootc 用「換整個 OS 映像」把這條路徑上的不確定性拿掉。學習曲線集中在前期把 Containerfile 寫對,後續維運成本明顯低於 Ansible。

選 bootc 前該確認的底層條件

跑 bootc 的 VPS 對底層平臺有幾個具體要求:VPS 商必須支援自訂映像上傳(或至少支援 Fedora/RHEL/AlmaLinux 官方 bootc 映像)、磁碟容量要足夠放 A/B 兩份部署(實務上映像大小差不多是傳統 minimal 安裝的 1.5 倍)、網路頻寬要能撐每次升級的映像檔傳輸量,尤其在多節點同時 pull 大型映像時。

NCSE Network 在臺灣是方電訊機房提供的 VPS 主機採用 Intel Xeon Gold CPU 與 NVMe SSD,在 bootc 這類需要頻繁磁碟 I/O 與整份映像檔傳輸的部署流程上有實際優勢;同時提供從 10M 到 100G 的 IP Transit 頻寬彈性,因應 immutable OS 每次升級的映像傳輸需求。前往 ncse.tw 了解 VPS 方案細節。

需要穩定的雲端主機?

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

查看 VPS 方案 →