基于NFS共享存储实现KVM虚拟主机动态迁移
文章目录
- 准备工作
- 配置主机名和IP地址
- 在虚拟机中安装KVM
- 设置KVM网络
- NFS服务器上配置共享目录(/kvm/share)
- 两台kvm服务器上创建共享存储池
- 在KVM1服务器上创建虚拟机
- 在源主机上添加远程连接
- 动态迁移虚拟机到KVM2服务器上
准备工作
迁移是指将虚拟机的配置文件、磁盘文件拷贝到目的主机。
实现一个kvm中运行的虚拟机迁移到另一个kvm中,同时两个kvm主机共享nfs服务器中的 /kvm-share目录。
-
准备3台虚拟机kvm1,kvm2,nfs,kvm1和kvm2需要安装KVM
-
3台虚拟机都要关闭防火墙和selinux
systemctl stop firewalld systemctl disable firewalld
-
kvm1做源主机,kvm2做目的主机,nfs做共享存储的服务器
-
kvm1中创建新的虚拟机,将kvm1中新创建的虚拟机迁移到kvm2中
三台主机的主机名和IP地址分为如下所示:
源主机:kvm1 192.168.247.106
目的主机:kvm2 192.168.247.107
nfs服务器:nfs 192.168.247.108
配置主机名和IP地址
-
修改IP地址
三台主机的修改方式相同,以修改 kvm1 为例:
[root@kvm1 ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33 TYPE="Ethernet" PROXY_METHOD="none" BROWSER_ONLY="no" # 修改为静态 BOOTPROTO="static" DEFROUTE="yes" IPV4_FAILURE_FATAL="no" IPV6INIT="yes" IPV6_AUTOCONF="yes" IPV6_DEFROUTE="yes" IPV6_FAILURE_FATAL="no" IPV6_ADDR_GEN_MODE="stable-privacy" NAME="ens33" UUID="6a8bf983-f8d5-47a8-aac2-4be976e192d8" DEVICE="ens33" ONBOOT="yes" # ip地址,需要在同一网段下 IPADDR=192.168.247.106 # 网关 GATEWAY=192.168.247.2 DNS1=192.168.247.2
-
重启网络服务
[root@kvm1 ~]# systemctl restart network
-
编辑 /etc/hosts 文件,以键值对的形式写入IP地址和对应的主机名
[root@kvm1 ~]# vim /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.247.106 kvm1 192.168.247.107 kvm2 192.168.247.108 nfs
-
远程复制到kvm2和nfs服务器中
# 根据提示输入 yes ,然后输入密码即可 [root@kvm1 ~]# scp /etc/hosts 192.168.247.107:/etc/ [root@kvm1 ~]# scp /etc/hosts 192.168.247.108:/etc/
在虚拟机中安装KVM
kvm1和kvm2都需要安装kvm,这里只显示虚拟机kvm1的安装过程。
- 安装kvm
[root@kvm1 ~]# yum install *virt* *qemu* librbdel-devel -y
-
查看kvm模块,出现以下结果说明安装成功
[root@kvm1 ~]# lsmod | grep kvm kvm_intel 188740 0 kvm 637289 1 kvm_intel irqbypass 13503 1 kvm
设置KVM网络
KVM网络模式有NAT和桥接模式两种,默认是NAT,这里我们将KVM虚拟机网络模式配置为桥接模式。由于我们需要在两台kvm服务器上都能运行虚拟机,所以两台kvm服务器上都要配置桥接模式。
以在kvm1上配置为例:
-
保险起见,先复制一份 ifcfg-ens33
[root@kvm1 ~]# cd /etc/sysconfig/network-scripts/ [root@kvm1 network-scripts]# cp ifcfg-ens33 ifcfg-ens33.bak
-
在复制一份ifcfg-ens33,命名为 ifcfg-br0,作为网桥的配置文件
[root@kvm1 network-scripts]# cp ifcfg-ens33 ifcfg-br0 [root@kvm1 network-scripts]# vim ifcfg-br0 # 修改类型、名称、设备名、删除uuid TYPE="Bridge" PROXY_METHOD="none" BROWSER_ONLY="no" BOOTPROTO="static" DEFROUTE="yes" IPV4_FAILURE_FATAL="no" IPV6INIT="yes" IPV6_AUTOCONF="yes" IPV6_DEFROUTE="yes" IPV6_FAILURE_FATAL="no" IPV6_ADDR_GEN_MODE="stable-privacy" NAME="br0" DEVICE="br0" ONBOOT="yes" IPADDR=192.168.247.106 GATEWAY=192.168.247.2 DNS1=192.168.247.2
-
配置ifcfg-ens33文件,将物理网卡ens33桥接到桥接网卡上去
[root@kvm1 network-scripts]# vim ifcfg-ens33 TYPE="Ethernet" PROXY_METHOD="none" BROWSER_ONLY="no" BOOTPROTO="static" DEFROUTE="yes" IPV4_FAILURE_FATAL="no" IPV6INIT="yes" IPV6_AUTOCONF="yes" IPV6_DEFROUTE="yes" IPV6_FAILURE_FATAL="no" IPV6_ADDR_GEN_MODE="stable-privacy" NAME="ens33" UUID="6a8bf983-f8d5-47a8-aac2-4be976e192d8" DEVICE="ens33" ONBOOT="yes" # 桥接网卡名 BRIDGE="br0"
-
重启网络服务和libvirtd服务
[root@kvm1 network-scripts]# systemctl restart network
-
查看是否成功
# 显示如下即可以 [root@kvm1 network-scripts]# ifconfig br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.247.106 netmask 255.255.255.0 broadcast 192.168.247.255 inet6 fe80::42c5:4aa8:a8e3:7daa prefixlen 64 scopeid 0x20<link> inet6 fe80::2d7a:2d5b:a13c:4f39 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:32:dd:37 txqueuelen 1000 (Ethernet) RX packets 65 bytes 6959 (6.7 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 47 bytes 6511 (6.3 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 ether 00:0c:29:32:dd:37 txqueuelen 1000 (Ethernet) RX packets 130367 bytes 190099903 (181.2 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 31518 bytes 2112710 (2.0 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Local Loopback) RX packets 36 bytes 2832 (2.7 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 36 bytes 2832 (2.7 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 virbr0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 192.168.122.1 netmask 255.255.255.0 broadcast 192.168.122.255 ether 52:54:00:00:bc:33 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 # 或者直接查看网桥信息 [root@kvm1 network-scripts]# brctl show br0 bridge name bridge id STP enabled interfaces br0 8000.000c2932dd37 no ens33
NFS服务器上配置共享目录(/kvm/share)
-
创建共享目录
[root@nfs ~]# mkdir /kvm-share
-
配置 exports 文件
默认为空,配置端口,这是因为需要启动RPC服务之后,NFS服务才能向RPC注册端口,然后RPC对NFS中的端口进行统一管理
允许哪些主机可以可以挂载 /kvm-share 目录
[root@nfs ~]# vim /etc/exports /kvm-share *(rw,sync,no_root_squash)
-
安装 rpcbind
[root@nfs ~]# yum install rpcbind -y
-
依次启动rpcbind服务、nfs服务,并且都设置为自启
[root@nfs ~]# systemctl enable nfs Created symlink from /etc/systemd/system/multi-user.target.wants/nfs-server.service to /usr/lib/systemd/system/nfs-server.service. [root@nfs ~]# systemctl enable rpcbind [root@nfs ~]# systemctl start rpcbind [root@nfs ~]# systemctl start nfs
# 出现以下问题的原因是 nfs服务器 没有关闭防火墙
clnt_create: RPC: Port mapper failure - Unable to receive: errno 113 (No route to host)
两台kvm服务器上创建共享存储池
两台kvm服务器上都要创建共享存储池,最好都设置为一样的名字。名字规定如下:
存储池名字:kvm-share
存储卷名字:kvm-test.qcow2
以在kvm1服务器上创建为例:
-
创建 /kvm目录,用来当作存放磁盘镜像的目录,也就是存储池。
[root@kvm1]# mkdir /kvm
-
打开虚拟系统管理器
[root@kvm1]# virt-manager
- 点击 [编辑] -> [连接详情]
-
点击 [存储] ,然后点击 [+] 添加存储池
-
类型选择为 netfs,点击[前进]
- 主机名为 nfs 服务器的IP地址,源路径就是 nfs 服务器中的共享目录,点击 [完成]
- 点击kvm-share存储池 ,点击 [+] ,在kvm-share中添加存储卷
- 根据实际情况填写存储卷的容量,点击 [完成]
至此,kvm1服务器上的共享存储池创建完成。
注意在kvm2服务器上也要创建,但是只需要创建存储池,不需要创建存储卷,因为在kvm2服务器中按上述步骤创建完存储池后,会发现该存储池中有一个存储卷,这个存储卷就是在kvm1服务器上创建好的存储卷。其实在创建存储池的过程中,我们发现需要填写nfs服务器的ip地址和共享目录,这其实就是将共享目录挂载到kvm1服务器上的 /kvm 目录上去了。
这样一来,一旦源主机上的存储池中磁盘镜像发生改变,目的主机上存储池中的磁盘镜像也能够实时的反馈。
在KVM1服务器上创建虚拟机
-
上传一份CentOS镜像文件到kvm1虚拟机的文件系统中
-
打开虚拟系统管理器
[root@vm1]# virt-manager
-
点击 [文件] -> [新建虚拟机]
-
选择 本地安装介质,点击 [前进]
-
选择上传的镜像文件,选择 Linux 操作系统,版本为 CentOS 7,点击[前进]
-
点击 [前进]
-
选择自定义存储,点击[管理] 选择存储卷
-
选择创建好的存储池(kvm-share)中的存储卷
-
点击 [前进]
-
修改虚拟机名字为vm1,勾选安装前自定义配置,网络选择为我们配置的桥接网络,点击[完成]
-
勾选自启,然后点击[开始安装]
-
接下来和安装Linux虚拟机一样
如果出现以下问题,可能是防火墙或者selinux没有关闭
在源主机上添加远程连接
-
kvm1和kvm2服务器上 安装 openssh-askpass
[root@kvm1 ~]# yum install openssh-askpass -y
-
打开虚拟系统管理器
[root@vm1]# virt-manager
-
点击[文件] -> [添加连接]
-
勾选连接到远程主机,填写目的主机的主机名或ip地址,root用户即可,点击[连接]
-
输入root用户登录目的主机的密码,点击 [OK]
动态迁移虚拟机到KVM2服务器上
-
打开虚拟系统管理器,并且开启虚拟机vm1
[root@vm1]# virt-manager [root@vm1]# virsh start vm1
-
登录,然后ping以下百度地址,让虚拟机一直跑起来
-
右击vm1虚拟机,选择[迁移]
-
在新主机选项中选择我们刚刚创建的远程连接,勾选允许不可靠,点击[迁移]
出现如下原因是目的主机中没有创建存储池,让nfs的共享目录挂载到目的主机上去。在目的主机上按上面的方法创建存储池即可。
- 迁移成功之后,kvm1服务器上的虚拟系统管理器如下所示
这是kvm2中的:
- 双击进入kvm2中的vm1虚拟机控制台,可以发现vm1虚拟机并未中断,而是一直在运行。
至此,基于NFS共享存储实现KVM虚拟主机动态迁移就完成了。