目录
[2.1 案例分析](#2.1 案例分析)
[2.1.1 案例概述](#2.1.1 案例概述)
[2.1.2 案例前置知识点](#2.1.2 案例前置知识点)
[1.KVM 虚拟机迁移](#1.KVM 虚拟机迁移)
[2.KSM 内核同页合并](#2.KSM 内核同页合并)
[(2)配置虚拟机 test01 可通过 console 登录](#(2)配置虚拟机 test01 可通过 console 登录)
[(1)配置 NFS 共享存储](#(1)配置 NFS 共享存储)
[(2)挂载 NFS 目录](#(2)挂载 NFS 目录)
[(1)KSM 服务介绍](#(1)KSM 服务介绍)
[(2)配置 KSM 优化内存](#(2)配置 KSM 优化内存)
2.1 案例分析
2.1.1 案例概述
企业内部为了使服务器资源达到最大化利用,通常都会进行KVM 虚拟化,每台服务器上运行多台 KVM 虚拟机。随着 KVM 虚拟机数量的不断增多,个别服务器会出现资源过载现象,这时候就需要对部分KVM 虚拟机进行迁移,迁移到负载相对较低的服务器上。
为了解决以上问题,针对可停机的 KVM 虚拟机,可使用静态迁移的方式来迁移KVM虚拟机。针对在线提供服务、不可停机的KVM虚拟机,可使用基于共享存储的动态迁移或基于数据块的动态迁移来完成迁移工作。最终按业务类型将虚拟机重新调配、合理布局,以保证服务器一直处于良好的运行状态。除了迁移之外,还可以在KVM 宿主机上开启 KSM内核同页合并,以达到节省内存、降低负载的目的。
2.1.2 案例前置知识点
1.KVM 虚拟机迁移
迁移类型 | 静态迁移 | 动态迁移(实时迁移) |
---|---|---|
定义 | 需关闭虚拟机后迁移 | 虚拟机运行状态下迁移,服务几乎不中断 |
停机时间 | 较长(需关闭虚拟机) | 极短(毫秒级)或可忽略 |
适用场景 | 非关键业务、允许中断的服务 | 关键业务、要求高可用性的服务 |
存储要求 | 本地存储或共享存储均可 | 共享存储(推荐)或本地存储(基于数据块迁移) |
实现方式 | 1. 关闭虚拟机 2. 拷贝磁盘和配置文件 3. 目标主机恢复启动 | 1. 内存状态实时同步 2. 监控并传输变更页 3. 最后切换至目标主机 |
子类型 | 无 | 1. 基于共享存储的动态迁移 2. 基于数据块的动态迁移(支持本地存储) |
优点 | - 实现简单 - 对网络带宽要求低 | - 服务连续性高 - 自动化程度高 |
缺点 | - 服务中断明显 - 不适用于高可用场景 | - 对网络带宽和稳定性要求高 - 内存频繁修改时可能失败 |
关键技术 | 文件拷贝、配置文件同步 | 内存脏页跟踪、增量同步、快速切换 |
适用条件 | 无特殊要求 | - 源和目标主机CPU兼容 - 网络延迟低(建议≤5ms) - 共享存储(非必须,但推荐) |
关键说明:
-
动态迁移的两种子类型:
-
基于共享存储:磁盘文件无需迁移,仅同步内存状态,要求源和目标主机挂载同一存储(如NFS、iSCSI)。
-
基于数据块:支持本地存储,需同步磁盘和内存数据,迁移时间较长但对环境要求更低。
-
-
动态迁移失败场景:
-
内存修改速度超过传输速度时,可能触发迁移超时或回滚。
-
网络抖动或带宽不足会导致迁移中断。
-
-
性能建议:
-
动态迁移前建议预拷贝(pre-copy)内存数据以减少最终停机时间。
-
对于大内存虚拟机,可调整迁移参数(如
max-bandwidth
)优化传输效率。
-
2.KSM 内核同页合并
特性 | 说明 |
---|---|
全称 | Kernel SamePage Merging(内核同页合并) |
功能 | 合并多个进程(如KVM虚拟机)的相同内存页,标记为"写时复制"(Copy-on-Write)以节省内存。 |
工作原理 | 1. 扫描运行中的进程内存 2. 发现完全相同的内存页后合并 3. 修改时触发复制(COW机制) |
适用场景 | - 多个KVM虚拟机运行相同OS或应用 - 非虚拟化系统中重复内存页较多的环境 |
内存节省效果 | - 相同OS/应用:可节省50%以上内存 - 不同OS/应用:节省效果有限(可能<5%) |
性能影响 | - 优点 :显著提高内存利用率 - 缺点:增加CPU开销(需扫描和合并内存页) |
安全性 | 仅合并不影响虚拟机/宿主机安全的内存页 |
配置建议 | 1. 开启KSM功能(默认未启用) 2. 确保足够的交换分区(Swap Space) 3. 监控CPU负载 |
虚拟化中的应用 | 每个KVM虚拟机是QEMU进程,KSM可合并多虚拟机间的相同内存页 |
注意事项 | - 内存页频繁修改时,COW机制可能导致额外内存占用 - 需权衡内存节省与CPU开销的平衡 |
关键点说明:
-
写时复制(COW):合并的内存页被标记为只读,任何修改会触发复制新页,确保数据隔离性。
-
虚拟化优化:KSM特别适合运行相同模板创建的虚拟机(如云环境中的批量实例)。
-
监控建议 :通过
ksmctl
工具调整扫描频率(如/sys/kernel/mm/ksm/
下的参数),平衡内存节省与CPU消耗。
3:案例环境

主机 | 操作系统 | IP 地址 | 主要软件 |
---|---|---|---|
kvm01 | CentOS 7.3 x86_64 | 192.168.10.101 | Qemu-kvm、libvirt |
kvm02 | CentOS 7.3 x86_64 | 192.168.10.102 | Qemu-kvm、libvirt、qemu-kvm-ev |
kvmnfs | CentOS 7.3 x86_64 | 192.168.10.103 | nfs-utils |
案例需求
通过静态迁移实现 KVM 虚拟机的迁移。
通过基于共享存储的动态迁移方式实现 KVM 虚拟机的迁移。
通过基于数据块的动态迁移方式实现 KVM 虚拟机的迁移。
实现 KSM 内存优化。
案例实现思路
通过拷贝磁盘文件和配置文件的方式实现静态迁移。
通过配置 NFS 共享服务,实现基于共享存储的动态迁移。
通过基于数据块的方式实现动态迁移
针对同类型 KVM 虚拟机和应用使用 KSM 来优化内存。
二:案例实施
1:静态迁移
使用源宿主机 kvm01 和目标宿主机 kvm02 来完成静态迁移。首先在源宿主机 kvm01上创建虚拟机 test01,虚拟机 test01 的数据放在本地磁盘。然后将虚拟机 test01 从源宿主机kvm01 迁移到目标宿主机 kvm02上,并进行一些相应的配置
(1)在源宿主机上准备虚拟机
创建虚拟机 test01


以上 VNC 的相关配置完成后,就可以通过文本方式创建 test01 虚拟机了。具体操作命
令如下所示。

virt-install 安装命令各选项的具体作用如下所示:
选项 | 具体作用描述 |
---|---|
-n |
指定虚拟机的名字。 |
-r |
指定内存大小。 |
--vcpu |
指定虚拟 CPU 个数。 |
--disk |
指定磁盘文件放置位置及大小。 |
-w |
指定所使用的网桥。 |
--autostart |
设置虚拟机在宿主机开机时自动启动。 |
-c |
指定镜像文件。 |
--vncport |
指定通过 VNC Viewer 连接的端口。 |
--vnclisten |
指定通过 VNC Viewer 连接的 IP 地址。 |
[root@kvmo1 ~]# virt-install \
-n test01 \ # 虚拟机名称
-r 1024 \ # 内存大小(MB)
--vcpus=1 \ # CPU核心数
--disk path=/data/store/test01.qcow2,size=10 \ # 磁盘路径和大小(GB)
-w bridge:br0 \ # 使用桥接网络br0
--virt-type=kvm \ # 虚拟化类型
--accelerate \ # 启用加速
--autostart \ # 设置自动启动
-c /data/iso/CentOS-7-x86_64-Minimal-1611.iso \ # 安装镜像路径
--vnc \ # 启用VNC
--vncport=5901 \ # VNC端口
--vnclisten=0.0.0.0 # VNC监听地址
上述命令执行后忽略如下所示报错信息,立刻双击打开图 2.4 中 VNC Viewer 创建的连接"192.168.10.101:5901"。
WARNING 无法连接到图形控制台:没有安装 virt-viewer。请安装 'virt-viewer' 软件包。
WARNING 没有控制台用于启动客户机,默认为 --wait -1
开始安装......
正在分配 'test01.qcow2'
ERROR unsupported format character '莫(0xffffffe7) at index 47
域安装失败,您可以运行下列命令重启您的域:
'virsh start virsh --connect qemu://system start test01'
否则请重新开始安装
之所以会出现上述"WARNING"和"ERROR"信息,是因为宿主机的 CentOS 系统采用了文本方式安装,没有图形化界面。这种情况不影响虚拟机的正常使用,可使用 VNC Vewer软件来开始 CentOS 系统的安装,如图所示

通过 VNC Viewer 安装 test01 虚拟机的具体过程这里省略,实际就是 CentOS 7.3 系统的安装过程,等虚拟机的操作系统安装完成后,test01虚拟机就安装完成了。
(2)配置虚拟机 test01 可通过 console 登录
如果在宿主机 kvm01 上想要实现通过 virsh console 命令连接到虚拟机 test01,需要在test01 虚拟机上进行如下配置。
[root@test01 ~]# grubby --update-kernel=ALL --args="console=ttyS0" # 添加ttyS0终端
[root@test01 ~]# reboot
(3)标记虚拟机 test01 当前 IP 地址
[root@kvm01 ~]# virsh console test01
Connected to domain test01
Escape character is ^] # 按Enter键继续
[root@test01 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.10.101 netmask 255.255.255.0 broadcast 192.168.9.255
inet6 fe80::a139:6e1e:a9b:782d prefixlen 64 scopeid 0x20<link>
ether 52:54:00:94:05:38 txqueuelen 1000 (Ethernet)
RX packets 2390 bytes 832219 (812.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 107 bytes 9941 (9.7 KiB)
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 1 (Local Loopback)
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
从上述命令执行结果中可以得知,迁移前虚拟机 test01 的IP 地址是 192.168.9.97。若想从虚拟机 test01 中退出,可以使用"Ctrl+]"组合键来实现。
2.提取磁盘和配置文件
在宿主机 kvm01 上,将虚拟机 test01 的磁盘文件和 xml配置文件上传到目标宿主机kvm02 上。
查看虚拟机 test01 当前状态
[root@kvm01 ~]# virsh list --all
Id Name State
---
2 test01 running
关闭虚拟机 test01
[root@kvm01 ~]# virsh shutdown test01
Domain test01 is being shutdown
# 查看虚拟机状态
[root@kvm01 ~]# virsh list --all
Id Name State
---
- test01 shut off
导出虚拟机 test01 的 xml 配置文件
[root@kvm01 ~]# virsh dumpxml test01 > test01.xml
# 查看生成的文件
[root@kvm01 ~]# ll
total 16
-rw---. 1 root root 1303 Nov 21 21:24 anaconda-ks.cfg
-rw-r--r--. 1 root root 1351 Feb 24 23:49 initial-setup-ks.cfg
-rw-r--r-- 1 root root 5927 Feb 25 21:38 test01.xml
定位虚拟机 test01 的磁盘文件
[root@kvm01 ~]# virsh domblklist test01
Target Source
---
vda /data/store/test01.qcow2
hda -
拷贝配置文件和磁盘文件到目标宿主机 kvm02上
[root@kvm01 ~]# scp test01.xml 192.168.10.102:/etc/libvirt/qemu/
The authenticity of host '192.168.10.102 (192.168.9.62)' can't be established.
ECDSA key fingerprint is 55:7d:29:61:80:71:f1:f1:da:4f:93:57:6d:28:ce:8f.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.9.62' (ECDSA) to the list of known hosts.
root@192.168.9.62's password:
test01.xml 100% 4461 4.4KB/s 00:00
# 2. 复制虚拟磁盘文件
[root@kvm01 ~]# scp /data/store/test01.qcow2 192.168.10.102:/data/store/
root@192.168.10.102's password:
test01.qcow2 100% 5121MB 76.4MB/s 01:07
(3)配置和启动目标虚拟机
在目标宿主机 kvm02 上,对拷贝过来的虚拟机test01 的数据进行重新定义,启动之后验证虚拟机 test01 的 IP 地址信息是否正确。
查看被迁移过来的配置文件和磁盘文件
# 查看配置文件
[root@kvm02 ~]# ls -l /etc/libvirt/qemu
total 8
drwx---. 3 root root 42 Feb 24 23:48 networks
-rw-r--r-- 1 root root 4461 Feb 25 22:06 test01.xml
# 查看磁盘文件
[root@kvm02 ~]# ls -l /data/store/
total 5243904
-rw--- 1 root root 5369757696 Feb 25 22:08 test01.qcow2
重新定义虚拟机 test01
# 始虚拟机列表为空
[root@kvm02 ~]# virsh list --all
Id Name State
---
# 通过XML文件定义虚拟机
[root@kvm02 ~]# virsh define /etc/libvirt/qemu/test01.xml
Domain test01 defined from /etc/libvirt/qemu/test01.xml
# 验证虚拟机已添加
[root@kvm02 ~]# virsh list --all
Id Name State
---
- test01 shut off
启动虚拟机 test01
[root@kvm02 ~]# virsh start test01
Domain test01 started
[root@kvm02 ~]# virsh list --all
Id Name State
---
1 test01 running
连接虚拟机 test01 并验证 IP 地址信息
[root@kvm02 ~]# virsh console test01
Connected to domain test01
Escape character is ^] # 按Enter键继续
[root@test01 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.10.97 netmask 255.255.255.0 broadcast 192.168.10.255
inet6 fe80::a139:6e1e:a9b:782d prefixlen 64 scopeid 0x20<link>
ether 52:54:00:94:05:38 txqueuelen 1000 (Ethernet)
RX packets 973 bytes 319923 (312.4 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 69 bytes 8117 (7.9 KiB)
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 1 (Local Loopback)
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
至此虚拟机 test01 已实现从源宿主机 kvm01 到目标宿主机 kvm02 的静态迁移。
2:基于共享存储的动态迁移
在 kvmnfs 服务器上部署 NFS服务并创建共享目录实现共享存储。在源宿主机 kvm01和目标宿主机 kvm02上分别挂载共享目录。被迁移虚拟机的磁盘文件存储在共享目录内最终实现虚拟机从源宿主机 kvm01 迁移到目标宿主机 kvm02 上。
(1)配置 NFS 共享存储
在 kvmnfs 服务器上面配置 NFS 服务实现共享存储。
在 kvmnfs 服务器上面安装 NFS 服务
[root@kvmnfs ~]# yum -y install nfs-utils
配置共享目录
在 NFS服务的配置文件/etc/exports 中,配置共享目录及相应权限。设置 192.168.9.0/24网段对/data 共享目录可读写、同步共享目录等权限。
# 创建共享目录
[root@kvmnfs ~]# mkdir /data
# 编辑exports配置文件
[root@kvmnfs ~]# vim /etc/exports
# 添加以下内容:
/data 192.168.9.0/24(rw,sync,no_root_squash)
启动并查看 NFS 服务
[root@kvmnfs ~]# systemctl enable nfs
[root@kvmnfs ~]# systemctl enable rpcbind
[root@kvmnfs ~]# systemctl start nfs
[root@kvmnfs ~]# systemctl start rpcbind
[root@kvmnfs ~]# showmount -e localhost
Export list for localhost:
/data 192.168.10.0/24
(2)挂载 NFS 目录
在 kvm01 和 kvm02两台宿主机上,先创建本地数据目录,之后再分别挂载 NFS目录,并设置开机自动挂载。下面以宿主机 kvm01为例进行操作演示。
源宿主机 kvm01 上查看 NFS 共享目录
[root@kvm01 ~]# showmount -e 192.168.10.103
Export list for 192.168.10.103:
/data 192.168.10.0/24
源宿主机 kvm01 上创建 kgc 目录
bash
[root@kvm01 ~]# mkdir /data/kgc
源宿主机 kvm01 上挂载共享目录
bash
[root@kvm01 ~]# mount -t nfs 192.168.10.103:/data /data/kgc
[root@kvm01 ~]# mount
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
...省略部分内容...
192.168.10.103:/data on /data/kgc type nfs4
(rw,relatime,vers=4.1,rsize=131072,wsize=131072,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=192.168.10.101,local_lock=none,addr=192.168.10.103)
源宿主机 kvm01 上设置自动挂载
bash
[root@kvm01 ~]# vim /etc/fstab
...省略部分内容...
192.168.10.103:/data /data/kgc nfs defaults 0 0
(3)创建动态迁移的虚拟机
在源宿主机 kvm01 上,新建虚拟机 test02,用于测试基于共享存储的动态迁移。
创建虚拟机 test02
创建虚拟机 test02,创建完后査看虚拟机 test02 当前状态。虚拟机 test02 的虚拟磁盘存放到了之前创建的共享目录/data/kgc 下。
bash
[root@kvm01 ~]# virsh list --all
Id Name State
---
3 test02 running
- test01 shut off
[root@kvm01 ~]# virsh domblklist test02
Target Source
---
vda /data/kgc/test02.qcow2
hda -
登录虚拟机 test02 并査看 IP 地址
bash
[root@kvm01 iso]# virsh console test02
Connected to domain test02
Escape character is ^] //输入 Enter 键
CentOS Linux 7 (Core)
Kernel 3.10.0-514.ei7.x86_64 on an x86_64
test02 login: root
Password:
Last failed login: Wed Feb 26 15:24:39 CST 2020 on ttyS0
There was 1 failed login attempt since the last successful login.
Last login: Wed Feb 26 15:24:05 from desktop-m9f1a4m.lan
[root@test02 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.10.42 netmask 255.255.255.0 broadcast 192.168.10.255
inet6 fe80::5938:a3ad:5687:21eb prefixlen 64 scopeid 0x20<link>
ether 52:54:00:93:0c:7d txqueuelen 1000 (Ethernet)
RX packets 120 bytes 35311 (34.4 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 53 bytes 7321 (7.1 KiB)
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 1 (Local Loopback)
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
从上述命令执行结果可以得知,虚拟机 test02 的 IP 地址是 192.168.10.42
(4)动态迁移
查看 kvm01和 kvm02 两台宿主机上虚拟机的运行状态
bash
[root@kvm01 ~]# virsh list --all
Id Name State
---
3 test02 running //kvm01 上 test02 运行
- test01 shut off
[root@kvm02 kgc]# virsh list --all
Id Name State
---
- test01 shut off //kvm02 上无 test02
在源宿主机 kvm01上执行迁移命令
在开始执行迁移操作之前,首先在本地 Windows 机器上面 ping 虛拟机 test02 的 IP 地址,用于迁移过程中观察是否存在网络中断情况。具体的 ping 命令如下所示。
bash
C:\Users\Administrator>ping 192.168.10.42 -t
下面开始执行迁移操作。
bash
[root@kvm01 ~]# virsh migrate --live --verbose test02 qemu+ssh://192.168.10.102/system
tcp://192.168.10.102
root@192.168.10.102's password: //此处输入 192.168.10.102 的密码
error: Unsafe migration: Migration may lead to data corruption if disks use cache != none or cache != directsync
如果迁移命令在执行时出现上述错误,根据提示修改虚拟机 test02的配置文件,加入标注为红色的字体部分,具体方法如下。
bash
[root@kvm01 ~]# virsh shutdown test02
Domain test02 is being shutdown
[root@kvm01 ~]# virsh edit test02
<domain type='kvm'>
<name>test02</name>
<uuid>694ae9ad-5f5b-4812-b5e2-7bdd44733cda</uuid>
<memory unit='KiB'>1048576</memory>
<currentMemory unit='KiB'>1048576</currentMemory>
...省略部分内容...
<devices>
<emulator>/usr/libexec/gemu-kvm</emulator>
<disk type='file' device='disk'>
<driver name='gemu' type='qcow2' cache='none'>
<source file="/data/kgc/test02.qcow2"/>
<target dev='vda' bus='virtio'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'>
</disk>
...省略部分内容...
[root@kvm01 ~]# virsh start test02
Domain test02 started
[root@kvm01 ~]# virsh list --all
| Id | Name | State |
|---|---|---|
| 4 | test02 | running |
| - | test01 | shut off |
[root@kvm01 ~]# virsh migrate --live --verbose test02 qemu+ssh://192.168.10.102/system
tcp://192.168.10.102
root@192.168.10.102's password:
Migration: [100 %]
查看迁移后虚拟机的状态
bash
[root@kvm01 ~]# virsh list --all
| Id | Name | State |
|---|---|---|
| - | test01 | shut off |
| - | test02 | shut off |
[root@kvm02 kgc]# virsh list --all
| Id | Name | State |
|---|---|---|
| 1 | test02 | running |
| - | test01 | shut off |
迁移之后源宿主机 kvm01 上虛拟机 test02 被关闭,目标宿主机 kvm02 上虚拟机 test02处于启动状态。
(5)生成配置文件
完成上述操作之后,基于共享存储的动态迁移已经实现了虚拟机test02 从源宿主机kvm01 转移到目标宿主机 kvm02上,但是其配置文件并没有一起迁移过来,此时还需要根据当前运行的虚拟机 test02 生成对应的配置文件,并重新定义。
创建虚拟机 test02 配置文件
bash
[root@kvm02 ~]# ls -l /etc/libvirt/qemu
total 8
drwx---. 3 root root 42 Feb 24 23:48 networks
-rw-----. 1 root root 4684 Feb 25 23:18 test01.xml
[root@kvm02 ~]# virsh dumpxml test02 > /etc/libvirt/qemu/test02.xml
[root@kvm02 ~]# cd /etc/libvirt/qemu/
[root@kvm02 qemu]# ll
total 16
drwx---. 3 root root 42 Feb 24 23:48 networks
-rw-----. 1 root root 4684 Feb 25 23:18 test01.xml
-rw-r--r--. 1 root root 5938 Feb 26 16:36 test02.xml
定义虚拟机 test02 配置文件
bash
[root@kvm02 qemu]# virsh define /etc/libvirt/qemu/test02.xml
Domain test02 defined from /etc/libvirt/qemu/test02.xml
(6)验证迁移结果
查看虚拟机 test02 的 IP 地址,验证迁移是否成功。
bash
[root@kvm02 qemu]# virsh console test02
Connected to domain test02
Escape character is ^] //输入回车
CentOS Linux 7 (Core)
Kernel 3.10.0-514.ei7.x86_64 on an x86_64
test02 login: root
Password:
Last login: Wed Feb 26 15:24:45 on ttyS0
[root@test02 ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.10.42 netmask 255.255.255.0 broadcast 192.168.10.255
inet6 fe80::5938:a3ad:5687:21eb prefixlen 64 scopeid 0x20<link>
ether 52:54:00:93:0c:7d txqueuelen 1000 (Ethernet)
RX packets 10717 bytes 3781188 (3.6 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 140 bytes 11892 (11.6 KiB)
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 1 (Local Loopback)
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
3:基于数据块的动态迁移
要实现基于数据块的动态迁移,首先要安装qemu-kvm-ev。并且在目标宿主机上提前生成同名的空白磁盘文件,最后再通过数据块进行动态迁移。
(1)依赖包安装
CentOS7默认安装的 qemu-kvm 包是不支持数据块动态迁移的,需要单独安装qemu-kvm-ev。在 kvm01 和 kvm02 两台宿主机中都需要安装 qemu-kvm-ev。下面以源宿主机 kvm01 为例进行 qemu-kvm-ev 的安装操作演示。
bash
[root@kvm01 ~]# yum -y install centos-release-qemu-ev
[root@kvm01 ~]# yum -y install qemu-kvm-ev
(2)迁移前准备工作
源宿主机 kvm01上的准备
bash
[root@kvm01 ~]# cat /etc/hosts
192.168.10.101 kvm01 #填写主机名和 IP 地址的对应关系
192.168.10.102 kvm02
[root@kvm01 ~]# virsh list --all
Id Name State
---
- test01 shut off
- test02 shut off
[root@kvm01 ~]# virsh start test01
Domain test01 started
[root@kvm01 ~]# virsh list --all
Id Name State
---
5 test01 running
- test02 shut off
目标宿主机 kvm02 上的准备
bash
[root@kvm02 ~]# cat /etc/hosts
192.168.10.101 kvm01
192.168.10.102 kvm02
[root@kvm02 ~]# virsh list --all
Id Name State
---
1 test02 running
- test01 shut off
[root@kvm02 ~]# virsh undefine test01
Domain test01 has been undefined
[root@kvm02 ~]# cd /data/store/
[root@kvm02 store]# ls
test01.qcow2
[root@kvm02 store]# rm -rf test01.qcow2
[root@kvm02 store]# virsh list --all
Id Name State
---
2 test02 running
(3)检查资源池
确保 kvm01 和 kvm02 两台宿主机拥有相同的资源池,若没有,则需创建
bash
[root@kvm02 store]# virsh pool-list --all
Name State Autostart
------------------------------------
bdqn active yes
bdqn_iso active yes
default active yes
(4)创建同名磁盘文件
bash
[root@kvm02 store]# 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
(5)执行迁移操作
bash
[root@kvm01 ~]# virsh migrate test01 qemu+ssh://192.168.10.102/system --live --persistent --undefinesource --copy-storage-all --verbose
root@192.168.10.102's password:
Migration: [100 %]
(6)验证迁移结果
bash
[root@kvm01 ~]# virsh list --all
Id Name State
---
- test02 shut off #kvm01 上 test01 已经被迁移
[root@kvm02 store]# virsh list --all
Id Name State
---
2 test02 running
7 test01 running #kvm02 上 test01 处于开启状态
4:KSM
(1)KSM 服务介绍
KSM 是在 Linux 2.6 内核版本中被添加进去的,目前大多数常用的、主流的 Linux 发行版都默认支持 KSM 技术,执行以下命令即可检査当前 Linux 系统是否支持 KSM。
bash
[root@kvm02 ~]# egrep -i ksm /boot/config-3.10.0-514.el7.x86_64
CONFIG_KSM=y #结果为 y 则表示支持
KSM 的常用配置的作用分别如下所示。
max_page_sharing:设置每个 KSM 页面允许的最大共享数量。这个配置设置了重复数据删除限制,以避免虚拟内存rmap 列表变得太大。max_page_sharing 最小值为 2因为新创建的 KSM 页面至少有两个共享器:
merge_across_nodes:指定是否可以合并来自不同 numa节点的页面。当设置为0时,ksm 只合并物理页面并驻留在同一 numa 节点的内存区域中,可以降低访问共享页面的延迟。
pages_to_scan:在 KSM 进程休眠之前会去扫描的内存数量。
run:控制 ksmd 进程是否运行,默认值为0。要激活 ksm 必须设置其值为 1。如果设置为 0,表示停止运行 ksmd, 但会保留已经合并的内存页;如果设置为 1,表示马上运行 ksmd 进程;设置为2表示停止运行 ksmd,并分离已经合并的所有内存页,但是保留已经注册为合并的内存区域给下一次使用。
sleep_milisecs:设置 ksmd 进程休眠的时间(单位:毫秒),即为ksmd 进程两次运行之间的间隔。
stable_node_chains_prune_milisecs:在 stable_node"链"中链接的整个stable_node"dups"列表被周期性地扫描,以删除陈旧的 stable_nodes。该参数的值用于调节重复扫描的时间(单位:毫秒)。
(2)配置 KSM 优化内存
在目标宿主机 kvm02 上,有 test01 和 test02 两台虚拟机。现在通过克隆的方式再创建两台新的虚拟机。然后开启这四台虚拟机,等四台虚拟机都启动后,观察内存使用情况。等内存使用量不再变化后,启动KSM 服务,过5分钟,观察内存使用量的变化情况。
克隆虚拟机
bash
[root@kvm02 ~]# virt-clone -o test02 -n test03 -f /data/store/test03.qcow2
Allocating 'test03.qcow2' | 5.0 GB 00:00:36
Clone 'test03' created successfully.
[root@kvm02 ~]# virt-clone -o test02 -n test04 -f /data/store/test04.qcow2
Allocating 'test04.qcow2' | 5.0 GB 00:00:36
Clone 'test04' created successfully.
记录开启 KSM 之前内存使用情况
bash
[root@kvm02 ~]# free -m # 确保虚拟机都启动好后,内存不再变化
total used free shared buff/cache available
Mem: 4939 2213 1744 30 981 2401
Swap: 1023 3 1020
启动KSM 服务
在 CentOS 7 系统中,通过 ksm 和 ksmtuned 两个服务来动态调节 KSM 的运行情况要想保证两个服务的存在,需要 qemu-kvm-common 这个 RPM 包的支持。执行以下命令启动 ksm 和 ksmtuned 这两个服务
bash
[root@kvm02 ~]# systemctl start ksm
[root@kvm02 ~]# systemctl start ksmtuned
当 ksm 服务启动后,需要检査/sys/kernelmm/ksm/run 文件的值是否为1,若为0则KSM 功能不会生效,需要将其置为1。
bash
[root@kvm02 ~]# echo 1 > /sys/kernel/mm/ksm/run
在 KSM 服务启动之后,KSM 能够最多共享系统物理内存一半的内存页。而ksmtuned服务一直保持循环执行,以调用 ksm 服务来运行。
对比 KSM 开启之后的内存使用情况
bash
[root@kvm02 ~]# free -m
total used free shared buff/cache available
Mem: 4939 1491 2438 30 1009 3099
Swap: 1023 3 1020
对比 KSM 开启前后内存的使用情况,"used"从开始的 2213M 降到了 1491M,说明节约了系统内存。
至此,KVM 虚拟机的各种迁移及KSM 内存优化已经介绍完成。