虚拟机迁移
如果源宿主机和目的宿主机共享存储系统,则只需要通过网络发送客户机的 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命令帮助
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # 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、迁移时遇到的错误描述:
1 2 | # 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、迁移时的存储错误:
1 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错误:
1 2 | # 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.迁移时语法错误:
1 2 | # 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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具