靜態遷移是指在虛擬機關閉或暫停的狀況下,將源宿主機上虛擬機的磁盤文件和配置文件拷貝到目標宿主機上。這種方式須要顯式的中止虛擬機運行,對服務可用性要求高的需求不合適。
***
動態遷移無需拷貝虛擬機配置文件和磁盤文件,可是須要遷移的主機之間有相同的目錄結構放置虛擬機磁盤文件,能夠經過多種方式實現,本例採用基於共享存儲動態遷移,經過NFS來實現。ubuntu
源宿主機:Ubuntu17.10 Server版操做系統,4.10.0-38-generic內核。下文中以「Node1」表示,主機名爲Service,IP地址爲192.168.200.132,NFS掛載目錄/opt。
目標宿主機:Ubuntu17.10 Server版操做系統,4.10.0-38-generic內核。下文中以「Node2」表示,主機名爲Service1,IP地址爲192.168.200.131,NFS掛載目錄/opt。
基於QEMU的動態遷移虛擬機鏡像文件爲ubuntu16server.img。
基於libvirt的靜態遷移測試虛擬機:demo1,IP爲192.168.200.132,虛擬鏡像文件爲ubuntu16.img。
基於libvirt的動態遷移測試虛擬機:demo2,IP爲192.168.200.131,虛擬鏡像文件爲ubuntu16.img。
NFS服務器:Ubuntu17.10 Server版,4.10.0-38-generic內核。IP地址爲192.168.200.130,服務目錄爲/opt/share。vim
KVM虛擬機動態遷移無需拷貝虛擬機配置文件和磁盤文件,可是須要遷移的主機之間有相同的目錄結構放置虛擬機磁盤文件(本例爲「/opt/share」目錄),這裏的動態遷移是基於共享存儲動態遷移,經過NFS來實現,須要QEMU 0.12.2以上版本支持。可使用如下命令查看安裝的QEMU的版本號。api
qemu-img --help|grep version安全
首先在NFS服務器上,下載安裝NFS,kernel-server至關於server端,common是client端,使用命令如下命令進行安裝NFS:服務器
sudo apt-get install nfs-kernel-server nfs-common -y網絡
配置NFS服務器,將NFS服務器上的「/opt/share」目錄設爲服務目錄。首先使用如下命令建立目錄,而後修改建立的目錄權限,同時若是不放心是否權限修改了,能夠查看下文件夾的權限,修改後爲「drwxr-xr-x」app
sudo mkdir /opt/share,
sudo chmod 777 /opt/share
sudo ll /optdom接下來使用vim修改「/etc/exports」:文件添加共享目錄,在該文件最後添加如下內容便可。/opt/share:表示要設置的共享目錄,_*_:表示容許全部的網段訪問,也可使用具體的IP。rw:表示掛載此目錄的客戶端對該共享目錄具備讀寫權限。sync:表示資料同步寫入內存和硬盤。no_root_squash:表示root用戶具備對根目錄的徹底管理訪問權限。no_subtree_check:表示不檢查父目錄的權限。修改完畢後保存退出。ssh
/opt/share *(rw,sync,no_subtree_check,no_root_squash)socket
_「/etc/exports」_文件修改後,使用命令而後進行刷新。最後啓動NFS服務,命令以下:
sudo exportfs –r
sudo /etc/init.d/rpcbind restart
sudo /etc/init.d/nfs-kernel-server restartNFS服務啓動後,在Node1上使用如下命令查看遠程主機的共享目錄,能夠看到如下斜體內容
sudo showmount -e 192.168.200.130
root@Service:~# sudo showmount -e 192.168.200.130
Export list for 192.168.200.130:
/opt/share *分別在Node1和Node2上分別掛載NFS服務器的共享文件夾到本地「/opt」目錄中,而後將Node1上的的虛擬磁盤文件ubuntu16server.img(前面實驗中製做的ubuntu的鏡像文件)拷貝到掛載NFS服務器共享目錄的文件夾「/opt」中(我製做好的鏡像文件在/root文件夾中),以後能夠看到ubuntu16server.img鏡像文件。在節點2上執行一樣的操做,但在Node2中不用執行拷貝這一命令。
sudo mount -t nfs 192.168.200.130:/opt/share /opt -o rw
sudo cp /root/ubuntu16server.img /opt掛載拷貝完成後兩節點都有相同的虛擬機磁盤文件存儲目錄
在Node1上使用以下命令啓動虛擬機,ubuntu16server.img爲前面實驗製做的鏡像文件,-monitor stdio表示能夠進入QEMU監控器,以便接下來執行遷移命令。
qemu-system-x86_64 -hda ubuntu16server.img -m 1024 -smp 1 -vnc :0 -monitor stdio
(qemu)- 打開VNC界面,鏈接節點1上的QEMU虛擬機,登錄以後並執行「top」命令,能夠看到界面一直在發生改變。
在Node2上使用如下命令啓動一個虛擬機,該虛擬機並無真實啓動,只是用於等待接收動態遷移過來的內存內容,使用VNC鏈接後顯示界面狀態爲黑屏,或者是有一行提示。這裏須要注意:在Node2上,NFS掛載目錄必須與源主機上保持一致;啓動客戶機命令也需一致,可是須要增長-incoming 選項。「-incoming tcp:0:6666」 這個參數表示在6666 端口創建一個tcp socket 鏈接用於接收來自於源宿主機的動態遷移的內容,其中「0」表示容許來自任何主機的鏈接,「-incoming」表示使QEMU進程進入到遷移監聽(migration-listen)模式,而不是真正以命令行中的鏡像文件運行客戶機。另外,這裏是以NFS服務器上的鏡像文件做爲虛擬機磁盤來啓動虛擬機,若是有多個用戶同時使用NFS服務器上的鏡像文件,請將鏡像文件在本地進行派生,使用派生後的鏡像文件啓動虛擬機,具體方式讀者可自行查閱相關資料
qemu-system-x86_64 -hda /opt/ubuntu16server.img -m 1024 -smp 1 -vnc :0 -incoming tcp:0:6666
在Node1源宿主機的qemu monitor 命令行中輸入如下命令遷移虛擬機,進入動態遷移的流程,其中「192.168.200.131」是目標宿主機IP,TCP協議和6666端口與目標宿主機上命令行的-incoming 參數保持一致
(qemu) migrate tcp:192.168.200.131:6666 //(qemu)爲啓動鏡像時出現的qemu monitor
- 在Node1上執行"migrate"命令從開始到執行完成,大約十秒鐘(視網絡而定),在執行完成後遷移成功。遷移後在Node2上,也就是目標宿主機上,以前處於遷移監聽狀態的虛擬機開始運行,在該虛擬機中能夠查看到,原來在Node1上運行的虛擬機上執行的top命令在遷移後仍在繼續在Node2上執行。
至此基於QEMU的虛擬機動態遷移完成
- 靜態遷移也叫作常規遷移、離線遷移(Offline Migration)。是在虛擬機關機或暫停的狀況下,拷貝虛擬機磁盤文件與配置文件從源宿主機到目標宿主機中,實現的從一臺物理機到另外一臺物理機的遷移。由於虛擬機的文件系統創建在虛擬機鏡像文件上面,因此在虛擬機關機的狀況下,只須要簡單的遷移虛擬機鏡像和相應的配置文件到另一臺物理主機上便可。若是須要保存虛擬機遷移以前的狀態,那麼應該在遷移以前將虛擬機暫停,而後拷貝狀態至目標宿主機,最後在目標宿主機重建虛擬機狀態,恢復執行。這種方式的遷移過程須要顯式的中止虛擬機的運行。從用戶角度看,有明確的一段停機時間,虛擬機上的服務不可用。這種遷移方式簡單易行,適用於對服務可用性要求不嚴格的場合。
爲網絡添加br0網橋
sudo brctl addbr br0
sudo brctl addif br0 ens33
sudo brctl stp br0 on
sudo ifconfig ens33 0
sudo dhclient br0在Node1上進行操做,首先肯定demo虛擬機狀態爲「shut off」,若是不是能夠執行「destroy
」 進行關閉sudo virsh list --all
準備遷移demo虛擬機,查看demo虛擬機的磁盤文件
virsh domblklist
導出虛擬機配置文件demo.xml、ubuntu16.img,將其發送到Node2中與Node1中文件對應的文件夾(demo.xml文件在文章結尾會給出代碼)
sudo scp /root/demo.xml /root/ubuntu16.img 192.168.200.131:/root
- 以後開始在目標宿主機Node2上進行虛擬機的配置和啓動。
使用virsh的子命令define定義並註冊demo虛擬機
sudo virsh define /root/demo.xml
啓動遷移後的demo虛擬機,經過VNC查看,VNC端口查看
sudo virsh vncdisplay
而後經過VNC查看是否能夠登錄和其餘操做
- 此處我說明下,這種遷移雖然爲基於Libvirt的動態遷移,可是其遷移的只是虛擬機的狀態而不是虛擬機的狀態和文件,這一點我再次特別說明。
將Node1上的「ubuntu16.img」發送到Node2對應的文件夾,此時的demo狀態爲「shut off」,發送後啓動demo虛擬機
sudo scp /root/ubuntu16.img 192.168.200.131:/root
查看Node1上虛擬機狀態,demo虛擬機保證處於「runing」(若是demo處於「shut off」,將其啓動運行「sudo virsh start demo」)
sudo virsh list --all
- 查看Node2上虛擬機狀態,確保無虛擬機運行,命令如上
- 經過VNC鏈接登錄,並執行"top"命令
在Node1上執行「virsh migrate」遷移命令,虛擬機demo在遷移出去的過程當中,狀態有從「running」到「shut off」的一個改變。--verbose 指遷移demo虛擬機,192.168.200.131爲節點2的IP地址,使用tcp協議鏈接,--unsafe參數表示跳過安全檢測, /system爲以root身份進行狀態遷移,qemu+ssh表示爲經過ssh通道鏈接到遠程節點的system實例,具備最大權限來管理遠程節點上的虛擬機資源
sudo virsh migrate --live --verbose demo qemu+ssh://192.168.200.131/system tcp://192.168.200.131 --unsafe
在Node2上,查看虛擬機demo虛擬機狀態爲「runing」
sudo virsh list --all
- 在遷移過程當中,能夠經過另一臺客戶機一直ping虛擬機demo,查看demo遷移過程當中的可鏈接性。實際上遷移過程除了偶爾有幾個包的中斷,基本上沒有太大影響
此時雖然demo虛擬機已經在Node2上啓動了,可是Node2上尚未demo虛擬機的配置文件。這時須要建立配置文件並定義該虛擬機,能夠經過遷移過來的虛擬機內存狀態建立虛擬機配置文件,而後經過xml配置文件定義虛擬機。
sudo virsh dumpxml demo > /etc/libvirt/qemu/demo1.xml //之因此命名爲demo1.xml是由於,在libvirt靜態遷移過程當中已經有個demo.xml文件,雖然不在同一個文件夾,爲了不搞混。
sudo virsh define /etc/libvirt/qemu/demo1.xml經過VNC鏈接查看,VNC端口號查詢。
sudo virsh vncdisplay demo
- 在經過VNC鏈接上後發現遷移前的「top」命令依然在執行
至此,demo虛擬機遷移完成。
<!-- WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE OVERWRITTEN AND LOST. Changes to this xml configuration should be made using: virsh edit demo or other application using the libvirt API. --> <domain type='kvm'> <name>demo</name> <uuid>782ca9b9-8403-4fcd-979e-e4f038aaeb15</uuid> <memory unit='KiB'>1048576</memory> <currentMemory unit='KiB'>1048576</currentMemory> <vcpu placement='static'>1</vcpu> <os> <type arch='x86_64' machine='pc-i440fx-trusty'>hvm</type> <boot dev='cdrom'/> <boot dev='hd'/> </os> <features> <acpi/> <apic/> <pae/> </features> <clock offset='localtime'/> <on_poweroff>destroy</on_poweroff> <on_reboot>restart</on_reboot> <on_crash>destroy</on_crash> <devices> <emulator>/usr/bin/kvm</emulator> <disk type='file' device='disk'> <driver name='qemu' type='qcow2'/> <source file='/home/ubuntu16.img'/> <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk> <controller type='usb' index='0'> <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> </controller> <controller type='pci' index='0' model='pci-root'/> <controller type='ide' index='0'> <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> </controller> <interface type='bridge'> <mac address='52:54:00:c0:a2:8a'/> <source bridge='br0'/> <model type='rtl8139'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </interface> <input type='tablet' bus='usb'/> <input type='mouse' bus='ps2'/> <input type='keyboard' bus='ps2'/> <graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0' keymap='en-us'/> <video> <model type='cirrus' vram='9216' heads='1'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> </video> <memballoon model='virtio'> <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> </memballoon> </devices> </domain>