静态迁移(冷迁移)
对于静态迁移,你可以在宿主机上保存一个完整的客户机镜像快照,然后在宿主机中关闭或者暂停该客户机,然后将该客户机的镜像文件复制到另一台宿主机中,使用在源主机中启动该客户机时的命令来启动复制过来的镜像。
动态迁移(热迁移)
如果源宿主机和目的宿主机共享存储系统,则只需要通过网络发送客户机的 vCPU 执行状态、内存中的内容、虚机设备的状态到目的主机上。否则,还需要将客户机的磁盘存储发到目的主机上。共享存储系统指的是源和目的虚机的镜像文件目录是在一个共享的存储上的。
在基于共享存储系统时,KVM 动态迁移的具体过程为:
1、迁移开始时,客户机依然在宿主机上运行,与此同时,客户机的内存页被传输到目的主机上。
2、QEMU/KVM 会监控并记录下迁移过程中所有已被传输的内存页的任何修改,并在所有内存页都传输完成后即开始传输在前面过程中内存页的更改内容。
3、QEMU/KVM 会估计迁移过程中的传输速度,当剩余的内存数据量能够在一个可以设定的时间周期(默认 30 毫秒)内传输完成时,QEMU/KVM 会关闭源宿主机上的客户机,再将剩余的数据量传输到目的主机上,最后传输过来的内存内容在目的宿主机上恢复客户机的运行状态。
4、至此,KVM 的动态迁移操作就完成了。迁移后的客户机尽可能与迁移前一致,除非目的主机上缺少一些配置,比如网桥等。
注意:当客户机中内存使用率非常大而且修改频繁时,内存中数据不断被修改的速度大于KVM能够传输的内存速度时,动态迁移的过程是完成不了的,这时候只能静态迁移。关于实时迁移的效率,业界不少人提出了改进的建议,比如通过使用内存压缩技术,减少需要传输的内存的大小
迁移注意事项
1、最好迁移的服务器cpu品牌一样
2、64位只能在64位宿主机间迁移,32位可以迁移32位和64位宿主机
3、宿主机名字不能冲突
4、目的宿主机和源宿主机软件配置尽可能的相同,如 有相同的桥接网卡,资源池等。
5、两台迁移的主机 cat /proc/cpuinfo |grep nx 的设置是相同的NX,全名为“No eXecute”,即“禁止运行”,是应用在CPU的一种技术,用作把存储器区域分隔为只供存储处理器指令集,或只供数据使用。任何使用NX技术的存储器,代表仅供数据使用,因此处理器的指令集并不能在这些区域存储。这种技术可防止大多数的缓冲溢出攻击,即一些恶意程序,把自身的恶意指令集放在其他程序的数据存储区并运行,从而把整台计算机控制。
静态迁移
1.拷贝镜像文件和虚拟机配置文件
2.重新定义此虚拟机
动态迁移
1.创建共享存储
2.两台机器挂载共享存储(手工挂载;使用资源池)
3.启动动态迁移
4.创建迁移后的虚拟机配置文件
5.重新定义虚拟机
迁移帮助命令
1. virsh migrate --help 2. 3. [--domain] <string> 域名,id 或 uuid 4. [--desturi] <string> 客户端(常规迁移)或者源(p2p 迁移)中看到到目的地主机连接 URI 5. --live 热迁移 6. --offline 离线迁移 7. --p2p 点对点迁移 8. --direct 直接迁移--tunnelled 管道迁移 9. --persistent 目的地中的持久 VM 10. --undefinesource 在源中取消定义 VM 11. --suspend 部启用目的地主机中的域 12. --copy-storage-all 使用全磁盘复制的非共享存储进行迁移 13. --copy-storage-inc 使用增值复制(源和目的地共享同一基础映像)的非共享存储进行迁移 14. --change-protection 迁移结束前不得对域进行任何配置更改 15. --unsafe 即使不安全也要强制迁移 16. --verbose 显示迁移进程 17. --compressed 实时迁移过程中压缩重复的页 18. --auto-converge force convergence during live migration 19. --rdma-pin-all support memory pinning during RDMA live migration 20. --abort-on-error 在迁移过程中忽略软错误 21. --migrateuri <string> 迁移 URI, 通常可省略 22. --graphicsuri <string> 无空隙图形迁移中使用的图形 URI 23. --listen-address <string> listen address that destination should bind to forincoming migration 24. --dname <string> 在迁移过长中重新命名为一个新名称(如果支持) 25. --timeout <number> 如果 live 迁移超时(以秒计)则强制虚拟机挂起 26. --xml <string> 包含为目标更新的 XML 的文件名 27. --migrate-disks <string> comma separated list of disks to be migrated
迁移实例
冷迁移时把kvm1中的配置文件,通过scp命令传到kvm2中;热迁移时需要把配置输入到nfs服务器中,导入本地目录,达到开机状态还可以继续迁移。拓扑图如下:
冷迁移
顾名思义,关机后迁移,类似与克隆。
先查看都有哪些虚拟机,下面正好打开一台myvm02,连接进入在当前目录创建一个文件,输入一些内容,等迁移完成的时候查看。
1. [root@kvm1 ~]# virsh list --all 2. Id Name State 3. ---------------------------------------------------- 4. 4 myvm02 running 5. - vm01 shut off 6. - vm02 shut off 7. 8. 9. [root@kvm1 ~]# virsh console myvm02 10. Connected to domain myvm02 11. Escape character is ^] 12. 13. CentOS Linux 7 (Core) 14. Kernel 3.10.0-1160.el7.x86_64 on an x86_64 15. 16. localhost login: root 17. Password: 18. [root@localhost ~]# hostnamectl set-hostname 8-10 19. [root@localhost ~]# bash 20. [root@8-10 ~]# vi test.txt 21. hello world
关机后查看确定是否关机
1. [root@kvm1 ~]# virsh shutdown myvm02 2. Domain myvm02 is being shutdown 3. 4. [root@kvm1 ~]# virsh list --all
通过scp命令把磁盘文件复制到kvm2上,因为磁盘较大,需要稍等片刻。不知道磁盘文件的使用virsh dumpxml myvm02找磁盘文件。
[root@kvm1 ~]# scp /kvm/img/vm02.qcow2 192.168.8.20:/kvm/img
把myvm02虚拟机配置文件导出,传到kvm2中
1. [root@kvm1 ~]# virsh dumpxml myvm02 > /tmp/vm02.xml 2. [root@kvm1 ~]# scp /tmp/vm02.xml root@192.168.8.20:/etc/libvirt/qemu/
打开kvm2,从新定义虚拟机,查看myvm02已经存在,开机测试查看 是否有test文件,到此冷迁移完成。
1. [root@kvm2 ~]# virsh define /etc/libvirt/qemu/vm02.xml 2. Domain myvm02 defined from /etc/libvirt/qemu/vm02.xml 3. 4. [root@kvm2 ~]# virsh list --all 5. Id Name State 6. ---------------------------------------------------- 7. - myvm02 shut off 8. 9. [root@kvm2 ~]# virsh start myvm02 10. Domain myvm02 started 11. 12. CentOS Linux 7 (Core) 13. Kernel 3.10.0-1160.el7.x86_64 on an x86_64 14. 15. 8-10 login: root 16. Password: 17. Last login: Mon Apr 24 17:21:09 on ttyS0 18. [root@8-10 ~]# cat test.txt 19. hello world
热迁移
热迁移要求较高,磁盘文件需要做nfs共享,虚拟网卡配置为网桥模式方便测试,这里将配置从nfs开始,后面创建池、卷、虚拟机。
打开nfs服务器
1. [root@nfs ~]# yum -y install nfs-utils rpcbind 2. #省略安装内容 3. [root@nfs ~]# mkdir /nfsdir 4. [root@nfs ~]# vim /etc/exports 5. /nfsdir *(rw,sync,no_root_squash) 6. 7. [root@nfs ~]# systemctl start nfs rpcbind 8. [root@nfs ~]# systemctl enable nfs rpcbind
测试nfs
打开另外两台kvm
1. [root@kvm1 ~]# showmount -e 192.168.8.30 2. Export list for 192.168.8.30: 3. /nfsdir *
配置本地地址解析
1. [root@kvm1 ~]# vim /etc/hosts 2. 192.168.8.10 kvm1 3. 192.168.8.20 kvm2 4. [root@kvm1 ~]# scp /etc/hosts root@192.168.8.20:/etc/
配置kvm1网络
1. [root@kvm1 ~]# cd /etc/sysconfig/network-scripts/ 2. [root@kvm1 network-scripts]# cp ifcfg-ens33 ifcfg-br10 3. [root@kvm1 network-scripts]# vim ifcfg-ens33 4. TYPE=Ethernet 5. NAME=ens33 6. DEVICE=ens33 7. ONBOOT=yes 8. BRIDGE=br10 9. [root@kvm1 network-scripts]# vim ifcfg-br10 10. DEVICE=br10 11. TYPE=Bridge 12. BOOTPROTO=static 13. NAME=br10 14. ONBOOT=yes 15. IPADDR=192.168.8.10 16. GATEWAY=192.168.8.2 17. DNS1=8.8.8.8 18. [root@kvm1 network-scripts]# systemctl restart network
配置kvm2网络
1. [root@kvm2 ~]# cd /etc/sysconfig/network-scripts/ 2. [root@kvm2 network-scripts]# cp ifcfg-ens33 ifcfg-br10 3. [root@kvm2 network-scripts]# vim ifcfg-ens33 4. TYPE=Ethernet 5. NAME=ens33 6. DEVICE=ens33 7. ONBOOT=yes 8. BRIDGE=br10 9. [root@kvm2 network-scripts]# vim ifcfg-br10 10. DEVICE=br10 11. TYPE=Bridge 12. BOOTPROTO=static 13. NAME=br10 14. ONBOOT=yes 15. IPADDR=192.168.8.20 16. GATEWAY=192.168.8.2 17. DNS1=8.8.8.8 18. [root@kvm2 network-scripts]# systemctl restart network
创建kvm1与kvm2之间互信
kvm1
1. [root@kvm1 ~]# ssh-keygen -t rsa 2. #直接按回车 3. [root@kvm1 ~]# ssh-copy-id 192.168.8.20 #传给对端kvm2
kvm2
1. [root@kvm2 ~]# ssh-keygen -t rsa 2. #直接按回车 3. [root@kvm2 ~]# ssh-copy-id 192.168.8.10 #传给对端kvm1
测试时,使用ssh 加对端ip无交互即可登录对端主机。
开始创建存储池,两台都需要创建,如果做动态迁移,虚拟机需要在nfs共享目录内。下面创建的池名为nfspool(自己定义)类型是netfs 源主机是nfs服务器ip,源地址是nfs服务器中的共享目录,而目标地址就是kvm主机的存放目录。(这条命令就相当于挂载目录)
1. [root@kvm1 ~]# mkdir /kvm/nfspool 2. [root@kvm1 ~]# virsh pool-define-as --name nfspool --type netfs --source-host 192.168.8.30 --source-path /nfsdir --target /kvm/nfspool 3. Pool nfspool defined 4. 5. [root@kvm1 ~]# virsh pool-start nfspool 6. Pool nfspool started
kvm2操作跟上面一样
1. [root@kvm2 ~]# mkdir /kvm/nfspool 2. [root@kvm2 ~]# virsh pool-define-as --name nfspool --type netfs --source-host 192.168.8.30 --source-path /nfsdir --target /kvm/nfspool 3. Pool nfspool defined 4. 5. [root@kvm2 ~]# virsh pool-start nfspool 6. Pool nfspool started
现在池中是没有卷的,先创建一个卷,这里就在kvm1中创建了,因为是挂载上了,创建的卷会在nfs服务器中共享到kvm2中。下面命令表示在nfspool池中创建一个nfs_vm01.qcow2的卷,大小为10G,文件类型为qcow2 。
1. [root@kvm1 ~]# ls /kvm/nfspool/ 2. [root@kvm1 ~]# virsh vol-create-as nfspool nfs_vm01.qcow2 10G --format qcow2 3. Vol nfs_vm01.qcow2 created 4. 5. [root@kvm1 ~]# virsh vol-list nfspool 6. Name Path 7. ------------------------------------------------------------------------------ 8. nfs_vm01.qcow2 /kvm/nfspool/nfs_vm01.qcow2
现在查看kvm2,上面是有磁盘文件的。
1. [root@kvm2 ~]# ls /kvm/nfspool/ 2. nfs_vm01.qcow2
安装一台虚拟机到共享池,创建的是后就需要等一会了,注意设置时区,root密码等。
[root@kvm1 ~]# virt-install -n vm001 -r 1024 --vcpus 1 -l /kvm/iso/centos.iso --disk /kvm/nfspool/nfs_vm01.qcow2 -w bridge=br10 --nographics -x "console=ttyS0"
到这里是不是觉得上面的操作很熟悉,没错就是继续NFS的存储池,这里nfs服务器省略了创建LVM卷,生产环境中还是不能省略的。因为我这里nfs目录中没有虚拟机所以需要创建迁移的虚拟机。它的工作原理简单来说,在kvm1共享目录中的虚拟机,也在kvm2共享目录中,因为是挂载的nfs服务,当要维护kvm1的时候需要停止它的服务,这时可以把虚拟机转换kvm2中开启,关闭kvm1的虚拟机,而服务时不会停,后面测试用ping访问。
登录虚拟机,获取地址。
1. localhost login: root 2. Password: 3. [root@localhost ~]# dhclient 4. [root@localhost ~]# ip a show ens3 5. 2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 6. link/ether 52:54:00:40:41:ed brd ff:ff:ff:ff:ff:ff 7. inet 192.168.8.132/24 brd 192.168.8.255 scope global dynamic ens3 8. valid_lft 1797sec preferred_lft 1797sec
切换会kvm1,实现迁移。迁移前使用win端ping虚拟机ip,切记添加-t参数一直ping,查看切换的同时会不会有延迟。
[root@kvm1 ~]# virsh migrate vm001 --live --unsafe qemu+ssh://192.168.8.20/system
可以看到下图中有一个请求超时,但马上就好了。
查看kvm1中的虚拟机,vm001已经关闭。
1. [root@kvm1 ~]# virsh list --all 2. Id Name State 3. ---------------------------------------------------- 4. - myvm02 shut off 5. - vm001 shut off 6. - vm01 shut off 7. - vm02 shut off
查看kvm2中的虚拟机,vm001已经迁移过来了,并且是开启状态。
1. [root@kvm2 ~]# virsh list --all 2. Id Name State 3. ---------------------------------------------------- 4. 1 myvm02 running 5. 4 vm001 running
错误总结
下面这个错误表示地址解析不到kvm2,想到了没有给他们两台地址解析,这个文档上面已经添加了。
1. [root@kvm1 ~]# virsh migrate vm001 --live --unsafe qemu+ssh://192.168.8.20/system 2. error: Unable to resolve address 'kvm2' service '49152': Name or service not known