OpenStack虛擬機狀態


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

 ../_images/PowerStates2.png../_images/PowerStates1.png

 

digraph states {
  node [fontsize=10 fontname="Monospace"]
  /* states */
  building [label="BUILDING"]

  active [label="ACTIVE"]
  paused [label="PAUSED"]
  suspended [label="SUSPENDED"]
  stopped [label="STOPPED"]
  rescued [label="RESCUED"]
  resized [label="RESIZED"]
  soft_deleted [label="SOFT_DELETED"]
  deleted [label="DELETED"]
  error [label="ERROR"]
  shelved [label="SHELVED"]
  shelved_offloaded [label="SHELVED_OFFLOADED"]

  /* apis */
  create [shape="rectangle"]
  create -> active
  create -> error
  building -> create

  delete [shape="rectangle"]
  delete -> deleted
  building -> delete
  paused -> delete
  suspended -> delete
  stopped -> delete
  rescued -> delete
  soft_deleted -> delete
  error -> delete

  soft_delete [shape="rectangle"]
  soft_delete -> soft_deleted
  soft_delete -> error
  active -> soft_delete
  stopped -> soft_delete

  restore [shape="rectangle"]
  restore -> active
  restore -> error
  soft_deleted -> restore

  pause [shape="rectangle"]
  pause -> paused
  pause -> error
  active -> pause

  unpause [shape="rectangle"]
  unpause -> active
  unpause -> error
  paused -> unpause

  suspend [shape="rectangle"]
  suspend -> suspended
  suspend -> error
  active -> suspend

  resume [shape="rectangle"]
  resume -> active
  resume -> error
  suspended -> resume

  start [shape="rectangle"]
  start -> active
  start -> error
  stopped -> start

  stop [shape="rectangle"]
  stop -> stopped
  stop -> error
  active -> stop
  error -> stop

  rescue [shape="rectangle"]
  rescue -> rescued
  rescue -> error
  active -> rescue
  stopped -> rescue
  error -> rescue

  unrescue [shape="rectangle"]
  unrescue -> active
  rescued -> unrescue

  resize [shape="rectangle"]
  resize -> resized
  resize -> error
  active -> resize
  stopped -> resize

  confirm_resize [shape="rectangle"]
  confirm_resize -> active
  confirm_resize -> error
  resized -> confirm_resize
  confirm_resize [shape="rectangle"]

  revert_resize -> active
  revert_resize -> error
  resized -> revert_resize

  snapshot [shape="rectangle"]
  snapshot -> active
  snapshot -> stopped
  snapshot -> error
  active -> snapshot
  stopped -> snapshot

  backup [shape="rectangle"]
  backup -> active
  backup -> stopped
  backup -> error
  active -> backup
  stopped -> backup

  rebuild [shape="rectangle"]
  rebuild -> active
  rebuild -> error
  active -> rebuild
  stopped -> rebuild

  set_admin_password [shape="rectangle"]
  set_admin_password -> active
  set_admin_password -> error
  active -> set_admin_password

  reboot [shape="rectangle"]
  reboot -> active
  reboot -> error
  active -> reboot
  stopped -> reboot
  paused -> reboot
  suspended -> reboot
  error -> reboot

  live_migrate [shape="rectangle"]
  live_migrate -> active
  live_migrate -> error
  active -> live_migrate

  shelve [shape="rectangle"]
  shelve -> shelved
  shelve -> shelved_offloaded
  shelve -> error
  active -> shelve
  stopped -> shelve
  paused -> shelve
  suspended -> shelve

  shelve_offload [shape="rectangle"]
  shelve_offload -> shelved_offloaded
  shelve_offload -> error
  shelved -> shelve_offload

  unshelve [shape="rectangle"]
  unshelve -> active
  unshelve -> error
  shelved -> unshelve
  shelved_offloaded -> unshelve
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM