当一台 KVM 宿主机的负载比较高时,可将源 KVM 宿主机上的部分虚拟机迁移到负载较低的 KVM 宿主机中,以保证服务质量。
通过KVM 虚拟机迁移将多台负载较低的KVM 宿主机上的KVM 虚拟机集中迁移到某一台 KVM 宿主机上,从而达到节约资源的目的。
在升级 KVM 宿主机硬件设备时,可以将 KVM 宿主机上运行的 KVM 虚拟机迁移到其他KVM 宿主机上,以解决对硬件的依赖,从而实现业务不中断情况下对物理硬件设备的升级。
跨地域迁移,实现 KVM 虚拟机的远程迁移。
迁移分为静态迁移(static magration)和动态迁移(live migration)。
二者的区别是:
静态迁移时会有一段时间虚拟机中的服务是不可用的,而动态迁移则没有明显的服务暂停时间。
静态迁移 静态迁移需要先关闭要迁移的 KVM 虚拟机,并拷贝它的磁盘文件和配置文件到目标KVM 宿主机,然后恢复启动,从而实现静态迁移。
动态迁移 动态迁移是保证 KVM 虚拟机上运行的应用正常提供服务的同时,让 KVM 虚拟机在不同的 KVM 宿主机之间进行迁移。动态迁移的过程仅有非常短暂的停机时间,甚至可以忽略不计,同时 KVM 虚拟机上已经打开的应用连接不会断开,依然保持不变。
KVM 的动态迁移有两种方式:一种是基于共享存储的动态迁移,另一种是基于数据块的动态迁移。
① 基于共享存储的动态迁移 基于共享存储的动态迁移是在 KVM 虚拟机迁移开始后,被迁移的 KVM 虚拟机依然保持在源 KVM 宿主机上运行。与此同时,KVM 虚拟机的内存页被传输到目标 KVM 宿主机之上。QEMU/KVM 会监控并记录迁移过程中所有已被传输的内存页的任何修改,并在所有内存页传输完成后再开始传输在前面传输过程中被更改的内存页内容。 如果 KVM 虚拟机中内存使用量非常大且修改频繁,内存中数据被不断修改的速度大于 KVM 能够传输的内存速度,该情况下无法使用动态迁移, 只能使用静态迁移方法来进行 KVM 虚拟机迁移。
② 基于数据块的动态迁移 使用本地存储的 KVM 虚拟机进行在线迁移,就要用到基于数据块的动态迁移。迁移的源宿主机和目标宿主机只需要保持以太网连接即可。因为少了共享存储,所以降低了动态迁移的难度。
相同内存页合并为单一内存页,并标识为“写时复制”
KSM开启后,CPU使用量会有一定的提高
不同虚拟机的相同类型操作系统或应用,有助于实现KSM
使用KSM要保证有足够的交换分区
资源配置
kvm节点:4G4核,开启虚拟化
nfs节点:2G2核
实验环境
主机名:IP | kvm01:172.16.10.10 kvm02:172.16.10.11 nfs:172.16.10.12 |
---|---|
关闭防火墙和selinux | systemctl stopfirewalld systemctl disable firewalld setenforce 0 |
修改主机名 | hostnamectl set-hostname kvm01 hostnamectl set-hostname kvm02 hostnamectl set-hostname nfs |
yum源 | 网络Base源 |
部署两台kvm:kvm01、kvm02
在kvm01安装虚拟机test01
windows安装vnc,其主要作用是在本地Windows上来连接KVM虚拟机,方便管理
单击菜单栏的“File”,选择“New connection”,新建到虚拟机的连接。“VNC Server”和“Name”填写宿主机的 IP 地址。其中,“5901”是执行 virt-install 安装命令时分配给对应虚拟机的端口,可以自己定义,通常都是以 5901 开始逐个递增。
# 安装需要的软件包 [root@kvm01 ~]# yum -y install qemu-kvm qemu-kvm-tools virt-install qemu-img bridge-utils libvirt virt-manager virt-viewer # 配置桥接网络 [root@kvm01 ~]# cd /etc/sysconfig/network-scripts/ [root@kvm01 network-scripts]# vim ifcfg-ens33 #IPADDR=172.16.10.10 ## 这几行注释掉 #NETMASK=255.255.255.0 #GATEWAY=172.16.10.2 #DNS1=172.16.10.2 BRIDGE=br0 [root@kvm01 network-scripts]# vim ifcfg-br0 TYPE=Bridge ##类型为 桥接 NAME=br0 DEVICE=br0 IPADDR=172.16.10.10 NETMASK=255.255.255.0 GATEWAY=172.16.10.2 DNS1=172.16.10.2 UUID=famjoaflajoagm75979afarw ## 删掉uuid [root@kvm01 network-scripts]# systemctl restart network # 创建存储目录 [root@kvm01~]# mkdir -p /data/store [root@kvm01 ~]# mkdir -p /data/iso # 上传镜像并将镜像移动到/data/iso/目录下 [root@kvm01 ~]# mv mv CentOS-7-x86_64-Minimal-2009.iso /data/iso/
# 创建虚拟机 [root@kvm01 ~]# virt-install --name test01 -r 1024 --vcpus=1 \ --disk path=/data/store/test01.qcow2,size=10 -w bridge:br0 \ --virt-type=kvm --accelerate --autostart \ -c /data/iso/CentOS-7-x86_64-Minimal-2009.iso \ --vnc --vncport=5901 --vnclisten=0.0.0.0 WARNING 无法连接到图形控制台:没有安装 virt-viewer。请安装 'virt-viewer' 软件包。 WARNING 没有控制台用于启动客户机,默认为 --wait -1 开始安装...... 正在分配 'test01.qcow2' | 10 GB 00:00:00 ERROR unsupported format character '奠(0xffffffe7) at index 47 域安装失败,您可以运行下列命令重启您的域: 'virsh start virsh --connect qemu:///system start test01' 否则请重新开始安装。 # 选项含义: -n 或 --name:指定虚拟机的名字。 -r:指定内存大小。 --vcpu:指定虚拟 CPU 个数。 --disk path:指定磁盘文件放置位置及大小。 -w:制定所使用的网桥。 --autostart:设置虚拟机在宿主机开机时启动。 -c:指定镜像文件。 --vncport:通过 vnc viewer 连接的端口。 --vnclisten:通过 vnc viewer 连接的 IP # 若是创建虚拟机时出现以下错误,可以升级以下系统 # 报错: virt-viewer: symbol lookup error: /lib64/libspice-client-glib-2.0.so.8: undefined symbol: gst_buffer_get_video_meta ## 解决方法:升级系统 [root@kvm01 ~]# yum -y update [root@kvm01 ~]# reboot ## 重启 ## 重启后继续执行创建虚拟机命令 # vnc连接虚拟机进行安装 # 安装好开启虚拟机test01 [root@kvm01 ~]# virsh start test01
# kvm01 节点 ## 关闭虚拟机 test0 [root@kvm01 ~]# virsh shutdown test01 ## 复制 test01 配置文件和磁盘文件 [root@kvm01 ~]# cp /etc/libvirt/qemu/test01.xml /root/ [root@kvm01 ~]# cp /data/store/test01.qcow2 /root/ ## 将test01复制的配置文件和磁盘文件 scp 传输到 kvm02 上 [root@kvm01 ~]# scp /root/test01.xml root@172.16.10.11:/root/ [root@kvm01 ~]# scp /root/test01.qcow2 root@172.16.10.11:/root/ # kvm02 节点 ## 将 test01 的配置文件和磁盘文件移动到相应的目录下 [root@kvm02 ~]# mv /root/test01.xml /etc/libvirt/qemu/ [root@kvm02 ~]# mkdir -p /data/store/ [root@kvm02 ~]# mv /root/test01.qcow2 /data/store/ ## 定义虚拟机test01 [root@kvm02 ~]# virsh define /etc/libvirt/qemu/test01.xml Domain test01 defined from /etc/libvirt/qemu/test01.xml ## 开启test01 ,此时静态迁移已完成 [root@kvm02 ~]# virsh start test01 [root@kvm02 ~]# virsh list Id Name State ---------------------------------------------------- 2 test01 running
# 安装相应软件 [root@nfs ~]# yum -y install rpcbind nfs-utils # 创建共享目录 [root@nfs ~]# mkdir /data [root@nfs ~]# vim /etc/exports /data 172.16.10.0/24(rw,sync,no_root_squash) # 启动nfs [root@nfs ~]# systemctl start rpcbind [root@nfs ~]# systemctl start nfs # 查看共享文件 [root@nfs ~]# showmount -e Export list for nfs: /data 172.16.10.0/24
kvm01、kvm02节点都要挂载共享文件,以下以kvm01 为例
# 创建挂载点 [root@kvm01 ~]# mkdir /data_nfs/ [root@kvm01 ~]# vim /etc/fstab 172.16.10.12:/data/ /data_nfs/ nfs defaults 0 0 [root@kvm01 ~]# mount -a
# 开启虚拟机test01 [root@kvm01 ~]# virsh start test01 # 复制test01的磁盘文件到共享目录下 [root@kvm01 ~]# virsh domblklist test01 ## 查看磁盘文件位置 Target Source ------------------------------------------------ vda /data/store/test01.qcow2 hda - [root@kvm01 ~]# mkdir /data_nfs/store ## 创建存储磁盘文件目录 [root@kvm01 ~]# cp /data/store/test01.qcow2 /data_nfs/store # 修改test01 的配置文件 [root@kvm01 ~]# vim /etc/libvirt/qemu/test01.xml <source file='/nfs_data/store/test01.qcow2'/> ## 将磁盘文件路径改为共享磁盘路径“/nfs_data/store/test01.qcow2'/” # 改完后需要重启宿主机并查看启动后test01 状态,test01 需要为开启状态 [root@kvm01 ~]# reboot [root@kvm01 ~]# virsh list Id 名称 状态 ---------------------------------------------------- 1 test01 running # 进行动态迁移 [root@kvm01 ~]# virsh migrate --live --verbose test01 qemu+ssh://172.16.10.11/system tcp://172.16.10.11 --unsafe root@172.16.10.11's password: 迁移: [100 %]
# kvm02 查看test01状态 [root@kvm01 ~]# virsh list Id 名称 状态 ---------------------------------------------------- 1 test01 running # 创建test01配置文件 [root@kvm01 ~]# virsh dumpxml test01 > /etc/libvirt/qemu/test01.xml
源kvm01虚拟机test01是运行状态,目标kvm02无虚拟机test01
# 查看kvm01 [root@kvm01 ~]# virsh list --all Id Name State ------------------------------------------------ 2 test01 running # 查看kvm02 [root@kvm02 ~]# virsh list --all Id Name State ------------------------------------------------
通过vnc在虚拟机中执行命令,给console分配一个控制台
[root@localhost ~]# grubby --update-kernel=ALL --args="console=ttyS0" [root@localhost ~]# reboot ## 重启。配置完一定要重启
使用kvm01连接虚拟机test01,并配置网络生成IP
[root@kvm01 ~]# virsh console test01 连接到域 test01 换码符为 ^] ## 敲回车 CentOS Linux 7 (Core) Kernel 3.10.0-1160.el7.x86_64 on an x86_64 localhost login: root ## 登录用户 密码: ## 输入用户密码 Last login: Fri Aug 27 09:18:59 on tty1 [root@localhost ~]# ## 登录test01 成功 # 虚拟机分配ip [root@localhost ~]# cd /etc/sysconfig/network-scripts/ [root@localhost network-scripts]# ls ifcfg-ens3 ifdown-ppp ifup-eth ifup-sit ifcfg-lo ifdown-routes ifup-ippp ifup-Team ifdown ifdown-sit ifup-ipv6 ifup-TeamPort [root@localhost network-scripts]# vi ifcfg-ens3 TYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no BOOTPROTO=dhcp 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=ens3 DEVICE=ens3 ONBOOT=yes ## 将 no 改为 yes ,开启网络 ## 因为使用的是DHCP服务,所以重启网络后悔自动分配ip的 # 重启网络 [root@localhost network-scripts]# systemctl restart network [root@localhost network-scripts]# ip a ## ens3 已分到ip地址 172.16.10.12/24 2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 52:54:00:76:1b:30 brd ff:ff:ff:ff:ff:ff inet 172.16.10.12/24 brd 172.16.10.255 scope global noprefixroute dynamic ens3 valid_lft 1795sec preferred_lft 1795sec inet6 fe80::98a2:1d7:d863:7524/64 scope link noprefixroute valid_lft forever preferred_lft forever
CentOS 7 默认安装的 qemu-kvm 包是不支持数据块动态迁移的, 需要单独安装qemu-kvm-ev
源kvm01和目标kvm02节点安装依赖包
# 安装 yum源 [root@kvm01 ~]# yum -y install centos-release-qemu-ev # 安装 qemu-kvm-ev [root@kvm01 ~]# yum -y install qemu-kvm-ev
源kvm01和目标kvm02都要添加
## kvm01 节点 [root@kvm01 ~]# vim /etc/hosts 172.16.10.10 kvm01 172.16.10.11 kvm02 ## kvm02 节点 [root@kvm02 ~]# vim /etc/hosts 172.16.10.10 kvm01 172.16.10.11 kvm02
确保 kvm01 和 kvm02 两台宿主机拥有相同的资源池,若没有,则需创建。
## kvm01 节点 [root@kvm01 ~]# virsh pool-list --all Name State Autostart ------------------------------------------- iso active yes store active yes ## kvm02 节点 [root@kvm02 ~]# virsh pool-list --all Name State Autostart -------------------------------------------
kvm02 创建虚拟池
# 定义虚拟池 [root@kvm02 ~]# virsh pool-define-as store --type dir --target /data/store Pool store defined # 创建虚拟池 [root@kvm02 ~]# virsh pool-build store Pool store built # 配置虚拟池开机自动 [root@kvm02 ~]# virsh pool-autostart store Pool store marked as autostarted # 启动虚拟池 [root@kvm02 ~]# virsh pool-start store Pool store started ## iso池同上操作 [root@kvm02 ~]# virsh pool-list --all Name State Autostart ------------------------------------------- iso active yes store active yes
3.3.5 目标kvm02 创建同名磁盘文件
在目标主机kvm02创建一个要迁移的虚拟机的同名的磁盘文件
必须保证目标主机kvm02创建的磁盘文件和kvm01的磁盘文件同名同位置
[root@kvm02 ~]# qemu-img create -f qcow2 /data/store/test01.qcow2 10G Formatting '/data/store/test01.qcow2', fmt=qcow2 size=10737418240 cluster_size=65536 lazy_refcounts=off refcount_bits=16
[root@kvm01 ~]# virsh migrate --live test01 qemu+ssh://172.16.10.11/system --unsafe root@172.16.10.11's password: --live 在线迁移 # 此时查看test01 状态已是关闭 [root@kvm01 ~]# virsh list --all Id 名称 状态 ---------------------------------------------------- - test01 关闭
[root@kvm02 ~]# virsh list --all Id Name State ---------------------------------------------------- 2 test01 running # 通过kvm02 登录test01 并查看test01的ip地址 [root@kvm02 ~]# virsh console test01 [root@localhost ~]# ip a 2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 52:54:00:76:1b:30 brd ff:ff:ff:ff:ff:ff inet 172.16.10.12/24 brd 172.16.10.255 scope global noprefixroute dynamic ens3 valid_lft 1759sec preferred_lft 1759sec inet6 fe80::98a2:1d7:d863:7524/64 scope link noprefixroute valid_lft forever preferred_lft forever
[root@kvm02 ~]# virsh dumpxml test01 > /etc/libvirt/qemu/test01.xml [root@kvm02 ~]# ll /etc/libvirt/qemu/ total 8 drwx------. 3 root root 42 Apr 28 21:36 networks -rw-r--r-- 1 root root 4477 Aug 27 12:35 test01.xml
KSM 是在 Linux 2.6 内核版本中被添加进去的,目前大多数常用的、主流的 Linux 发行版都默认支持 KSM 技术,执行以下命令即可检查当前 Linux 系统是否支持 KSM。
[root@kvm02 ~]# egrep -i /boot/config-3.10.0-514.el7.x86_64 CONDIF_KSM=y ## =y 表示支持ksm
安装并启动ksm服务
[root@kvm02 ~]# yum -y install qemu-kvm-common [root@kvm02 ~]# systemctl start ksm [root@kvm02 ~]# systemctl enable ksm # 设置/sys/kernel/mm/ksm/run文件的值为1,表示ksm功能生效 [root@kvm02 ~]# echo 1 > /sys/kernel/mm/ksm/run ## 若 0则KSM 功能不会生效,需要将其置为 1