雲端基礎架構無法承受非預期的停機,但透過 OpenStack,這已不再是問題。OpenStack 的即時遷移(OpenStack Live Migration )功能可將正在運行的虛擬機從同一叢集內的某個運算節點移至另一個節點。這確保了在維護底層硬體或軟體時,服務仍能持續運作。Nova 運算服務負責協調此流程,並透過主機疏散機制進一步擴展其功能;該機制旨在從已無法連線或完全故障的運算節點中恢復工作負載。
這兩項機制協同運作,賦予運維團隊靈活性,使其能同時應對預定的維護時段與非預期的節點故障,且無需將系統進行下線維護。
- host-evacuate
- host-evacuate-live
- host-server-migrate
- live-migration
- migrate
如標題所示,我們主要關注的是 host-evacuate-live,它會將所有運行中的 Instance 遷移到其他計算節點。這個操作要求較高,所以如果它能成功,其他類似的操作也應該沒有問題。我們來看看一個遷移失敗的範例以及如何修復它。
我們從一個由 3 個控制與計算節點(cc1、cc2 和 cc3)組成的叢集開始,所有的虛擬機 Instance 都處於運行狀態。
圖片來源:Bigstack CubeCOS
我們嘗試將所有在 cc2 上運行的 Instance 遷移到 cc3。
# nova host-evacuate-live cc2
注意,狀態已經從 ACTIVE 變為 MIGRATING。
圖片來源:Bigstack CubeCOS
幾秒鐘過去後,我們收到了好消息,兩個 Instance 成功地遷移到了 cc3。
圖片來源:Bigstack CubeCOS
經過足夠長的等待後,我們發現其中一個 Instance 處於 ERROR 狀態。值得注意的是,大多數情況下所有 Instance 都能成功遷移。
/Blog/Nova%2004.png?width=1349&height=188&name=Nova%2004.png)
圖片來源:Bigstack CubeCOS
此錯誤可以從 Horizon UI 中確認。
圖片來源:Bigstack CubeCOS
為了診斷問題,我首先檢查了日誌(logs)。在 cc2 節點的 nova-compute.log 中檢查了遷移的相關日誌,並發現了以下內容。
Live migration failed.: libvirt.libvirtError: Timed out during operation: cannot acquire state change lock (held by monitor=remoteDispatchDomainGetobStats)
同樣,檢查了目標節點 cc3 上的 libvirtd 日誌,並發現了類似的錯誤。
cc3 libvirtd[39220]: Timed out during operation: cannot acquire state change lock (held by monitor=remoteDispatchDomainMigratePrepare3Params)
由於 CubeOS 是基於 Linux 的,且底層的虛擬化技術是 KVM hypervisor,進一步調查意味著要檢查 qemu 進程。在 cc2 節點上,確實有一個正在運行的 qemu 進程,與我們的錯誤 Instance 完全吻合。
# ps awx | grep qemu
635175 ? Sl 51:20 /usr/libexec/qemu-kvm -name guest=instance-00000007,debug-threads=on -S
# virsh list
Id Name State
----------------------------------
2 instance-00000007 paused
Paused 狀態並不是預期的狀態,所以我想連接到 qemu 監控器進一步了解。
# virsh qemu-monitor-command --hmp 2 info status
有趣的是,這個命令一直掛起,這也解釋了為什麼日誌顯示操作超時,VNC 控制台也沒有回應。該進程顯示為運行狀態,但由於某些原因處於無反應狀態。一些舊的網絡文章暗示了 qemu 線程之間的競爭條件。通過 gdb/gstack 傾印的堆疊追蹤,結果與其他人觀察到的情況相似。感謝 libvirt 及其搭檔 virsh,虛擬機的配置在 xml 文件中有良好的追蹤。這意味著我們可以安全地終止無響應的進程,並使用相同配置創建一個全新的進程。
# virsh destroy 2
Domain '2' destroyed
# virsh list --all
Id Name State
------------------------------------
- instance-00000007 shut off
確實,舊的 qemu 進程被終止。
# ps awx | grep qemu
3633296 pts/2 S+ 0:00 grep --color=auto qemu
# virsh start instance-00000007
Domain 'instance-00000007' started
# virsh list
Id Name State
-----------------------------------
4 instance-00000007 running
# virsh qemu-monitor-command --hmp 4 info status
VM status: running
# virsh console 4
Connected to domain 'instance-00000007'
Escape character is ^] (Ctrl + ])
login as 'cirros' user. default password: 'gocubsgo'. use 'sudo' for root.
cirros-hotstorage-1a0e login: cirros
cirros
Password:
$ hostname
hostname
cirros-hotstorage-1a0e
$ uptime
uptime
19:25:08 up 12:03, 1 users, load average: 0.00, 0.00, 0.00
$
這幾乎是結束了,除了有一步是通知 OpenStack Instance 的狀態其實是健康的。
# openstack server set --state active 198e7b81-8267-44dc-a061-0cf63a970e57
圖片來源:Bigstack CubeCOS
一切又回到了正常狀態,但我還需要再執行一次撤離命令,將復原過的 Instance(仍然在 cc2 上)遷移到 cc3。
# nova host-evacuate-live cc2我們也可以連接到更友善的 UI 控制台,與新遷移的虛擬機進行互動。
圖片來源:Bigstack CubeCOS
經過所有這些操作後,cc2 節點變得空曠(沒有虛擬機 Instance ),並準備進行維護操作。
