讀古今文學網 > OpenStack系統架構設計實戰 > 2.7.3 nova-compute >

2.7.3 nova-compute

nova-compute負責管理虛擬機,單獨運行於承載分配虛擬機的主機之上。nova-compute通過消息隊列獲取任務然後執行。

典型的業務流程是:nova-compute從消息隊列獲取分發給自己的消息,消息隊列的消息體裡定義了一系列的key/value值對,nova-compute需要對消息體進行解析。消息體中有個很重要的key是method,該key對應的value指明nova-compute需要完成的任務。以創建虛擬機為例,method對應的value為run_instance。run_instance指令要求nova-compute創建虛擬機。

首先nova-compute從Glance將虛擬機模板鏡像下載到/var/lib/nova/instances/_base/文件夾下,文件名即為image,在對像存儲上所對應的image_id,形如:

這裡存儲的還是原始模板鏡像文件。隨後,nova-compute會以這個鏡像為模板,創建一個虛擬機真正使用的磁盤映像文件。以KVM作為Hypervisor舉例,映像文件使用qcow2文件格式。

qemu-img create -f qcow1--o cluster_size=2M, backing_file=/var/lib/nova/ instances/_base/644208f3 /var/lib/nova/instances/instance-00000033/disk

如例所示,以644208f3這個鏡像文件為模板,通過qemu-img程序創建虛擬機磁盤文件/var/lib/nova/instances/instance-00000033/disk,其中instance-00000033是nova-compute動態創建的目錄,存放虛擬機實例相關信息,instance-00000033本身也是該虛擬機實例的instance-id。

隨後nova-compute會向/var/lib/nova/instances/instance-00000033/disk這個虛擬機文件注入SSH登錄的公鑰,以支持虛擬機啟動後通過私鑰方式登錄虛擬機。注入SSH公鑰的步驟如下:

1)連接到虛擬機文件/var/lib/nova/instances/instance-00000033/disk,將之虛擬成字符設備。

sudo qemu-nbd -c /dev/nbd15 /var/lib/nova/instances/ instance-00000033/disk

2)掛載文件系統。

sudo tune2fs -c 0 -i 0 /dev/nbd15sudo mount /dev/nbd15 /tmp/tmpLoFGru

3)建立SSH登錄環境目錄。

sudo mkdir -p /tmp/tmpLoFGru/root/.sshsudo chown root /tmp/tmpLoFGru/root/.sshsudo chmod 700 /tmp/tmpLoFGru/root/.ssh

4)將公鑰寫入SSH的配置文件/tmp/tmpLoFGru/root/.ssh/authorized_keys。

sudo tee -a /tmp/tmp4kabqd/root/.ssh/authorized_keys

5)釋放資源。

sudo umount /dev/nbd15rmdir /tmp/tmpLoFGrusudo qemu-nbd -d /dev/nbd15

通過該樣例過程,可瞭解nova-compute是如何向虛擬機注入數據的。如果是向虛擬機注入固定IP,也是相同思路,無非就是掛接虛擬機的磁盤文件到文件系統上,修改其內部的網絡配置文件。從H版本開始,這樣的直接注入方式不是默認方式,Nova又引入了ConfigDrive機制和metadata服務,來實現針對虛擬機內部數據的修改。

對於AMI格式的虛擬機鏡像,AMI格式的鏡像只包含一個根文件系統。Kernel和ramdisk是單獨另外存放的,不存放在鏡像裡面。為此,nova-compute也需要將Kernel和ramdisk從Glance上下載下來,複製到/var/lib/nova/instances/instance-00000033目錄下,nova-compute會自動創建一個libvirt.xml文件,該文件即是該虛擬機實例的配置文件,nova-compute通過libvirt接口調用KVM,KVM會使用libvirt.xml虛擬機配置文件來啟動虛擬機實例。最終,虛擬機運行實例動態目錄下的文件如下:

root@nova-compute-1:/var/lib/nova/instances/instance-00000033# lsconsole.log disk disk.local kernel libvirt.xml ramdiskroot@nova-compute-1:/var/lib/nova/instances/instance-00000033#

虛擬機啟動參數文件libvirt.xml樣例如下:

<domain type=\'kvm\'> <name>instance-00000033</name> <memory>2097152</memory> <os> <type>hvm</type> <kernel>/var/lib/nova/instances/instance-00000033/kernel</kernel><cmdline>root=/dev/vda console=ttyS0</cmdline><initrd>/var/lib/nova/instances/instance-00000033/ramdisk</initrd> </os> <features> <acpi/> </features> <vcpu>1</vcpu> <devices><disk type=\'file\'> <driver type=\'qcow2\'/> <source file=\'/var/lib/nova/instances/instance-00000033/disk\'/> <target dev=\'vda\' bus=\'virtio\'/></disk> <disk type=\'file\'><driver type=\'qcow2\'/><source file=\'/var/lib/nova/instances/instance-00000033/disk.local\'/><target dev=\'vdb\' bus=\'virtio\'/> </disk><interface type=\'bridge\'> <source bridge=\'br100\'/> <mac address=\'02:16:3e:2b:29:cf\'/> <!-- <model type=\'virtio\'/> CANT RUN virtio network right now --> <filterref filter=\"nova-instance-instance-00000033-02163e2b29cf\"><parameter name=\"IP\" /><parameter name=\"DHCPSERVER\" /> </filterref></interface><!-- The order is significant here. File must be defined first --><serial type=\"file\"> <source path=\'/var/lib/nova/instances/instance-00000033/console.log\'/> <target port=\'1\'/></serial><console type=\'pty\' tty=\'/dev/pts/2\'> <source path=\'/dev/pts/2\'/> <target port=\'0\'/></console><serial type=\'pty\'> <source path=\'/dev/pts/2\'/> <target port=\'0\'/></serial><graphics type=\'vnc\' port=\'-1\' autoport=\'yes\' keymap=\'en-us\' listen=\'0.0.0.0\'/> </devices></domain>

以上,以典型的虛擬機實例創建過程,說明了nova-compute基本工作原理。nova-compute從消息隊列獲取的任務主要有以下幾個:

·運行實例

·終止實例

·重啟實例

·添加卷

·去除卷

·獲得控制輸出

·遷移實例

·診斷實例

·擱置