5、KVM虚拟机热迁移实现
5、KVM虚拟机热迁移实现
刘付kin 发表于10个月前
5、KVM虚拟机热迁移实现
  • 发表于 10个月前
  • 阅读 46
  • 收藏 2
  • 点赞 0
  • 评论 0

腾讯云 十分钟定制你的第一个小程序>>>   

#问题:为什么需要热迁移? 集群中,有时候一台物理服务器上安装了很多虚拟机,这个时候hypervisor的网卡带宽、磁盘IO速度等都会成为它上面每一个虚拟机的瓶颈。这个时候需要把一些虚拟机迁移到其他机器上。

#问题:如何迁移? 所谓的迁移,无非是把镜像文件和虚拟机内存中的数据原样拷贝到另一台hypervisor上,然后又另一台hypervisor上的虚拟机代替这台虚拟机工作即可。

#问题:如何copy镜像?

  • 情况一:镜像文件就在hypervisor的filesystem上。通过scp、自己写socket程序都可以,但是这样的速度很慢,如果有500多G的镜像大小,那么需要很长的时间(集群中就不推荐把镜像文件直接放在hypervisor上。)

  • 情况二:镜像文件在NFS、SAS等集群存储系统中。hypervisor通过挂载的方式挂载镜像文件,这样在做热迁移的时候,只需要在另一台hypervisor上挂载(mount)NFS、SAS共享出来的文件夹,这样数据就相当于==>情况一的copy,瞬间copy完。

  • 架构图如下:(迁移前)

  • 架构图如下:(迁移后)

以上可以看出,迁移前后,镜像文件其实都没有被移动,还是在NFS存储系统中,只是被另一台hepervisor进行接管和操作而已。

#实现步骤:

#1、需要一个NFS集群的存储系统,NFS的介绍和安装

  • NFS就是Network File System的缩写,最早是由Sun公司发展开发出来的,它最大的功能就是可以通过网络,让不同计算机,不同操作系统,可以共享资源文件。用户和程序可以像访问本地文件一样访问NFS上的文件

  • 因为NFS支持的功能相当的多,而不同的功能都会使用不同的程序来启动,每启动一个功能就会启用一些端口来传输数据

  • NFS需要依赖RPC(Remote Procedure Call),RPC最主要的功能就是在指定每个NFS功能所对应的端口号,并且将其反馈给客户端,让客户端可以连结到正确的端口号上去 所以要启动NFS之前,RPC就要先启动了,否则NFS会无法向RPC注册

  • rpc.nfsd:

    这个daemon主要的功能就是在管理Client是否能够登入主机的权限,其中还包含这个登入者的ID的判断!

  • rpc.mountd

    这个daemon主要的功能,则是在管理NFS的文件系统!当Client端顺利的通过rpc.nfsd而登入主机之后,在他可以使用NFS服务器提供的档案之前,还会经过文件权限(就是那个 -rwxrwxrwx 与 owner, group 那几个权限)的认证程序!他会去读NFS的配置文件/etc/exports来比对Client的权限,当通过这一关之后Client就可以取得使用NFS文件的权限了! (注:这个也是我们用来管理 NFS 分享之目录的权限与安全设定的地方)

  • rpc.lockd

    这个进程可以用在管理文件的锁定 (lock) 用途。为何文件需要『锁定』呢? 因为既然分享的NFS档案可以让客户端使用,那么当多个客户端同时尝试写入某个文件时, 就可能对于该文件造成一些问题啦!这个rpc.lockd则可以用来克服这个问题。但rpc.lockd必须要同时在客户端与服务器端都开启才行喔!此外,rpc.lockd也常与rpc.statd同时启用。

  • rpc.statd 

    可以用来检查文件的一致性,与rpc.lockd有关!若发生因为客户端同时使用同一文件造成文件可能有所损毁时,rpc.statd可以用来检测并尝试恢复该文件。与 rpc.lockd 同样的,这个功能必须要在服务器端与客户端都启动才会生效。

  • rpc.rquotad

    处理当用户通过nfsmount到远程服务器时的配额

  • NFS /etc/exports配置含义

    /data1/storage *(rw,async,no_root_squash,no_subtree_check)

    /data1/storage 是要共享的目录

    *是允许访问的计算机,可以是以下内容

    单个机器:一个全限定域名(能够被服务器解析)、主机名(能够被服务器解 析)或IP地址。

    通配符指定的主机名,使用 * 或 ?字符来指定一个字符串匹配,IP地址中不使用通配符,*代表允许所有计算机访问共享目录

    IP 网络:使用a.b.c.d/z,a.b.c.d是网络,z是子网掩码中的位数(如192.168.0.0/24)。另一种可以接受的格式是 a.b.c.d/netmask,a.b.c.d是网络,netmask是子网掩码(如192.168.70.8/255.255.255.0)。

    () 内是共享选项

    rw是指客户端拥有读写权限,还有一个ro选项,代表只读

    sync 同步写入到内存与硬盘中

    async 异步写入,写入时会先放到内存,等硬盘有空档再写入

    root_squash 客户机用root用户访问该共享文件夹时,将root用户映射成匿名用户

    no_root_squash 客户端使用root访问共享目录时 还是拥有root权限,

    root_squash:如果客户端使用 root访问共享目录,会被当作匿名用户(也就是说,权限变的很小,比较安全)

    all_squash:无论客户端使用什么用户访问共享目录都会被当作匿名用户

    subtree_check 如果共享/usr/bin之类的子目录时,强制NFS检查父目录的权限(默认)

    no_subtree_check 和上面相对,不检查父目录权限

    其它选项参考man exports


  • 1、安装NFS(所有节点都要安装)

      yum -y install nfs-utils
    
  • 2、创建NFS存储目录

      mkdir -p /data1/storage
    
  • 3、修改/etc/exports

    vi /etc/exports

      /data1/storage *(rw,async,no_root_squash,no_subtree_check)
    
  • 4、修改/etc/sysconfig/nfs

    vi /etc/sysconfig/nfs (最后加入)

      LOCKD_TCPPORT=32803
      LOCKD_UDPPORT=32769
      MOUNTD_PORT=892
      RQUOTAD_PORT=875
      STATD_PORT=662
      STATD_OUTGOING_PORT=2020
    
  • 5、修改/etc/sysconfig/iptables

      -A INPUT -s 192.168.50.0/24 -m state --state NEW -p udp --dport 111 -j ACCEPT
      -A INPUT -s 192.168.50.0/24 -m state --state NEW -p tcp --dport 111 -j ACCEPT
      -A INPUT -s 192.168.50.0/24 -m state --state NEW -p tcp --dport 2049 -j ACCEPT
      -A INPUT -s 192.168.50.0/24 -m state --state NEW -p tcp --dport 32803 -j ACCEPT
      -A INPUT -s 192.168.50.0/24 -m state --state NEW -p udp --dport 32769 -j ACCEPT
      -A INPUT -s 192.168.50.0/24 -m state --state NEW -p tcp --dport 892 -j ACCEPT
      -A INPUT -s 192.168.50.0/24 -m state --state NEW -p udp --dport 892 -j ACCEPT
      -A INPUT -s 192.168.50.0/24 -m state --state NEW -p tcp --dport 875 -j ACCEPT
      -A INPUT -s 192.168.50.0/24 -m state --state NEW -p udp --dport 875 -j ACCEPT
      -A INPUT -s 192.168.50.0/24 -m state --state NEW -p tcp --dport 662 -j ACCEPT
      -A INPUT -s 192.168.50.0/24 -m state --state NEW -p udp --dport 662 -j ACCEPT
    
  • 6、重启防火墙

      service iptables restart
    
  • 7、启动NFS

      service rpcbind start
      service nfs start
      chkconfig rpcbind on
      chkconfig nfs on
    

#2、在hypervisor上挂载这个共享文件夹,用来存储镜像文件。

为了防止virsh启动虚拟机出错,所有Linux都修改selinux权限。

  • 1、关闭所有机器的SELinux

    sed -i 's/SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config

    sed -i 's/SELINUX=enforcing/SELINUX=permissive/' /etc/sysconfig/selinux

    setenforce 0

  • 2、然后重新启动libvirt

    service libvirtd restart

  • 3、查看NFS服务器共享了哪些文件夹

    showmount -e 192.168.30.250

  • 4、挂载到一个指定的目录中

    mkdir /mnt/storage

    mount -t nfs 192.168.30.250:/data1/storage /mnt/storage

  • 5、查看当前hypervisor挂载了那些磁盘

    mount

#3、虚拟机进行热迁移操作

##3.1、使用最基本的qemu-kvm来迁移

  • 注意操作系统的镜像一定要在NFS上的才行,不能够在hypervisor自己的filesystem上

  • 由于镜像在NFS上,所以镜像同步就没问题了,==> 剩下的就是虚拟机内存数据的同步

  • 1、在第一台hypervisor上启动虚拟机

    /usr/libexec/qemu-kvm -m 1024 -smp 1 -boot order=d -hda /mnt/storage/centos1.qcow2 -vnc :1 &

  • 2、在第二台hypervisor启动一个接收程序,用来接收第一个hypervisor虚拟机上的内存信息,同步过去**(注意:需要关闭iptables或者在iptables中开启8888端口)**

    /usr/libexec/qemu-kvm -m 1024 -smp 1 -incoming tcp:0:8888 /mnt/storage/centos1.qcow2 -vnc :1 &

  • 3、回到第一台hypervisor,使用taige VNC连接它的虚拟机,然后进入monitor模式

    QEMU monitor的切换

      "Ctrl + Alt + 2"  -->  QEMU monitor状态
      "Ctrl + Alt + 1"  -->  客户机标准显示窗口
    
  • 4、使用命令将虚拟机迁移到目标主机(会阻塞等待,迁移完成后,本虚拟机shutoff)

      migrate tcp:192.168.30.250:8888
    

    完成后,本虚拟机无法使用了,程序就这样被迁移到了另一台hypervisor上。

    注意:如果没有阻塞,说明无法连接到目标hypervisor,很有可能是目标hypervisor的iptables没有关闭或者8888端口没有开放。

##3.2、使用高级命令virsh。 注意:由于镜像是使用挂载NFS的方式,再启动虚拟机的时候,有可能出现这种问题

  • 1、启动虚拟机时会出现权限的问题

      error: Failed to start domain centos-nfs
    
      error: internal error process exited while connecting to monitor: 
      2015-07-16T21:37:17.473018Z qemu-kvm: -drive file=/mnt/storage/
      centos.qcow2,if=none,id=drive-virtio-disk0,format=qcow2: could not open 
      disk image /mnt/storage/centos.qcow2: Permission denied
    
  • 2、关闭SELinux

      sed -i 's/SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config
    
      sed -i 's/SELINUX=enforcing/SELINUX=permissive/' /etc/sysconfig/selinux
    
      setenforce 0
    
  • 3、然后重新启动libvirt

      service libvirtd restart
    
  • 4、根据配置文件启动虚拟机

    配置文件如下:

      <domain type="kvm">
          <!--虚拟机名称-->
          <name>onlyNAT</name>
          <!--最大内存,单位mb-->
          <memory unit="MiB">4096</memory>
          <!--可用内存,单位k-->
          <currentMemory unit="MiB">700</currentMemory>
          <!--虚拟cpu个数-->
          <vcpu>2</vcpu> 
    
          <os>
                  <type arch="x86_64">hvm</type>
                  <!-- 硬盘启动 -->
                  <boot dev="hd" />
                  <!--光盘启动-->
                  <boot dev="cdrom" />
          </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>
                  <!--指定基于那个虚拟化平台,也可以指定为xen-->
                  <emulator>/usr/libexec/qemu-kvm</emulator>
    
                  <disk type="file" device="disk">
                          <driver name="qemu" type="qcow2" />
                          <!--目的镜像>路径,设置为本虚拟化I/O-->
                          <source file="/mnt/kvmstorage/onlyNat.qcow2" /> 
                          <target dev="vda" bus="virtio" />
                  </disk>
    
                  <disk type="file" device="cdrom">
                          <!--光盘镜像路径 -->
                          <source file="/mnt/kvmstorage/CentOS-6.7-x86_64-bin-DVD1.iso" />
                          <target dev="hdb" bus="ide" />
                  </disk>
    
                  <!--配置第一个网卡,指定他的网络为:NAT(virbr0是libvirtd进程提供的NAT网桥)-->
                  <interface type="bridge">
                          <mac address='06:64:12:00:00:62'/>
                          <!--当前主机网桥的名称,这个br0需要使用brctl命令创建-->
                          <source bridge="virbr0" />
                          <model type='virtio'/>
                  </interface>
                  <input type="mouse" bus="ps2" />
                  <!--vnc端口号自动分配,可以通过virsh vncdisplay来查询-->
                  <graphics type="vnc" port="5901" autoport="no" listen="0.0.0.0" keymap="en-us" passwd='abcd'/>
          </devices>
      </domain>
    

    virsh define /root/onlyNat.xml

    virsh start onNAT

  • 5、迁移虚拟机到另一台hypervisor上

    virsh migrate centos-nfs --live qemu+ssh://192.168.30.14/system --unsafe

    注意:不需要在另一台hypervisor上启动接受程序,为什么呢?

    因为它是通过ssh先去另一台hypervisor上启动接受程序,然后再传输过去的,virsh的底层还是和第一种最原始的qemu-kvm一样,因为virsh是基于qemu-kvm的。

  • 6、迁移完成后,本虚拟机会shutoff,而另一个hepervisor上会启动一台一模一样的虚拟机。

共有 人打赏支持
粉丝 7
博文 100
码字总数 72832
×
刘付kin
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: