如果源宿主機和目的宿主機共享存儲系統,則只需要通過網絡發送客戶機的 vCPU 執行狀態、內存中的內容、虛機設備的狀態到目的主機上。否則,還需要將客戶機的磁盤存儲發到目的主機上。共享存儲系統指的是源和目的虛機的鏡像文件目錄是在一個共享的存儲上的。
在基於共享存儲系統時,KVM 動態遷移的具體過程為:
- 遷移開始時,客戶機依然在宿主機上運行,與此同時,客戶機的內存頁被傳輸到目的主機上。
- QEMU/KVM 會監控並記錄下遷移過程中所有已被傳輸的內存頁的任何修改,並在所有內存頁都傳輸完成后即開始傳輸在前面過程中內存頁的更改內容。
- QEMU/KVM 會估計遷移過程中的傳輸速度,當剩余的內存數據量能夠在一個可以設定的時間周期(默認 30 毫秒)內傳輸完成時,QEMU/KVM 會關閉源宿主機上的客戶機,再將剩余的數據量傳輸到目的主機上,最后傳輸過來的內存內容在目的宿主機上恢復客戶機的運行狀態。
- 至此,KVM 的動態遷移操作就完成了。遷移后的客戶機盡可能與遷移前一直,除非目的主機上缺少一些配置,比如網橋等。
注意,當客戶機中內存使用率非常大而且修改頻繁時,內存中數據不斷被修改的速度大於KVM能夠傳輸的內存速度時,動態遷移的過程是完成不了的,這時候只能靜態遷移。
關於實時遷移的效率,業界不少人提出了改進的建議,比如通過使用內存壓縮技術,減少需要傳輸的內存的大小。這篇文章比較了各種方法,還是值得一讀。
1.3 使用命令行的方式做動態遷移
1.3.1 使用 NFS 共享存儲
(1)在源宿主機上掛載 NFS 上的客戶機鏡像,並啟動客戶機
mount my-nfs:/raw-images/ /mnt/
kvm /mnt/rh1.img -smp 2 -m 2048 -net nic -net tap
(2)在目的宿主機上也掛載鏡像目錄,並啟動一個客戶機用於接收動態遷移過來的內存內容
mount my-nfs:/raw-images/ /mnt/
kvm /mnt/rh1.img -smp 2 -m 2048 -net nic -net tap -incoming tcp:0:6666
注意:(1)NFS 掛載目錄必須一致 (2)“-incoming tcp:0:6666” 參數表示在 6666 端口建立一個 TCP socket 連接用於接收來自源主機的動態遷移的內容,其中 0 表示運行來自任何主機的連接。“-incoming“ 使 qemu-kvm 進程進入到監聽模式,而不是真正以命令行中的文件運行客戶機。
(3)在源宿主機的客戶機的 QEMU monitor 中,使用命令 ” migrate tcp:host2:6666" 即可進入動態遷移的流程。
1.3.2 不使用共享存儲的動態遷移
過程類似,包括使用相同backing file 的鏡像的客戶機遷移,以及完全不同鏡像文件的客戶機的遷移。唯一的區別是,migrate 命令中添加 “-b” 參數,它意味着傳輸塊設備。
1.3.3 其它 QEMU monitor migrate 命令
- migrate_cancel:取消遷移
- migrate_set_speed:設置最大遷移速度,單位是 bytes
- migrate_set_downtime:設置最大允許的服務暫停時間,單位是 秒
- info migrate:顯示遷移進度
virsh migrate --live virtual01 --copy-storage-inc qemu+tcp://192.168.136.96/system tcp://192.168.136.96 --verbose --persistent --p2p
libvirt 啟用遠程連接
(1)SSH方式
使用最簡單的SSH方式,只要擁有SSH連接到服務器的權限,就可以無需配置:
qemu+ssh://root@example.com/system
例如: qemu+ssh://root@172.16.0.12/system ,本機SSH連接到172.16.0.12時,要使用證書登錄,否則每次連接都需要輸入SSH用戶名和密碼。
(2)TCP方式:
qemu+tcp://example.com/system
例如:qemu+tcp://172.16.0.15/system,服務端只需要做簡單配置即可:
vim /etc/libvirt/libvirtd.conf:
listen_tls = 0 #禁用tls登錄
listen_tcp = 1 #啟用tcp方式登錄
tcp_port = "16509" #tcp端口16509
listen_addr = "0.0.0.0"
unix_sock_group = "libvirtd"
unix_sock_rw_perms = "0770"
auth_unix_ro = "none"
auth_unix_rw = "none"
auth_tcp = "none" #TCP不使用認證
max_clients = 1024 #最大總的連接客戶數1024
min_workers = 50 #libvirtd啟動時,初始的工作線程數目
max_workers = 200 #同上,最大數目
max_requests = 1000 #最大同時支持的RPC調用,必須大於等於max_workers
max_client_requests = 200 #每個客戶端支持的最大連接數
同時修改libvirt-bin的配置文件:
有的在 /etc/sysconfig/libvirtd
改成:
或者:
vim /etc/default/libvirt-bin:
# Start libvirtd to handle qemu/kvm:
start_libvirtd="yes"
# options passed to libvirtd, add "-l" to listen on tcp
libvirtd_opts="-d -l --config /etc/libvirt/libvirtd.conf"
以上修改后,執行service libvirt-bin restart即可。 netstat -anpt就能看到libvirtd監聽在TCP 16509端口
netstat -tlnp
前端 linux下開啟libvirtd的tcp監控
使用 virsh 連接到別的服務器時,使用的是 tcp 連接
virsh -c qemu+tcp://host/system
如果目標服務器沒有開啟 libvirtd 的 tcp 端口監聽時,會出現
error: unable to connect to server at 'host:16509': Connection refused
error: failed to connect to the hypervisor
ubuntu 下解決方法
sed -i 's/#listen_tls = 0/listen_tls = 0/g' /etc/libvirt/libvirtd.conf
sed -i 's/#listen_tcp = 1/listen_tcp = 1/g' /etc/libvirt/libvirtd.conf
sed -i 's/#auth_tcp = "sasl"/auth_tcp = "none"/g' /etc/libvirt/libvirtd.conf
vi /etc/default/libvirt-bin
修改為libvirt_opts = "-d -l"
增加-l監聽tcp
service libvirt-bin restart
centos 下解決方法
sed -i 's/#listen_tls = 0/listen_tls = 0/g' /etc/libvirt/libvirtd.conf sed -i 's/#listen_tcp = 1/listen_tcp = 1/g' /etc/libvirt/libvirtd.conf sed -i 's/#auth_tcp = "sasl"/auth_tcp = "none"/g' /etc/libvirt/libvirtd.conf sed -i 's/#LIBVIRTD_ARGS="--listen"/LIBVIRTD_ARGS="--listen"/g' /etc/sysconfig/libvirtd service libvirtd restart
api
使用libvirt控制KVM虛擬機進行熱遷移,這里記錄一下migrate方法的使用
import libvirt
import pprint
conn_004 = libvirt.open(‘qemu+tcp://username@server004/system’)
conn_005 = libvirt.open(‘qemu+tcp://username@server005/system’)
vm_domain = conn_004.lookupByName(‘instance_name’)
vm_domain.migrate(conn_005,True,’instance_name’,None,0)
pprint.pprint(help(vm_domain.migrate))
下面是程序的輸出,也就是migrate接口的說明
IBM example:
virsh --keepalive-interval 10 migrate --live --persistent --undefinesource --timeout 1200 --verbose vserv1 qemu+ssh://kvmhost/system
virsh migrate --live --auto-converge --timeout 300 vserv3 qemu+ssh://zhost/system
virsh migrate --live --auto-converge --timeout 300 --undefinesource --persistent vserv3 qemu+ssh://zhost/system
發現有問題:
網卡名字需要相同
/etc/hosts
這個是防火牆沒有開
第二個是 沒有相同名字的磁盤 qcow2
qemu版本相差太大
kvm 與 qemu-kvm
小版本差別。添加xml解決 網卡問題
qemu-kvm --version
qemu-img -V
kvm --version
libvirtd --version
171:
其他遇到問題:https://www.iteye.com/blog/liuzhijun-1744236
為什么要遷移呢?當一台主機的負載過高時,我們希望把虛擬機遷移到一台系統更好的主機上。當主機發生硬件故障需要停機維護時,我們需要遷移虛擬機,如果主機就只跑了一台虛擬機我們可以把它遷移到其他主機,提高資源的利用率,等等。

問題解決了,順便學習下libvirt migrate的概念:





https://blog.csdn.net/wan_hust/article/details/33793987:
之前一直以為KVM虛擬機遷移需要共享存儲,虛擬機的鏡像放到共享存儲中,遷移的過程相當於啟動一個監聽虛擬機,將內存數據copy到目標服務器上,然后銷毀source上的虛擬機,啟動target上的機器。
廢話不多說,直入正題(被遷移的機器成為:vmtest,所在服務器:source,目標服務器:target,#后是shell命令)
實驗環境:
RedHat 6.2
# virsh version
Compiled against library: libvir 0.9.4
Using library: libvir 0.9.4
Using API: QEMU 0.9.4
Running hypervisor: QEMU 0.12.1
主要用兩種方式,命令行virsh migrate
命令行比較簡單:
#virsh migrate vmtest qemu+ssh://target/system --live --storage-all
我們也可以用tcp代替ssh連接到目標服務器上,很多管理工具(webvirt)也是使用的tcp作為連接的方式。
在目的宿主機創建2個空的qcow2文件,路徑、文件名以及大小必須與原虛擬機一致
qemu-img create -f qcow2 -o preallocation=metadata kylin.qcow2 20G
virsh migrate --live --copy-storage-all --persistent –unsafe instance-1 qemu+ssh://root@compute02/system
virsh migrate --live --copy-storage-all --persistent –unsafe
七、virsh migrate命令幫助
# virsh migrate --help [--domain] <string> 域名,id 或 uuid [--desturi] <string> 客戶端(常規遷移)或者源(p2p 遷移)中看到到目的地主機連接 URI --live 熱遷移 --offline 離線遷移 --p2p 點對點遷移 --direct 直接遷移 --tunnelled 管道遷移 --persistent 目的地中的持久 VM --undefinesource 在源中取消定義 VM --suspend 部啟用目的地主機中的域 --copy-storage-all 使用全磁盤復制的非共享存儲進行遷移 --copy-storage-inc 使用增值復制(源和目的地共享同一基礎映像)的非共享存儲進行遷移 --change-protection 遷移結束前不得對域進行任何配置更改 --unsafe 即使不安全也要強制遷移 --verbose 顯示遷移進程 --compressed 實時遷移過程中壓縮重復的頁 --auto-converge force convergence during live migration --rdma-pin-all support memory pinning during RDMA live migration --abort-on-error 在遷移過程中忽略軟錯誤 --migrateuri <string> 遷移 URI, 通常可省略 --graphicsuri <string> 無空隙圖形遷移中使用的圖形 URI --listen-address <string> listen address that destination should bind to for incoming migration --dname <string> 在遷移過長中重新命名為一個新名稱(如果支持) --timeout <number> 如果 live 遷移超時(以秒計)則強制虛擬機掛起 --xml <string> 包含為目標更新的 XML 的文件名 --migrate-disks <string> comma separated list of disks to be migrated
八、 常見錯誤:
1、遷移時遇到的錯誤描述:
# virsh migrate centos live qemu+ssh://192.168.30.132/system error: unable to connect to server at 'KVM2:49152': No route to host
原因:你的免密登錄沒有成功
解決方法:重新做免密登錄即可
2、遷移時的存儲錯誤:
# virsh migrate centos live qemu+ssh://192.168.30.132/system error: Failed to open file '/mnt/CentOS6.8.qcow2': Input/output error
原因:存儲沒有掛載成功
解決方法:mount -o remount /dev/sdb /mnt
3、遷移時FQDN錯誤:
# virsh migrate centos live qemu+ssh://192.168.30.132/system error: internal error hostname on destination resolved to localhost, but migration requires an FQDN
原因:兩台宿主機無法解析主機名
解決方法:重新配置主機名和ip的解析
4.遷移時語法錯誤:
# virsh migrate centos live qemu+ssh://192.168.30.132:/system error: internal error Unable to parse URI qemu+ssh://192.168.30.132:/system
原因:qemu+ssh語法寫錯了 解 決 方 法 :
正 確 的 應 該 是 : virsh migrate centos live qemu+ssh://192.168.30.132/system
主機之間的客人遷移是一個復雜的問題,有許多可能的解決方案,每個解決方案都有自己的優點和缺點。為了最大限度地提高管理程序集成和管理員部署的靈活性,libvirt 實現了多個遷移選項。
網絡數據傳輸
遷移期間使用的數據傳輸有兩種選擇,一種是管理程序自己的本機傳輸,另一種是通過 libvirtd 連接進行隧道傳輸。
管理程序本機傳輸
本機數據傳輸可能支持也可能不支持加密,具體取決於所討論的虛擬機管理程序,但通常通過最小化所涉及的數據副本的數量來具有最低的計算成本。本地數據傳輸還需要管理員在部署主機時執行額外的特定於管理程序的網絡配置步驟。對於某些虛擬機管理程序,可能需要在防火牆上開放大量端口以允許多個並發遷移操作。
現代虛擬機管理程序支持 TLS 用於遷移連接的加密和身份驗證,可以使用VIR_MIGRATE_TLS標志啟用。qemu管理程序驅動程序允許用戶通過/etc/libvirt/qemu.conf中配置的 migrate_tls_force 旋鈕強制使用 TLS 。
libvirt 隧道傳輸
隧道數據傳輸將始終能夠進行強加密,因為它們能夠利用 libvirt RPC 協議中內置的功能。然而,隧道傳輸的缺點是,當數據在 libvirtd 和虛擬機管理程序之間移動時,源主機和目標主機都會涉及額外的數據副本。對於具有非常大 RAM 的客戶機來說,這可能是一個更嚴重的問題,這會很快弄臟內存頁面。在部署方面,隧道傳輸不需要任何額外的網絡配置,超出一般 libvirtd 遠程訪問所需的配置,並且只需要在防火牆上打開一個端口即可支持多個並發遷移操作。
注意:使用 libvirt 的隧道時,某些功能,例如非共享存儲遷移 ( VIR_MIGRATE_NON_SHARED_DISK )、多連接遷移 ( VIR_MIGRATE_PARALLEL ) 或復制后遷移 ( VIR_MIGRATE_POSTCOPY ) 可能不可用。
熱遷移:
1. mkdir hgh
2. chmod 777 hgh
3. qemu-img create -f qcow2 ubuntu-server.qcow2 20G //是否必須
4.獲取網卡 修改網卡,獲取路徑
5.修改xml文件 ,修改 網卡與路徑。
6.修改 /etc/hosts 添加ip name
5 .
需要添加用戶名
或者獲取存儲池
virsh pool-list
virsh pool-dumpxml default > default.xml
note:
cpu相同 個數相同 。 host-passthrough
macvtap0
macvtap1
網卡mac 修改
target 相同
pci mac地址
slot 以及bus都相同
如果在60-net.rules ,71-biosdevname.rules這兩條規則中沒有重命名網卡,且內核指定net.ifnames=1參數,則udev依次嘗試使用以下屬性值來命名網卡,如果這些屬性值都沒有,則網卡不會被重命名。
ID_NET_NAME_ONBOARD
ID_NET_NAME_SLOT
ID_NET_NAME_PATH
上邊的71-biosdevname.rules 是實際執行biosdevname的策略
以及host
參考:https://blog.csdn.net/hzj_001/article/details/81587824
go調用 libvirt api
https://libvirt.org/html/libvirt-libvirt-domain.html#virDommainMigrate2
https://libvirt.org/docs.html
virsh edit 10
vi 的時候
target 不同
alias 不同。
運行時候:
遇到問題:
https://patchwork.kernel.org/project/qemu-devel/patch/20170811164854.GG4162@localhost.localdomain/
'nbd-server-add': Block node is read-only
qemu-img -V
4.0.1
參考:
https://blog.csdn.net/LEoe_/article/details/78740088
https://www.cnblogs.com/sammyliu/p/4572287.html
https://blog.csdn.net/qiongtianliuyun/article/details/109205169
https://blog.csdn.net/x_i_y_u_e/article/details/45223157
https://blog.csdn.net/weiyuanke/article/details/8020657
https://www.dazhuanlan.com/reenigne/topics/1813118
https://blog.csdn.net/x_i_y_u_e/article/details/45223157
https://www.ibm.com/docs/en/linux-on-systems?topic=migration-migrate IBM
https://blog.csdn.net/wan_hust/article/details/33793987
https://www.iteye.com/blog/liuzhijun-1744236
http://t.zoukankan.com/mo-xiao-tong-p-12877030.html
https://libvirt.org/migration.html#id14