SSD Nodes Learn 🎉 VPS $5.50/月起
指南 Matt Connor作者: Matt Connor · 已更新 2026-08-16

VPS 即時 kernel 修補與重新開機差異

即時 kernel 修補會在不中斷連線的情況下替換執行中的函式,但未涵蓋所有問題。了解 unmanaged VPS 的適用範圍,以及為何重新開機只是延後。

VPS 上的即時 kernel 修補功能

即時 kernel 修補會在機器持續運作期間套用 kernel 安全性修正,不需要重新開機,也不會中斷現有連線。系統會將修正後的函式載入為 kernel module,並將對舊函式的每次呼叫重新導向至新的副本,同時持續處理網路流量。這項機制同時說明了即時修補的適用範圍,以及它無法處理的問題。

它能爭取時間,但無法取代重新開機。伺服器即使已進行六個月的即時修補,磁碟上的舊 kernel image 仍是目前的開機核心,而所有這些修補內容都只存在於記憶體中。

即時修補通常被當作代管方案的功能銷售。在自行管理的主機上,你只需執行兩個指令即可啟用這項功能。若你正評估是否支付 代管與自行管理 VPS 之間的價差,這一點值得先了解。

即時核心修補如何運作?

核心內建即時修補核心,並以 CONFIG_LIVEPATCH 編譯啟用。請檢查目前執行中的核心:

grep CONFIG_LIVEPATCH /boot/config-$(uname -r)

若輸出包含 CONFIG_LIVEPATCH=y,表示目前執行中的核心是在具備該核心的情況下建置。若沒有該核心,任何即時修補服務都無法在這台機器上運作。

這項重新導向本身使用 ftrace,也就是核心的函式追蹤器。大多數核心函式都會在函式最開頭編譯一個 call 指令,位置早於參數或堆疊受到處理之前。ftrace 會將這個呼叫位置作為 hook。套用修補程式時,即時修補核心會在目標函式上註冊 ftrace handler,接著由該 handler 將執行流程改送至替代函式。核心文件明確說明:「即時修補通常必須在函式進入點的最開頭重新導向程式碼,且此時函式參數或堆疊尚未以任何方式修改。」

這句話帶來兩項後果,稍後都很重要。只有 ftrace 能夠 hook 的函式才可修補,因此未編譯該進入點呼叫的函式完全無法修補。此外,修補單位是完整函式,絕不會是函式內的單一程式碼行。

更困難的部分,是安全地切換執行中的系統。如果替換函式時,某個 CPU 的堆疊上仍在執行舊程式碼,就會混合新舊行為。Upstream Linux 透過每個 task 的一致性模型處理這個問題。核心文件將其描述為混合模型:「結合 kGraft 的每個 task 一致性與 syscall barrier 切換,以及 kpatch 的堆疊追蹤切換。」只有在核心能確認某個 task 目前不在已修補函式內時,該 task 才會逐一移至新程式碼。在所有 task 都完成切換之前,修補程式都處於轉換中。

你可以自行查看結果。已套用的修補程式會出現在 /sys/kernel/livepatch 下方,每個修補程式各有一個目錄,目錄內列出已修補的函式。

ls /sys/kernel/livepatch/

列出空白表示記憶體中沒有載入任何即時修補程式。對於全新的伺服器,這是正常的初始狀態。

即時核心修補無法修正的問題

只有函式本體會套用修補。其他內容不會。

  • 已變更的資料結構。 如果上游修正為 struct 新增欄位,或變更現有欄位的意義,就沒有安全的方法可以改寫已配置且正在使用的物件。kpatch project 直接說明了等效情況:「不直接支援修改靜態配置資料的修補。」Shadow variables 和 callbacks 可作為替代方案,但必須針對每個修補手動撰寫,無法自動處理。
  • 同時分散在多個函式中的修正。 如果修正需要變更一組函式之間的鎖定順序,就必須同時變更所有函式;一致性模型會切換工作,而不是在單一時間點凍結整台機器。
  • 初始化程式碼。 標記為 __init 的函式在伺服器啟動完成前就已執行並釋放,因此沒有可重新導向的內容。
  • 新的核心版本與新功能。 即時修補只能在同一個核心系列內變更修補層級。它不會將核心從一個系列升級到另一個系列,也不會加入新功能。如果需要較新系列的內容,例如 Linux 7.1 中納入的變更,就必須安裝該核心並以它開機。
  • 使用者空間。 Canonical 明確說明了界線:「Canonical Livepatch 不會修補 OpenSSL 或 glibc 等使用者空間函式庫,因為這是 unattended-upgrades 或系統管理工具的責任。」即時修補的核心旁邊若仍有過時的 OpenSSL,就不能算是已修補的伺服器,因此請讓同一台主機上的 unattended upgrades 處理使用者空間套件

Ubuntu 的服務也有嚴重性限制。Canonical 表示,它「會修補具有 critical 和 high Common Vulnerability Scoring System (CVSS) 以及 Ubuntu Priority 評等的核心漏洞」。CVE(common vulnerabilities and exposures)識別碼代表一項漏洞,而 CVSS 是附加在該漏洞上的評分。medium 評等的核心 CVE 會在磁碟上的套件中修正,但不會套用即時修補,因此要等到下次重新開機時才會進入執行中的核心,在此之前不會生效。

即時核心修補有哪些選項?

目前常見的實作路線有三種,而且都使用相同的核心機制。

Canonical Livepatch 透過 Ubuntu Pro 提供。Ubuntu Pro 可供個人免費使用。Canonical 的說法是,個人使用「現在以及未來都可免費用於最多 5 台實體機器」,正式 Ubuntu Community 成員的上限則提高至 50 台。這是截至 August 2026 的文件化上限。商業用途需要付費訂閱。支援範圍依核心系列與 flavour 分別提供,涵蓋支援的長期支援(LTS)版本之一般可用性(GA)核心及其硬體啟用(HWE)核心,flavour 包括 generic、aws、azure、gcp、oracle、ibm 和 lowlatency。依賴這項功能前,請先將自己的核心與 Canonical 發布的核心清單比對。

KernelCare 由 TuxCare 提供,是商業 agent,支援多個發行版,包括沒有第一方服務的發行版。其文件記載的安裝方式是執行廠商提供的 script,curl -s -L https://kernelcare.com/installer | bash,接著使用 /usr/bin/kcarectl --register KEY 設定以金鑰為基礎的授權。之後 agent 會依自身排程檢查新的修補程式,而 /usr/bin/kcarectl --update 會強制執行檢查。在重要伺服器上將安裝程式串接至 shell 執行前,請先閱讀該安裝程式。

kpatch 和 kGraft 是這項技術的前身。kGraft 由 SUSE 開發,kpatch 由 Red Hat 開發;目前 upstream Linux 中的即時修補核心,是兩者概念的合併。kpatch 本身正在退場:其 README 表示,自 Linux 6.19 起「kpatch project is deprecated and in maintenance mode」,而 upstream kernel 中的 kpatch-build 將由 klp-build 取代。在 RHEL 及其重建版本上,應使用發行版提供的服務,而不是自行建立修補程式。

請依發行版支援的功能與授權條件進行選擇。就核心層級的結果而言,各方案相同。

如何在 Ubuntu 啟用 Canonical Livepatch

先從 Ubuntu Pro 帳戶頁面取得 token。以下兩個命令都需要可用的對外網路連線,因為 client 會連線至 Canonical 的伺服器以完成附加並取得修補程式。

sudo pro attach TOKEN
sudo pro status

不提供 token 直接執行 sudo pro attach 時,會改為啟動瀏覽器流程,並輸出一組要在 Canonical 網站輸入的代碼。完成附加後,系統會自動啟用建議的服務;在目前的 LTS 版本中,這通常包括 Livepatch。如果要自行選擇服務,請使用 sudo pro attach --no-auto-enable

如果 Livepatch 尚未啟用:

sudo pro enable livepatch
sudo canonical-livepatch status

此服務透過 canonical-livepatch snap 執行,因此 snapd 必須正常運作,啟用程序才能完成。pro status 會輸出包含服務授權與狀態的表格。canonical-livepatch status 會輸出每個 kernel 的詳細資訊,而 Canonical 的文件會顯示下列格式的輸出:

last check: 52 seconds ago
kernel: 5.4.0-216.236-generic
server check-in: succeeded
kernel state: ✓ kernel series 5.4 is covered by Livepatch
patch state: ✓ all applicable livepatch kernel modules applied
patch version: 113.1

其中兩行是判斷依據。kernel state 表示目前執行的 series 是否受此服務支援;如果開機使用的 kernel 不受 Livepatch 支援,這一行就會顯示異常。patch state 表示適用於該 kernel 的修補程式是否確實已載入。受支援但未套用任何修補程式,表示是 client 問題。不受支援則是 kernel 問題,沒有任何 client 設定可以解決。

如何判斷是否需要重新開機?

Livepatching 消除了緊急性,因此是否需要重新開機不再明顯。您必須主動檢查。

ls -l /var/run/reboot-required
cat /var/run/reboot-required.pkgs

套件管理器會在已安裝的套件需要重新啟動才能生效時建立 /var/run/reboot-required,而新的 linux-image 套件一律會建立該檔案。.pkgs 檔案會列出提出要求的套件。如果第一個命令回傳 No such file or directory,表示自電腦上次開機後,沒有任何套件要求重新開機。在目前的 Ubuntu 中,/var/run 是指向 /run 的符號連結,因此使用任一路徑都會存取相同檔案。

該旗標位於 tmpfs 中,每次開機都會重設,因此請直接對照核心本身確認:

uname -r
dpkg -l 'linux-image-*' | grep ^ii

uname -r 會輸出目前正在執行的核心。第二個命令會輸出磁碟上已安裝的核心套件。如果清單中的 linux-imageuname -r 回報的版本新,表示電腦仍在執行舊核心,不論 Livepatch 狀態為何。這項檢查才是重點,因為 live patching 的設計目標是確保執行中的核心安全,而不是讓核心保持最新。

至於同一問題的使用者空間部分,Ubuntu Server 預設會安裝 needrestart,用來列出仍持有已刪除程式庫檔案的執行中服務。

sudo needrestart -r l

-r l 旗標組合表示「僅列出」,因此只會回報資訊,不會變更任何內容。

為什麼仍然無法免除重新開機

磁碟上的 kernel 並未變更。Live patches 會載入正在執行的 kernel,但不會寫入 boot image。因此,重新開機後會使用 bootloader 選取的 linux-image,接著 Livepatch client 會重新套用仍然適用的 patches。在這兩個時間點之間,系統會執行尚未套用 patches 的程式碼。這也是應該啟動最新 kernel,而不是舊 kernel 的另一個原因。

Coverage 依 kernel series 分別計算,而 series 也會停止支援。執行中的 series 不再列於支援清單後,kernel state 行便會停止回報 coverage。唯一的解決方式是使用較新的 kernel。這就需要重新開機。

Medium 和 low severity 的 kernel fixes 不會以 live patch 方式套用。它們會留在磁碟上的 package 中,只有在啟動該 kernel 時才會生效。

長時間執行的 kernel 也會累積 patching 無法清除的狀態。Canonical 的說法值得引用,因為這是最誠實的說明:Livepatch「不是重新開機的替代方案,而是透過避免非預期的重新開機,讓你能更有效控制重新開機時機的工具。」其中真正關鍵的詞是 非預期的。你仍然需要重新開機,但可以自行選擇時機。

如何排程重新啟動並確認系統恢復

如果無法連線到主控台,VPS 重新啟動後就可能無法挽回。在輸入 reboot 前,先確認即使機器未能恢復,也有方法重新登入。

  • 確認供應商在控制面板提供 serial console 或 VNC(virtual network computing)畫面,並立即開啟,不要等到服務中斷時才處理。
  • 使用 df -h /boot 檢查可用空間。/boot 滿了時,kernel package 可能會在寫入 initramfs(initial RAM filesystem)時失敗,導致 bootloader 項目指向尚未完成的映像檔。
  • 至少保留一個已知可正常運作的舊 kernel。GRUB 會在「Advanced options for Ubuntu」下列出該 kernel;新 kernel 啟動失敗時,從這裡啟動是最快的復原方式。
  • 在需要前先找出供應商的 rescue mode。若重新啟動後主控台顯示 initramfs 提示字元,修復工作就要在該環境中進行。

請在你清醒且能處理問題的時間重新啟動:

sudo shutdown -r +5 "Kernel update, back in a moment"

這會將重新啟動排程在 5 分鐘後,並向已登入的使用者傳送訊息。sudo shutdown -c 可取消排程。機器恢復後,確認以下兩部分:

uname -r
sudo canonical-livepatch status

uname -r 現在應回報較新的 kernel,而狀態輸出也應回報新的系列已涵蓋。如果機器完全沒有恢復,問題幾乎總是在 boot path,而不是網路;此時應依照kernel 更新後無法啟動的 VPS 指南中的復原流程處理。

為什麼仍需清理舊 kernel

Live patching 反而會讓這個問題更嚴重,因為即使 linux-image 套件持續安裝,也不再有必須重新開機的壓力。每個 kernel 都會安裝 boot image、initramfs、modules tree,通常還會安裝 headers 套件。在只有數百 MB 的小型 VPS 上,若另有獨立的 /boot partition,安裝三或四個 kernel 就會將其填滿。

/boot 滿載後,下一次 kernel 安裝就會失敗,導致機器無法套用自己真正需要的更新。apt autoremove 流程會在舊 kernel 符合條件後清除它們;但對從未重新開機的主機而言,這些 kernel 不一定已符合條件,因為套件管理員不會移除你目前可能仍在使用的 kernel。

因此,請先確認已安裝的 kernel,保留目前執行中的 kernel 與一個已知可正常運作的 fallback,再依照 Ubuntu 移除舊 kernel 的安全程序移除其餘項目。絕對不要移除 uname -r 目前回報的 kernel。

FAQ

Live kernel patching 是否代表 VPS 永遠不需要重新開機?

不是。Live patch 會載入執行中的 kernel,但不會寫入開機映像,因此磁碟上的 linux-image 仍維持開機時使用的版本。Canonical 明確表示,Livepatch「不是重新開機的替代方案,而是一項讓您更能掌控重新開機時機的工具,可避免非預期的重新開機。」此外,當 kernel series 終止支援時,涵蓋範圍也會結束;中嚴重度的 kernel 修正也完全不會透過 live patch 套用。請依您選定的週期安排維護性重新開機,不要等到系統強制要求重新開機。

如何確認 live kernel patching 確實正在套用修補程式?

執行 sudo canonical-livepatch status 並查看兩行輸出。kernel state 顯示目前執行中的 kernel series 是否受該服務涵蓋,patch state 顯示該 kernel 的修補程式是否已載入。您也可以使用 ls /sys/kernel/livepatch/ 直接檢查 kernel 端的狀態;此命令會為每個已載入的修補程式列出一個目錄。若輸出為空,表示目前沒有任何修補程式套用在記憶體中,無論 client 回報什麼狀態。

個人 VPS 可以免費使用 Ubuntu Pro 嗎?

可以,但有文件所載的數量限制。Canonical 的說法是,Ubuntu Pro「現在及未來都會提供個人免費使用,最多支援 5 台實體機器」;截至 August 2026,正式 Ubuntu Community members 的上限提高至 50 台機器。商業用途需要付費訂閱。您可以從 Ubuntu Pro 帳戶頁面取得 token,使用 sudo pro attach TOKEN 附加機器,然後使用 sudo pro enable livepatch 啟用服務。

為什麼 Livepatch 執行後,kernel CVE 仍顯示未修正?

通常有兩個原因。修正可能低於嚴重度門檻,因為 Canonical 的 live patch 會「修補具有 critical 和 high Common Vulnerability Scoring System (CVSS) 與 Ubuntu Priority 評等的 kernel vulnerabilities」,其餘問題則交由磁碟上的套件處理。另一種可能是,該修正無法表示為函式本體的變更;例如 upstream 修改了資料結構,而 live patching 無法安全地修改已配置的物件。這兩種情況的處理方式相同:安裝更新後的 kernel package,然後開機進入該 kernel。

Live kernel patching 完全不涵蓋哪些內容?

Userspace。Canonical 明確說明,Livepatch「不會修補 OpenSSL 或 glibc 等 userspace libraries,因為這是 unattended-upgrades 或 systems management tool 的責任。」它也無法提供新的 kernel version 或新功能,因為它只會替換目前執行之 series 內的函式本體。此外,它無法修補 __init 函式,因為伺服器啟動完成時,這些函式已經執行完畢並從記憶體釋放。