天天看點

Nova 操作彙總(限 libvirt 虛機) [Nova Operations Summary]

本文梳理一下 Nova 主要操作的流程。

Nova 基本的 CRUD 操作和 extensions:

#

類别

Nova V2 REST API Action

Nova CLI

Horizon

解釋

虛機操作

POST

boot

Launch Instance

啟動一個新的虛機

DELETE

delete

Terminate Instance

關閉和删除一個虛機

call dom.destroy

call dom.undefineFlags

confirmResize

 resize-confirm

 N/A

确認 resize 操作 

<a href="http://www.cnblogs.com/sammyliu/p/4572287.html" target="_blank">http://www.cnblogs.com/sammyliu/p/4572287.html</a>

revertResize

 resize-revert

N/A 

取消 resize 操作

reboot

 reboot [--hard]

Soft Reboot Instance

Hard Reboot Instance 

重新開機虛機,具體分析見本文 1. 章節

changePassword

 root-password

 libvirt driver 沒有實作

resize

 resize

 Resize Instance

rebuild

 rebuild

 Rebuild Instance

 先調用 driver.destroy (destroy domain,detach volume connections,plug VIF), 然後再調用 driver.spawn

createImage

 image-create

 N/A 

os-start

 start

 Launch Instance

 = hard reboot,見下面 1. 章節

os-stop

 stop

 Shut Off Instance

 call dom.destroy

admin action

pause

 pause

 Pause Instance

 call dom.suspend

unpause

 unpause

 Resume Instance

 call dom.resume

suspend

 suspend

 _detach_pci_devices

_detach_sriov_ports

dom.managedSave(0)

resume

 resume

 get domain xml

_create_domain_and_network

attach pci devices

attach sriov port

migrate

 migrate

resetNetwork

 libvirt 沒有實作

injectNetworkInfo

 Set up basic filtering (MAC, IP, and ARP spoofing protection),調用 _conn.nwfilterDefineXML(xml)

lock

 lock

 直接在資料庫中 instance 上面設定 lock = true

unlock

 unlock

 直接在資料庫中 instance 上面設定 lock = false

createBackup

 backup

 同 createImage,可以指定類型(daily 或者 weekly),和儲存的 image 的最大數目,老的 image 會被删除

{"backup_type": "daily", "rotation": "2", "name": "bk"}

os-migrateLive

 live-migration

os-resetState

 reset-state

 傳入 state 參數,直接修改資料庫中 instance 的狀态

bare metal

add_interface

 baremetal-interface-add

TBD

remove_interface

 baremetal-interface-remove

TBD 

cloudpipe

update

 cloudpipe-configure

console

os-getVNCConsole

 get-vnc-console

 Console

見本文第四章節

os-getSPICEConsole

 get-spice-console

os-getRDPConsole

 get-rdp-console

os-getSerialConsole

os-getConsoleOutput

console-log

 View Log

 讀取 虛機的 console.log 檔案并傳回其内容;如果沒有這檔案的話,則使用 “pty”,将其内容寫入到 consolue檔案并傳回其内容。

restore

 restore

 Terminate Instance

 Restore a previously deleted (but not reclaimed) instance。直接修改資料庫。

forceDelete

 force-delete

 有 snapshot,則全部删除;然後從 DB 中删除 instance.

evacuate

 evacuate

 從 DB 中讀取 instance 資料,在一個新的主機上 rebuild。

flavor access

addTenantAccess

 flavor-access-add

 Flavor - Modify Access

 修改 DB 中 flavor 表

removeTenantAccess

 flavor-access-remove

 Flavor - Modify Access

flavor manage

 flavor-delete

 Flavor - Delete Flavor

直接 DB 操作

create

 flavor-create

 Flavor - Create Flavor

 直接 DB 操作

floating ip

addFloatingIp

 floating-ip-create

 Associate Floating IP

 調用 network_api.associate_floating_ip

removeFloatingIp

 floating-ip-delete

 Disassociate Floating IP

 調用 network_api.disassociate_floating_ip

NIC

addFixedIp

 fixed-ip-reserve

 參數 "networkId"。

call network_api.add_fixed_ip_to_instance

call firewall_driver.setup_basic_filtering

removeFixedIp

 fixed-ip-unreserve

 參數 "address"。

call network_api.remove_fixed_ip_from_instance

call firewall_driver.setup_basic_filtering(instance, nw_info) 

network associate

disassociate_host

 Associate or disassociate host or project to network。 call network_api.associate

disassociate_project

 network-disassociate

 call network_api.associate

associate_host

 network-associate-host

os network

disassociate

rescue

 rescue

 見本文第二章節

unrescue

 unrescue

security group

addSecurityGroup

 add-secgroup

 call security_group_rpcapi.refresh_security_group_rules

removeSecurityGroup

 secgroup-delete

shelve

 shelve

 見本文第三章節

shelveOffload

 shelve-offload

unshelve

 unshelve

實體機有兩種重新開機方式:一種從作業系統中重新開機,一種直接先斷電然後再接通電源。虛機的重新開機也有類似的兩種方式:Soft Reboot 和 Hard Reboot。nova reboot 指令在不使用 “-hard” 情況下,預設會 Soft Reboot,如果失敗則會 Hard reboot;如果使用了 “-hard”,則直接 Hard reboot。

Soft reboot 完全依賴于虛機的作業系統和 ACPI。其過程為:

Shutdown domain (domain.shutdown)

Launch domain (domain.createWithFlags)

關于 shutdown API ,它會shutdown一個虛機,但是虛機的各種附件(object)依然可以使用,隻是虛機的作業系統被停止了。注意,虛機的作業系統可能會忽略該請求。這時候,shutdown 不會成功(在 CONF.libvirt.wait_soft_reboot_seconds 指定的時間内,nova發現虛機沒有被 shutdown),得轉到 hard reboot 了。(Shutdown a domain, the domain object is still usable thereafter, but the domain OS is being stopped. Note that the guest OS may ignore the request.) 

Hard reboot 比 Soft reboot 複雜、耗時長。其主要過程為:

Destroy domain (virt_dom.destroy())。Destroy 和 Shutdown 兩個 API 的差別是:shutdown domain 以後,客戶機的磁盤存儲處于可用狀态,而且該 API 在指令發給 Guest OS 後立即傳回,客戶程式需要不斷檢查其狀态來判斷是否shutdown 成功;而 destroy API 執行後,客戶機的所有資源都會被歸還給 Hypervisor (all resources used by it are given back to the hypervisor),它的過程是首先給客戶機發送一個terminate 指令比如SIGTERM,如果在一定的時間内未成功則直接發送 SIGKILL 指令将虛機殺掉。

根據 domain 的資訊(instance, network_info, disk_info,image_meta, block_device_info)重新生成 domain 的配置 xml

根據 image 重新生成各鏡像檔案(包括 disk,disk.local 和 disk.swap)

連接配接各個 volume

将各個 interface 挂到 OVS 上

重新生成和應用 iptales 規則

Define domain (conn.defineXML)

Launch domain (domain.createWithFlags)

可見,hard reboot 是真正的 reboot 一個虛機。來比較一下 hard reboot 前後的虛機的磁盤和xml 檔案:

Nova 操作彙總(限 libvirt 虛機) [Nova Operations Summary]
Nova 操作彙總(限 libvirt 虛機) [Nova Operations Summary]

Rescue 是個很有意思的功能。它的一個使用場景是,虛機的啟動盤的一個檔案被誤删除了導緻無法再次啟動了,或者 admin 的密碼忘記了。Rescue 功能提供一個解決這類問題的手段。

執行 nova rescue 指令後的主要過程是:

(1)儲存目前domain 的 xml 配置到 unrescue.xml 檔案

(2)根據 image 重新生成啟動盤 disk.swap (大小不受 falvor.root_disk_size 控制,盡可能小的一個檔案)

Nova 操作彙總(限 libvirt 虛機) [Nova Operations Summary]
Nova 操作彙總(限 libvirt 虛機) [Nova Operations Summary]

(3)構造一個新的 domain 的 xml 配置,使用 disk.rescue 做啟動盤,将原來的 disk 挂載到該 domain,其他的盤和volume不會被挂載。

Nova 操作彙總(限 libvirt 虛機) [Nova Operations Summary]
Nova 操作彙總(限 libvirt 虛機) [Nova Operations Summary]

(4)将原來的 domain destroy 掉 (virt_dom.destroy)

(5)定義新的 domain (conn.defineXML(xml))

(6)啟動新的 domain (domain.createWithFlags)

至此,nova rescue 的過程完成。使用者可以 ssh 到新的虛機,修改 “Vdb“分區中的受損害的檔案。然後執行 ”nova unrescue“指令。其主要過程是:

(1)讀取之前儲存的 unrescue.xml 檔案

(2)将 rescued domain destroy 掉

(3)定義和啟動新的domain(同上面5和6)

(4)删除 unrescue.xml 檔案

注意,這時候檔案夾中的 libvirt.xml 檔案和新運作的 domain 的 xml 不一緻,因為代碼中沒有将新的 domain 的xml 寫到該檔案。

當一個虛機不需要使用的時候,可以将其 shelve 起來。該操作會建立該虛機的一個快照并傳到 Glance 中,然後在 Hypervisor 上将該虛機删除,進而釋放其資源。

其主要過程為:

destroy 虛機 (virt_dom.destroy())

snapshot 該 domain

如果 CONF.shelved_offload_time == 0 的話,将domain 的各種資源(interface,volume,執行個體檔案等),然後将其undefine (virt_dom.undefine())

其隻存在于資料庫和 Glance 中。運作 nova list 能看到一條記錄:

運作 glance image-list 能看到其image:

能看到該 image 的 instance 相關的屬性:

Nova 操作彙總(限 libvirt 虛機) [Nova Operations Summary]
Nova 操作彙總(限 libvirt 虛機) [Nova Operations Summary]

Unshelve 是 shelve 的反操作。它的主要過程是:

從 DB 中擷取 network_info 和 block_device_info

從 Glance 中擷取 image

象建立一個虛拟那樣 spawn 新的虛機

調用 image API 将 image 删除 

Nova 操作彙總(限 libvirt 虛機) [Nova Operations Summary]

(1)使用者查詢 VNC 的通路 URL。

Nova CLI 對應的指令為 “nova get-vnc-console &lt;server&gt; &lt;console-type&gt;”。 REST API 的資料格式為:{"os-getVNCConsole": {"type": "novnc"}} 

“type” 參數值可以是 “novnc” 或者 “xvpvnc”。

(2)通過 RPC 調用虛機所在的 node 上的 Nova 生成一個 UUID(長度為 4)格式的 token,以及格式為 ‘&lt;base_url&gt;?token=&lt;token&gt;' 的 Access URL。

base_url 從 CONF.novncproxy_base_url (比如 http://192.168.1.20:6080/vnc_auto.html)或者 CONF.xvpvncproxy_base_url 讀取。

(3)本地Nova 調用 libvirt driver 從 domain xml 中擷取 port,比如下面例子中的 5900,以及從 confi.vncserver_proxyclient_address 擷取 host。 

&lt;graphics type='vnc' port='5900' autoport='yes' listen='0.0.0.0' keymap='en-us'&gt;

&lt;listen type='address' address='0.0.0.0'/&gt;

&lt;/graphics&gt;

(4)通過 RPC,調用 consoleauth 的 authorize_console 方法,它将 Access URL, host,port 儲存到 memcached。

(5)傳回 Access URL 給用戶端,比如 http://192.168.1.20:6080/vnc_auto.html?token=8dc6f7cb-2e2d-4fbe-abab-3334fe3a19dc

在 Contoller 節點上運作着一個service “/usr/bin/python /usr/bin/nova-novncproxy --config-file=/etc/nova/nova.conf”。該 service 預設在 6080 端口(可由 CONF.novncproxy_port 配置)監聽來自所有位址(可由 CONF.novncproxy_host 配置)的請求。

(6)在用戶端浏覽器上打開 Access URL,由 Controller 上的 nova-novncproxy 接收并處理

(7)nova-novncproxy 通過 RPC 調用 consoleauth.check_token() 方法,擷取 console_type 和 port 等 connect info。期間還會到目的node上去校驗這些資訊。

(8)連接配接到目的 node,握手,開始 proxying。

 與 NOVNC 有關的配置參數:

節點

配置檔案

參數

預設配置

說明

Controller

/etc/nova/nova.conf

novncproxy_port

6080

/usr/bin/nova-novncproxy 服務所在的節點(通常是 Controller 節點)上 該 service 所監聽的端口。奇怪的是 nova 文檔中沒說明該配置參數。

novncproxy_host 

0.0.0.0

nova-novncproxy service 所監聽的請求來源位址。0.0.0.0 表示接收所有來源的請求。奇怪的是 nova 文檔中沒說明該配置參數。

nova-compute

vncserver_proxyclient_address

虛機所在的 nova compute 節點的 management 網卡的 IP 位址

vncserver_listen

127.0.0.1

虛機所在的 nova compute 節點的 vnc service 所監聽的端口,需要修改預設配置為其 0.0.0.0

novncproxy_base_url

http://127.0.0.1:6080/

vnc_auto.html

nova 用戶端通過 get_vncconsole 指令擷取到的通路虛機的 VNC URL。需要修改其值為 

http://&lt;nova-novncproxy-node-management-interface-ip&gt;:&lt;nova-novncproxy-node-nova.conf.novncproxy_port&gt;/vnc_auto.html 比如 http://192.168.1.20:6080/

vnc_enabled

true

使得虛機能夠對外提供 VNC 服務

作用:當一個 node down 掉後,在新的 node 上根據其 DB 中儲存的資訊重新 build down node 上虛機。這個往往在虛機 HA 方案中用到。它盡可能地将原來的虛機在新的主機上恢複:

虛機的配置:從 DB 中擷取,包括 image,block,network 等

虛機的資料:如果使用共享存儲,則使用共享存儲上的虛機資料;如果不使用共享存儲,則無法恢複資料

記憶體狀态:無法恢複

是以,HA 方案中,應該盡可能地将虛機的資料檔案放在共享存儲上,否則,恢複出來的虛機的價值非常有限。

Nova CLI:usage: nova evacuate [--password &lt;password&gt;] [--on-shared-storage] &lt;server&gt; [&lt;host&gt;]

要求:

(1)必須指定和虛機的 host 不同的 host,否則将報錯“The target host can't be the same one”。

(2)虛機的host 必須處于不可用狀态,否則将報錯 “Compute service of compute2 is still in use.”

(3)可以指定新的 admin password,不指定的話,nova 将生成一個随機密碼

(4)參數 on-shared-storage 表示虛機的 instance folder 是不是在共享存儲上。

主要步驟:

(1)在做完以上各種參數檢查後,調用 Conductor 的 方法:

return self.compute_task_api.rebuild_instance(context, instance=instance, new_pass=admin_password, injected_files=None, image_ref=None,

orig_image_ref=None, orig_sys_metadata=None, bdms=None, recreate=True, on_shared_storage=on_shared_storage, host=host)

如果 host 為none 的話,conductor 将調用 scheduler 的方法選擇一個 host。

(2)接着調用 nova compute 的 rebuild_instance 方法。該方法從系統(DB)中擷取已有的資料,然後根據這些已有的 metadata 重新構造domain。“A 'rebuild' effectively purges all existing data from the system and remakes the VM with given 'metadata' and 'personalities'.”

擷取 image_ref,再擷取 image meta

擷取 network_info 并在新的 host 上構造網絡

擷取 BlockDeviceMappingList

擷取 block_device_info

(3)然後調用 virt driver 的 rebuild 方法,但是 libvirt 沒有實作該方法,轉而調用 _rebuild_default_impl 方法。該方法:

從 volume 端斷開其與原來 host 的連接配接

調用 driver.spawn 方法構造新的 domain,依次建立 image(如果 on_shared_storage = false 的話,則重新下載下傳 image, 構造 instance folder;如果 on_shared_storage = true 的話,則直接使用共享存儲上的 instance folder。這也可見使用共享存儲的優勢),network 和 domain,并設定 domain 的狀态和之前一緻。

(4)在壞了的 host 被重新開機後,nova-compute 服務調用 _destroy_evacuated_instances 方法來找到 evacuated instances 并将它們删除:

調用 libvirt 找到該 host 上所有 domains,然後在 nova db 中一一查找其狀态,過濾出 “deleted” 為 false 的 domains

如果instance.host 不是本機,而且 instance.task_state 不是 { MIGRATING,RESIZE_MIGRATING,RESIZE_MIGRATED,RESIZE_FINISH} 之一,則删除該 domain,以及 network,block device 以及 instance folder。

總之,在使用共享存儲的情況下,evacuate 出來的新的 domain 除了臨時盤上的資料外,它和之前的 domain 的資料是一樣的了,但是記憶體狀态除外。

    本文轉自SammyLiu部落格園部落格,原文連結:http://www.cnblogs.com/sammyliu/p/4571209.html,如需轉載請自行聯系原作者