SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor · 已更新 2026-10-24

伺服器適合使用不可變 Linux 發行版嗎?

了解 Image mode 如何以整個系統映像更新伺服器,失敗時重新開機即可回復,並比較 bootc、Fedora CoreOS、Flatcar 與 Talos 在 VPS 上的代價。

不可變 Linux 發行版的定義

不可變 Linux 發行版會以單一映像檔提供作業系統,因此更新時是替換整個系統,而不是直接修改目前的系統。執行中的主機不會在 /usr 下方重新寫入檔案 apt upgrade。您可以建置或抓取新的映像檔,主機會將它與目前執行中的映像檔並列暫存,下一次重新開機時再切換啟用的映像檔。舊映像檔仍保留在磁碟上,因此若更新失敗,只要重新開機即可復原。

「不可變」這個名稱容易讓人誤解。root 仍可寫入磁碟,並沒有任何機制從硬體層面阻止這件事。這類系統會將系統目錄以唯讀方式掛載,並將這些目錄的所有權交給映像檔。持久性資料位於 /var。專屬於該機器的設定位於 /etc。/usr 下的所有內容都屬於映像檔,因此執行相同映像標籤的兩台伺服器會擁有完全相同的系統檔案。

Red Hat 對這兩種模型的稱呼最為清楚:套件模式與映像模式。套件模式是執行中的系統搭配可修改系統的套件管理員。映像模式則是在其他地方執行建置程序,產生一項成品;伺服器唯一的工作,就是啟動您指定的成品。以下內容都源自這項差異。

為什麼唯讀系統對伺服器更重要

執行了 2 年的伺服器,通常累積了沒有人記錄的歷史。可能是某次倉促處理留下的 make install。也可能是為了安裝某個套件而加入的第三方套件庫,或是在服務中斷期間編輯過、之後卻未還原至設定管理系統的設定檔。這稱為設定漂移,也是為什麼根據筆記重建「相同」伺服器時,結果往往會得到行為不同的主機。筆記記錄的是原本的意圖。磁碟保存的才是實際狀態。

Image mode 移除了設定漂移累積的所在位置。/usr 在執行階段是唯讀的,因此手動進行的安裝要麼直接失敗,要麼會被記錄為可透過一個命令列出的層。如此一來,兩台機器之間的差異會清楚呈現,不必再靠逐層考古式追查。這和 一般 Linux 伺服器維護檢查清單 要以紀律處理的是同一個問題,只是改由檔案系統負責。

復原就是重新開機,這就是全部重點

這個模型要處理的失敗情境,就是我們已經記錄的情況:核心更新後無法開機的 VPS。在套件模式中,您要從供應商的救援主控台進行復原。掛載磁碟、進入 chroot,然後手動移除核心套件。這種方式之所以可行,是因為 bootloader 會保留舊核心;但只有核心會以這種方式進行版本管理。同一筆交易中套用的 glibc 更新與 systemd 變更已經生效,沒有任何單一命令能將它們一起回復。

在映像檔模式中,整個系統就是部署單位。在 bootc 主機上:

sudo bootc status
sudo bootc rollback
sudo systemctl reboot

bootc rollback 會將 bootloader 的順序切回上一個開機項目,也就是您 1 小時前執行的映像檔,包含核心與使用者空間。系統不會下載任何內容,也不會重新建置,因為舊映像檔仍保留在磁碟上。如果您已啟用下文所述的自動更新 timer,請先停止它:bootc 文件警告,執行自動升級的 agent 可能會復原這次回復操作。

Fedora CoreOS 也能執行相同操作,但使用不同名稱:

sudo systemctl stop zincati.service
sudo rpm-ostree rollback -r

請先停止 Zincati。Zincati 是讓 Fedora CoreOS 機器維持在最新版本的 agent。它不會重新安裝您剛才復原的部署,但會持續尋找更新,並升級到任何出現的較新版本。因此,如果機器在修正版本發布前應維持目前狀態,請執行 sudo systemctl disable --now zincati.service。部署回復準備完成後,-r 會重新開機。若要避免您信任的部署遭到垃圾回收:

sudo ostree admin pin 0
rpm-ostree status

rpm-ostree status 會依 bootloader 提供開機選項的順序列出部署,並在目前執行中的部署旁顯示點號,在您釘選的部署旁顯示 Pinned: yes。

Talos 可從您的工作站以一次 API 呼叫完成:

talosctl rollback --nodes 10.20.30.40

Flatcar 會保留兩個 /usr 分割區,並在兩者之間切換。每個插槽都會在分割區表中記錄優先順序與嘗試次數,因此無法成功開機的插槽會耗盡嘗試次數,bootloader 就會選擇另一個插槽。請確認目前使用的插槽,以及它是否已標記為正常:

sudo cgpt show "$(rootdev -s /usr)" | grep successful=1

正常執行中的插槽會輸出包含 tries=0 successful=1 的行。同一行中的優先順序數字只用來排列 bootloader 偏好的插槽,因此在完全正常的機器上也可能顯示 1 或 2。若找不到相符的行,表示目前插槽從未獲得確認;機器在更新後、第一次乾淨開機前,就會處於這種狀態。

「install a package」的替代方案:bootc 與 Containerfile

bootc 是將這種模式一般化的工具。它將自身描述為使用 OCI(open container initiative)容器映像,進行交易式的就地作業系統更新;同時也是 CNCF Sandbox 專案。您的伺服器會變成一個 Containerfile。截至 2026 年 8 月,Fedora 基礎映像為 quay.io/fedora/fedora-bootc:44,CentOS Stream 基礎映像則為 quay.io/centos-bootc/centos-bootc:stream10。

FROM quay.io/fedora/fedora-bootc:44
RUN dnf -y install nginx && dnf clean all
RUN systemctl enable nginx

像其他映像一樣建置並推送:

sudo podman build -t registry.example.com/edge/web:2026-08-19 .
sudo podman push registry.example.com/edge/web:2026-08-19

接著在伺服器上執行:

sudo bootc upgrade --check
sudo bootc upgrade --apply

bootc upgrade 會查詢映像來源,並將新映像排入下一次開機。--check 會回報是否有可用更新,但不會變更任何內容。--apply 會重新開機並載入該映像。bootc switch registry.example.com/edge/web:next 會讓機器改用其他映像,同時保留 /etc 與 /var;這就是在不重新安裝的情況下,將伺服器移至不同映像串流的方式。

若要啟用無人值守更新,請啟用專案提供的 timer:

sudo systemctl enable --now bootc-fetch-apply-updates.timer

這是映像模式對應於 Ubuntu 的無人值守升級,以及 Rocky 和 Alma 上的 dnf-automatic 的方案。差異在於實際套用的內容。套件模式的 timer 會套用該晚儲存庫提供的版本,因此每台機器最後得到的套件集合都會略有不同。映像模式的 timer 則會套用一個您已在其他地方啟動過的成品。

這個 Containerfile 會導出兩項建置規則。可寫入的資料應放在 /var 下,因此若軟體堅持寫入自身的安裝目錄,就需要在建置時加入 symlink 或 systemd 的 BindPaths= 行。更新時,/etc 會進行三方合併。未曾修改的檔案會採用映像的新版本;曾在本機編輯的檔案則會保留。

若只需要在執行中的主機上使用工具進行一次除錯:

sudo bootc usr-overlay
sudo dnf -y install strace

這會在 /usr 上加入暫時的可寫入 overlay,並在下次重新開機時捨棄。它適合用來查看問題,不是用來修正問題。您無法透過這種方式變更 kernel,而且依設計,所有安裝的內容都會在重新開機時消失。

Fedora CoreOS:配置一次,持續更新

Fedora CoreOS 沒有互動式安裝程式。您需要撰寫 Butane YAML 檔案,將其轉換為 Ignition JSON,並在機器第一次開機時提供給它:

podman run --interactive --rm quay.io/coreos/butane:release \
       --pretty --strict < your_config.bu > transpiled_config.ign

Ignition 僅在第一次開機時於 initramfs 中執行。這是從 cloud-init 轉換過來的使用者最容易忽略的地方。如果設定中沒有 SSH 金鑰,機器開機後就沒有登入方式,必須從頭重新佈建才能修正。將設定套用到正式伺服器前,先在可捨棄的機器上測試。

從 live environment 將系統安裝到磁碟:

sudo coreos-installer install /dev/sda \
    --ignition-url https://example.com/example.ign

更新預設會自動進行。您能控制更新時間,但無法停用更新機制。將 TOML 檔案放在 /etc/zincati/config.d/55-updates-strategy.toml,以選擇週期性策略:

[updates]
strategy = "periodic"

使用此策略時,您需要為 array-of-tables 中的每個項目新增一個維護時段。每個時段都以雙方括號中的 updates.periodic.window 作為標頭,接著指定 3 個鍵:

  • days:日期名稱清單,例如 "Sat" 和 "Sun"。
  • start_time:維護時段開始的時間,格式為 "22:30"。
  • length_minutes:維護時段持續的時間,例如 60。

上述時間均為 UTC。若要完全停止更新,請執行 sudo systemctl disable --now zincati.service,並接受之後必須自行負責修補排程。

Package layering 可作為例外處理方式:

sudo rpm-ostree install --allow-inactive vim
sudo systemctl reboot

這會建立包含該套件的新部署,變更要等重新開機後才會生效。代價會在之後出現。每個新的 base image 套用後,系統都會重新套用您分層安裝的套件;因此,如果更新當天該套件已從 repository 消失,更新就會失敗。Fedora 官方文件建議,任何規模較大的內容都應使用容器;如果確實需要變更作業系統,則應使用 bootc image。

Flatcar Container Linux:完全沒有套件管理員

Flatcar 是 CoreOS Container Linux 的延續版本,也是通用型選項中限制最嚴格的一種。系統沒有可供應急使用的套件管理員。所有執行內容都是容器。佈建方式是 Ignition,與 Fedora CoreOS 相同。更新採用上述兩個 A/B /usr 分割區,由 update_engine 驅動,並由 locksmithd 決定何時重新開機。

update_engine_client -status
update_engine_client -check_for_update

UPDATE_STATUS_UPDATED_NEED_REBOOT 表示被動插槽已經包含新映像檔,目前只剩重新開機尚未執行。預設的重新開機策略是 reboot,延遲時間為 5 分鐘。因此,除非另行設定,單一正式環境 VPS 會依自身排程自動重新啟動。請在 /etc/flatcar/update.conf 中設定時段:

REBOOT_STRATEGY=reboot
LOCKSMITHD_REBOOT_WINDOW_START="Thu 04:00"
LOCKSMITHD_REBOOT_WINDOW_LENGTH=1h

REBOOT_STRATEGY=off 會將重新開機交由您手動執行。同一檔案中的 SERVER=disabled 會完全停止更新檢查。對於叢集,將 REBOOT_STRATEGY=etcd-lock 與 locksmithctl set-max 4 搭配使用,可限制同時允許重新開機的節點數量,避免更新一次讓整個節點群組同時停止服務。

Talos Linux:沒有 shell、沒有 SSH、沒有主控台

Talos 是 4 個系統中用途最專一的一個,也最清楚界定了自己的用途。它用來執行 Kubernetes 節點。系統沒有 SSH daemon、登入 shell,也沒有主控台登入功能。實體主控台會顯示用於檢查機器狀態的儀表板,而不是登入提示字元。所有操作都是從工作站使用 talosctl,針對儲存在 git 中的機器設定,發出 gRPC API 呼叫。

talosctl upgrade --nodes 10.20.30.40 \
  --image factory.talos.dev/metal-installer/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba:v1.14.2

自 Talos 1.14 起,ghcr.io/siderolabs/installer 映像不再發布,安裝程式映像改由 Image Factory 提供。該路徑中的長 ID 是未自訂機器所使用的空白 schematic。請使用安裝節點時採用的 schematic,讓系統擴充功能一併保留,並將標籤替換成要升級到的版本。升級採用 A-B 配置,會保留先前的 kernel 與 OS 映像。因此,如果新映像無法啟動,Talos 會自行回復,不需要人工介入。由於沒有登入 shell,除錯方式也不同:請使用 talosctl logs 與 talosctl dmesg,而不是在該機器上使用 journalctl。需要在節點上使用工具時,talosctl debug 會從你提供的映像啟動具備權限的容器,並將你帶入其 shell;離開後容器會被移除。

如果你的工作負載不是 Kubernetes,Talos 就不是正確選擇。如果是 Kubernetes,Talos 會消除一整類事件,因為「有人登入節點並修改了某些內容」這種情況根本不會發生。

VPS 租戶實際放棄的項目

在執行中的系統上進行臨時安裝。 這是最大的差異。事件處理期間,凌晨 2 點無法使用 sudo apt install htop。在 bootc 上,你會取得重新開機時即失效的暫存 overlay。在 Fedora CoreOS 上,你會取得需要重新開機的分層部署。在 Flatcar 和 Talos 上,則什麼都沒有。

原本不存在的建置管線。 新增套件表示必須編輯 Containerfile、建置 image、推送至 registry,然後逐台更新伺服器。管線已存在時,這項工作成本很低;但若尚未建立管線,就需要實際投入時間,且伺服器必須能連線至 registry,這代表你還要執行另一項服務,或支付另一筆費用。

Kernel modules。 kernel 來自 image,因此針對目前執行中的 kernel 編譯的 module 無法存活到下一次更新。Out-of-tree modules 與 DKMS(dynamic kernel module support)套件必須針對該 image 的 kernel 建置到 image 中。任何需要基礎 image 未提供的 module 的功能,都會從安裝問題變成建置問題。

供應商與服務商代理程式。 監控與備份代理程式通常以 .deb 或 .rpm 提供,並搭配安裝腳本寫入 /usr 及啟用 unit。在唯讀系統上,該腳本會失敗。有些供應商提供 container,或說明 image-mode 安裝方式;許多供應商則沒有。提交決定前請先確認,因為無法監控的伺服器機群,比設定逐漸偏離的伺服器機群更糟。

Image 本身。 幾乎沒有 VPS 控制面板會在 Ubuntu 和 Debian 旁列出 Fedora CoreOS、Flatcar 或 Talos。你必須自行提供磁碟,下一節將說明這一點。

將其中一種系統安裝到租用的 VPS

先向供應商確認兩件事:你是否能使用 out-of-band 主控台,也就是 VNC 或序列主控台;以及是否能啟動救援系統。沒有主控台時,無法重新啟動的機器就只能提交支援工單,而不是花 5 分鐘修復。

如果供應商接受自訂映像檔,請上傳供應商提供的 raw 或 qcow2 映像檔。但只上傳映像檔,並不會讓你取得可登入的機器。Fedora CoreOS 的 core 使用者沒有預設密碼或 SSH 金鑰,因此仍須提供包含你金鑰的 Ignition 設定;如果使用的是 Afterburn 支援的雲端平台,也可以透過供應商提供的 SSH 金鑰功能設定金鑰。否則,請從救援系統自行寫入磁碟。Flatcar 提供專門處理這項工作的獨立 script,而且可在任何 Linux 上執行:

curl -fsSLO https://raw.githubusercontent.com/flatcar/init/flatcar-master/bin/flatcar-install
chmod +x flatcar-install
sudo ./flatcar-install -d /dev/sda -i ignition.json

請從救援系統執行這項操作,絕對不要從要取代的伺服器執行,因為 script 執行時會重新分割目標裝置。裝置上至少需要 8 GB 可用空間,且救援環境必須提供 bash、bzip2 或 lbzip2、lsblk、wget、udevadm、gpg 和 gawk。你的 ignition.json 必須包含 SSH 金鑰,否則安裝完成的系統將沒有允許你登入的方式。

Fedora CoreOS 的流程相同,其安裝程式會以容器執行:

sudo podman run --pull=always --privileged --rm \
    -v /dev:/dev -v /run/udev:/run/udev -v .:/data -w /data \
    quay.io/coreos/coreos-installer:release \
    install /dev/vdb -i config.ign

執行前,請使用 lsblk 確認裝置名稱。寫入錯誤的裝置會摧毀其中原有的資料,而且不會顯示確認提示。

bootc 提供了不需進入救援模式的做法,因為它能就地轉換正在執行的 Linux 系統:

sudo podman run --rm --privileged -v /dev:/dev -v /var/lib/containers:/var/lib/containers -v /:/target \
             --pid=host --security-opt label=type:unconfined_t \
             quay.io/fedora/fedora-bootc:44 \
             bootc install to-existing-root

執行前,請先閱讀所用 base image 的說明文件,並在可捨棄的伺服器上測試。重新開機後,機器會執行該映像檔,而原本的套件組合將會消失。

誰適合執行不可變伺服器,誰不適合

如果您的伺服器是「牲畜」而不是「寵物」,就適合採用這種方式。也就是從同一份配方建立許多機器。例如只執行一小時的 CI(持續整合)runner、遭替換而不是修復的 k3s 或 Kubernetes 節點,以及遇到故障主機時,標準處理方式本來就是「刪除它,再建立一台新的」的環境。當您需要向稽核人員證明機器上執行的內容時,這種方式也很有幫助,因為答案會是映像檔摘要,而不是套件清單。

如果您只有一台手動維護的 VPS,上面執行三項服務,需要什麼就直接安裝什麼,而且沒有建置管線,就不適合採用這種方式。映像檔模式不會消除工作,只會把工作從伺服器移到建置流程,並為此增加 registry 和管線的成本。如果您有地方承擔這些工作,就能取得彼此一致的伺服器,且只要重新開機即可回復上一版。如果沒有,就只是為原本運作正常的主機增加元件,讓凌晨 2 點的維運更加困難。

採用一般發行版並啟用自動安全性更新,再搭配實際演練過的重建流程,仍然是可行的折衷方案。選擇基礎系統本身就是另一項決策,詳見 選擇 VPS 上要執行的 OS。映像檔模式只是關於軟體應如何進入機器的古老爭論再次出現,而 Linux 發行版的歷史 大致上就是這場爭論不斷重演的結果。

FAQ

Immutable Linux 發行版真的不可變嗎?

不是真的,這個名稱容易造成混淆。root 仍然可以寫入磁碟。實際情況是,/usr 在執行期間會以唯讀方式掛載,並在下一個映像檔中整體替換;/etc 和 /var 則維持可寫入,且會在更新期間保留。你在 /usr 下所做的變更,會在當下被拒絕,或於下一次更新時捨棄。因此實際效果是,系統目錄只會在映像檔變更時更新。

如果 VPS 未提供 Fedora CoreOS 或 Flatcar,我可以執行它們嗎?

通常可以,前提是供應商提供救援系統與主控台存取權限。先啟動救援系統,將該發行版的磁碟映像檔寫入區塊裝置,再重新開機。Flatcar 的 flatcar-install script 可在任何 Linux 系統中執行這項操作,而 Fedora CoreOS 將 coreos-installer 以容器形式提供,也能用相同方式執行。兩者都需要包含 SSH key 的 Ignition 檔案,因為首次開機時沒有可供使用的密碼提示。若沒有主控台存取權限,請勿嘗試;機器若無法重新上線,你將沒有任何方式查看問題。

如何在 immutable server 上安裝套件?

將套件加入映像檔,然後重新部署。在 bootc 中,這表示在 Containerfile 加入 RUN dnf -y install ... 行、重新建置並推送,接著在機器上執行 sudo bootc upgrade --apply。在 Fedora CoreOS 中,可以使用 sudo rpm-ostree install 將套件分層加入並重新開機,但之後每次更新都必須重新套用該套件。在 Flatcar 和 Talos 中沒有套件管理員,因此應使用容器。若只需在 bootc 主機上暫時使用除錯工具,sudo bootc usr-overlay 會提供可寫入的 /usr,並在下一次重新開機時消失。

image mode 能修復核心更新後無法開機的 VPS 嗎?

它能將復原工作從救援主控台操作轉為重新開機。先前的映像檔、核心與使用者空間仍完整保留在磁碟上,因此執行 sudo bootc rollback 或 sudo rpm-ostree rollback -r 即可切回先前版本。Talos 和 Flatcar 更進一步:如果新的 slot 無法開機,系統會在未收到手動指示時自動回復,因為開機項目必須成功開機一次後,才會成為預設項目。這些機制都無法防止錯誤更新,但能讓回復操作的成本很低。

應該選擇哪個 immutable distro 作為 server?

如果你要的是通用 Linux server,希望像建置 container image 一樣建置系統,並能將其安裝到既有機器上,請選擇 bootc。如果你希望採用相同模式,但由系統代為完成建置,且開箱即用地提供自動更新,請選擇 Fedora CoreOS。如果你需要採用 A/B 更新機制的精簡 container host,並且不提供套件管理員讓人安裝套件,請選擇 Flatcar。只有在該機器是 Kubernetes node 時才選擇 Talos,因為它沒有 login shell,也不會執行其他服務。

#bootc#immutable#atomic#coreos#updates