TECHNOLOGY / EDGE RELEASES
節點失聯了,不代表更新已經停止
失聯:沒有回覆,還不是操作結束
主管問:「他現在還在處理嗎?」
「不知道,電話沒接,訊息也沒回。」
主管想了一下:「那就當他沒在處理,交給別人吧。」
一個原本只是「不知道」的問題,經過討論,成功變成了「我們已經確認」。
最近我做了一個小專案:Fleetweft。這是一個採單一控制器設計的小型邊緣應用程式發布管理工具,用來研究更新、故障處理與狀態復原。

其中一個問題是:節點更新到一半突然失聯,原本的部署名額能不能釋放?
不能只看它有沒有回覆。它可能還沒開始,可能正在更新,也可能已經完成,只是確認訊息沒有送達。
失去聯絡,不代表操作已經停止。
部署名額:保留未知,也要安排接手
因此,Fleetweft 會保留已授出的部署名額,直到操作狀態得到釐清。Pause 會停止授出新名額,但不會把已經授出的操作當成不存在。
這就像公司只有一個改版名額。原負責人失聯,主管把名額交給另一個人。
隔天兩個人都回來:「主管,我完成了!」
主管很感動:「兩位都很有 Ownership!」
直到發現,他們改的是同一套系統。
保留名額也有代價。如果狀態一直無法確認,發布進度就可能一直卡住。這不是一句「保守一點比較安全」就能帶過。
誰負責釐清?需要什麼證據才能繼續?無法自動復原時,由誰接手?這些都需要事先想清楚。
既有 VM 紀錄刻意讓控制器先持久保存提交授權,再丟失第一次回覆。節點沒收到回覆,不代表授權沒有發生。Pause 之後,控制器仍保留該名額,重送同一份已保存的授權,讓原操作完成結算;同時不授出後續節點的新操作。
Canary:看實際服務,而不只看程序
Fleetweft 也會先在指定的 Canary 節點驗證,檢查應用程式實際提供服務時的回傳結果,再決定是否繼續發布。程序啟動了,還不足以認定更新成功。
這是一道功能放行檢查,不能當成統計可靠性的證據,也不是持續健康監測。
其中一個情境讓 Canary 回報健康,實際服務卻傳回錯誤結果。受測流程恢復基準版本、暫停發布,沒有放行後續節點。這份證據支持的是該情境下的功能把關;通過這一道檢查,仍不能替其他服務或之後的每一刻背書。
復原證據:要求已送出,服務恢復了嗎?
Rollback 同樣需要證據。發出復原要求,不等於原本的服務已經恢復;未經驗證的復原,仍然保持 UNKNOWN。
另一個情境在節點回報 FAILED_RESTORED 後,終止已恢復的應用程式。當實際探測仍失敗,控制器保留該授權的 UNKNOWN 占額;直到 Agent 重新啟動、重建健康基準並回報後,才有足夠證據結算。日誌寫下「已復原」,仍要核對服務是否真的可用。
節點重新連線後,也要處理舊操作與新版 Release 的關係,避免遲到的命令覆蓋後來的設定。
控制通道使用 mTLS,應用程式套件必須通過簽章驗證。不過,來源可信,不代表程式沒有缺陷;驗證簽章,也不等於把程式隔離在安全沙箱裡。
驗證範圍:一次受控實驗能說到哪裡
目前的驗證紀錄包括:
- macOS 與 Linux 各通過 69 項 Portable Tests。
- 15 個 Linux VM 測試情境,以及另外保留的正常 VM 重啟驗證。
但三個節點是同一台 VM 裡的網路命名空間(Network Namespaces),共用核心、磁碟與故障範圍。這不是三台獨立主機的故障隔離驗證。
目前受測的部署範圍,是 Linux ARM64 上受信任、已簽章、單檔且無狀態的 Python HTTP 應用程式。高可用(HA)、突然斷電、持久資料遷移與正式環境可靠性,都不在這次驗證結論裡。
接手:把未知變成具體工作
對我而言,這次最重要的不是把更新指令送出去,而是把幾件容易混在一起的事情分開:
指令送達,不代表更新完成。
節點失聯,不代表操作停止。
要求復原,不代表服務已恢復。
重新連線,也不代表舊命令仍然有效。
這些區別最後會影響發布速度、故障風險,以及維運人員需要承擔的工作。
最後,主管看著 Dashboard 問:
「這個 Unresolved 可以改成 Completed 嗎?」
「還沒有完成證據。」
「那改成 Failed?」
「也沒有失敗證據。」
主管想了一下:「能不能至少換個顏色?看起來比較好管理。」
狀態沒有比較清楚,但 Dashboard 已經比較樂觀了。
系統可以暫時沒有答案。重要的是保留已知事實、限制下一步操作,並讓需要介入的人知道:還有什麼沒有被確認。
繼續發布前,留下這三個答案
- 哪個節點持有哪一份已授操作?最後確認的 Release、操作識別與服務結果是什麼?
- 還缺哪份證據,才能釋放名額或確認復原?誰負責取得,何時重新檢視?
- 若一直無法釐清,由誰決定維持暫停、採取復原或人工介入?接手者能用什麼路徑查證實際狀態?
實驗證據
以下文件固定於公版來源 7e41d24,報告 run 06663f42a7edc9a0。本文沿用既有紀錄,沒有為撰文重新執行 VM 驗證。