1. 程式人生 > >OpenStack虛擬機狀態

OpenStack虛擬機狀態

調用 spawn ima per failed com sof 可用 虛擬機

OpenStack創建一個虛擬機,涉及到三種狀態,vm_state,task_state和power_state。

技術分享

先總結幾點:

  • 電源狀態(power_state):是hypervisor的狀態,從計算節點”由下而上“加載。
  • 虛擬機狀態(vm_state):反應基於API調用的一種穩定狀態,符合用戶體驗,從上而下的API實現。
  • 任務狀態(task_state):代表API調用過程的過渡狀態。
  • 只要數據庫可用,就可以強刪虛擬機。(”hard“ delete of VM)
  • 電源狀態和虛擬機狀態會彼此沖突,需具體情況具體分析。

Power_state

Power_state是我們調用虛擬機中驅動獲得的一個狀態,事實上hypervisor的狀態才是權威的。數據庫中power_state只是之前狀態的一個快照,

會被周期性更新,並且在有任務改變了power_state後要更新數據庫。

1、怎樣更新?

通常是”自下而上“,由計算節點產生,重寫數據庫。這個更新過程可能引起和vm_state的一致性沖突,如下。

2、power_state命名慣例

取決於ibvirt返回的狀態。

廢棄的狀態:

BLOCKED,本質上應該是RUNNING;

SHUTOFF,現在是SHUTDOWN;

FAILED,現在是NOSTATE。

vm_state

vm_sate描述虛擬機當前穩定狀態,而非過渡狀態。如果沒有running_tasks,虛擬機就應該是用戶期待的狀態,比如active。ACTIVE是一個vm_state,因為它代表虛擬機正常運行;而SUSPENDING是一個過渡狀態,代表n秒後虛擬機將被掛起,所以應該屬於task_state。

1、vm_stae怎樣更新

vm_state僅在任務結束後更新,即當一個任務成功結束並且設置task_state狀態為None。

當有API調用時,vm_state永遠不能改變。如果任務失敗,並且合適的清理後(比如live遷移失敗,任務回滾,虛擬機在源節點正常運行),虛擬機狀態不變。如果任務失敗並且不能回滾,vm_state狀態被置為ERROR。

2、vm_state命名慣例:使用一個形容詞

3、vm_state和power_state關系?

二者不是一一映射,代表的側重點不同,不能通過推理從一個得到另一個,所以都是需要的。

比如,當你去修復一個虛擬機,虛擬機從一個rescue鏡像啟動,此時power_state狀態為RUNNING,但是vm_state狀態只能是RESCUED。單單靠power_state是不能確定vm_state是ACTIVE還是RESCUED。

4、power_state和vm_state狀態不一致,如何修正?

首先,有正在運行的任務時,vm_state和power_state極有可能不同,因為vm_state代表一個穩定狀態,在任務運行期間,狀態是過度狀態,vm_state本來就是過期的。

當沒有任務運行時,power_state和vm_state應該保持一致,除非出錯或者失敗,這種情況,要具體分析。

a、如果power_state=SHUTOFF,但是vm_state=ACTIVE,極有可能是虛擬機內部shotdown命令出錯,所以power_state正確。一個粗暴但等價的方法,手動調用一個內部方法stop()API,虛擬機應該被修正為STOPPED。

b、如果power_state=BLOCKED,vm_state=HARD_DELETED,代表用戶已經要求刪除虛擬機但是過程失敗了。所以嘗試再次刪除。

c、如果power_state=BLOCKED,vm_state=PAUSED,代表可能是pause()方法調用前出了不可預料的問題。此時修正方法就看怎樣對用戶最友好了,maybe設置vm_state為ERROR。

到此,會發現 _sync_power_states (同步電源狀態)不鳥正在執行的任務,可能導致奇怪的錯誤。
5、如何從vm_state中獲得和EC2等價的狀態?

ec2狀態包含穩定狀態和過渡狀態。所以需要同時根據task_state和vm_state來推斷ec2狀態。

vm_state如下:

  • INITIALIZED:虛擬機僅僅在數據庫創建(應該是說表結構建好了),但是還沒開始創建。(狀態是BUILDING)
  • ACTIVE:虛擬機正在運行,使用特定的鏡像。
  • RESCUED:虛擬機正在運行,但使用rescue鏡像。
  • PAUSED:虛擬機暫停,使用特定鏡像。依然占用計算和內存資源。
  • SUSPENDED:虛擬機掛起,使用的是特定的鏡像,但是不占用計算和內存資源。
  • STOPPED:虛擬機停止,但是鏡像依然在磁盤上。
  • SOFT_DELETED:虛擬機不再計算節點運行了,但是磁盤鏡像依然保存,可以恢復。
  • HARD_DELETED:從配額和計費角度看,虛擬機不存在了。最終虛擬機和磁盤被銷毀。
  • RESIZED:虛擬機在源節點停止,在目標節點運行。虛擬機鏡像在源節點和目標節點都有,但是參數不同。用於需要確認resize(調整參數)或者恢復虛擬機。(廢棄的的task_state RESIZE_VERIFY和vm_state RESIZED功能一樣。)
  • ERROR:發生了無法恢復的錯誤,唯一的可執行的操作就是刪除虛擬機。

vm_state中廢棄的狀態REBUILDING,MIGRATING,RESIZING都放在了task_state中。而SHUTOFF不用了,因為這個狀態很費解,應該根據shutdown_terminate標記被劃分到STOPPED或者DELETED。

task_state

task_state代表過渡狀態,和一個computeAPI緊密相關,表明虛擬機當前執行哪個任務。處於vm_state的虛擬機是不會有task_state,只有正在運行的進程有task_state。

1、特定任務:force_delete(或者hard delete)

虛擬機什麽時候都能成功刪除。用戶刪除虛擬機可以釋放配額裏更多資源,不再被收費。不幸的是,可能出現這種情況,一個前置任務卡住了所以task_state永遠不能到None,或者虛擬驅動在銷毀虛擬機時卡住了,再或者計算節點因為網絡/硬件的原因不可用而無法執行銷毀虛擬機操作。所以,不應該等到force_delete() 任務獲得計算節點然後更新虛擬機狀態為HARD_DELETED。而應該是說,vm_state立馬更新而不去檢查計算節點。換句話說,force_delete() 任務是一個純粹的數據庫操作。一些善後工作(真正的清除工作)隨後進行,也不需要power_state和vm_state之間的一致性操作,因為它們會被定期觸發。

2、如何更新?

task_state被設置當確認它是虛擬機上唯一執行的任務時。要做到原子更新,任務開始會生成一個獨一無二的task_id(uuid格式)和虛擬機id關聯。如果虛擬機已經有一個VM id,說明已經有別的任務在運行。在任務執行過程中,task_id通過RequestContext數據格式傳播。在任務執行中途如果要更新ask_state,必須確認虛擬機的task_id匹配當前執行任務的id,否則新任務搶占當前任務(目前只有force_delete)。當任務成,task_state置為None,同時task_id置為None。

因為hard delete是唯一一個可以搶占其他任務的任務,我們沒必要立即設置task_id,但是需要檢查vm_state以確認它不是HARD_DELETE而不是去檢查task_id是否匹配。

3、真的要分開vm_state和task_state嗎?

從技術上講,虛擬機狀態(穩定)和任務狀態(過渡)沒有交集,可以組合使用。分開最大的好處就是狀態轉換圖簡單得多——只要考慮vm_state之間的DFA。如果需要增加一個新task_state,狀態轉換圖保持不變。

4、命名變化

最好用動詞+”ing“來描述task_state,且這個動詞是compute API方法。任務執行期間,task_state不變。要表述任務的進展,應該使用一個單獨的領域,而不是簡化狀態機。

  • None:沒有正在執行的任務
  • BUDILDING
  • IMAGE_SNAPSHOTTING
  • IMAGE_BACKINGUP
  • UPDATING_PASSWORD
  • PAUSING
  • UNPAUSING
  • SUSPENDING
  • RESUMING
  • DELETING
  • STOPPING
  • STARTING
  • RESCUING
  • UNRESCUING
  • REBOOTING
  • REBUILDING
  • POWERING_ON
  • POWERING_OFF
  • RESIZING
  • RESIZE_REVERTING
  • RESIZE_CONFIRMING
  • SCHEDULING
  • BLOCK_DEVICE_MAPPING
  • NETWORKING
  • SPAWNING
  • RESIZE_PREP
  • RESIZE_MIGRATING
  • RESIZE_MIGRATED
  • RESIZE_FINISH

廢棄的狀態:
RESIZE_VERIFY不是一個過渡狀態,而是穩定狀態。變成了vm_state中的新狀態RESIZED。

參考:

https://wiki.openstack.org/wiki/VMState

http://docs.openstack.org/developer/nova/devref/vmstates.html#preconditions-for-commands

OpenStack虛擬機狀態