关于KVM 虚拟化注意的二三事整理
CPU mode 的选取
在 KVM 虚拟化中,大家对 CPU mode 的关注相对较少,多采用默认值。其实,CPU mode 的选取对 VM 的影响却很大,如果考虑不周,可能会导致稳定性差,维护成本高,影响业务等一系列问题。本文从性能,热迁移,稳定性,应用移植四个角度对 CPU mode 进行分析。
Libvirt 主要支持三种 CPU mode:
- host-passthrough: libvirt 令 KVM 把宿主机的 CPU 指令集全部透传给 VM 。因此 VM 能够最大限度的使用宿主机 CPU 指令集,故性能是最好的。但是热在迁移时,它要求目的节点的 CPU 和源节点的一致。
- host-model: libvirt 根据当前宿主机 CPU 指令集从配置文件
/usr/share/libvirt/cpu_map.xml
选择一种最相配的 CPU 型号。在这种 mode 下, VM 的指令集往往比宿主机少,性能相对 host-passthrough 要差一点,但是热迁移时,它允许目的节点 CPU 和源节点的存在一定的差异。 - custom: 这种模式下 VM CPU 指令集数最少,故性能相对最差,但是它在热迁移时跨不同型号 CPU 的能力最强。此外,custom 模式下支持用户添加额外的指令集。
性能
三种 mode 的性能排序如下:
host-passthrough > host-model > custom
但是它们的差距到底是多少呢,CERN 根据 HEPSpec06 测试标准给出了如下性能数据。
host-passthrough | host-model | custom |
---|---|---|
100% | 95.84% | 94.73% |
从上可以总结出:
- 这三种 CPU mode 的性能差距较小
- 除非某些应用对某些特殊指令集有需求,否则不太建议用
host-passthrough,原因请见后续分析。
热迁移
从理论上说:
host-passthrough
: 要求源节点和目的节点的指令集完全一致host-model
: 允许源节点和目的节点的指令集存在轻微差异- custom: 允许源节点和目的节点指令集存在较大差异
故热迁移通用性如下:
custom > host-model > host-passthrough
从实际情况来看,公司不同时间采购的 CPU 型号可能不相同;不同业务对 CPU 型号的要求也有差异。虽然常见多采用 intel E5 系列的 CPU,但是该系列的 CPU 也有多种型号,常见的有 Xeon,Haswell,IvyBridge,SandyBridge 等等。即使是 host-model,在这些不同型号的 CPU 之间热迁移 VM 也可能失败。所以从热迁移的角度,在选择 host-mode 时:
- 需要充分考虑既有宿主机类型,以后采购扩容时,也需要考虑相同问题;
- 除非不存在热迁移的场景,否则不应用选择 host-passthrough;
- host-model 下不同型号的 CPU 最好能以 aggregate hosts 划分,在迁移时可以使用 aggregate filter 来匹配相同型号的物理机;
- 如果 CPU 型号过多,且不便用 aggregate hosts 划分,建议使用 custom mode;
稳定性
从使用经验来看,host-model 和 custom 模式下的 VM 运行稳定,而 host-passthrough
则问题比较大,特别是在 centos6 内核下,常常出现宿主机 kernel panic 问题,如:
所以从稳定性出发:
- 2.6 内核及更早内核版本避免使用
host-passthrough
- custom/host-model 比较稳定
应用移植
对应用的影响主要体现在编译型应用,如 C,C++,Golang。在物理机上编译好的二进制应用,直接移植到 custom mode
的 VM 有可能出现 illegal instruction
。其中最常见的 SSE4 类型指令集异常,因为 custom 模式下没有 SSE4 指令集,而在物理机或者其它 mode 的 VM 是有该指令集的。
从经验来看:
- host-model 能够平滑移植绝大部分编译型二进制文件。
- custom 下的 VM 如果出现
illegal instruction
,在该 VM 重新编译(有时需要修改编译参数)应用后,一般能正常运行。 - 如果公司存在大量编译型应用,host-model 能让业务上云更平滑些。
搭建几点
初始化网卡
因为 centos7 默认网卡发生改变,我们需要修改内核参数,使用 eth0 作为网卡:
光标移动到 Install CentOS 上,按 tab 键 输入net.ifnames=0 biosdevname=0
回车
分区
我们不分交换分区,因为公有云上的云主机都是没有交换分区的:
分配标准分区:
VM 网络
重启/etc/init.d/network restart
或者systemctl restart network
安装软件包
安装的常用企业运维基础工具包:
yum install tree nmap dos2unix lrzsz nc lsof wget tcpdump htop iftop iotop sysstat nethogs net-tools -y
libvirtd 日志
配置文件位置:
/etc/libvirt/libvirtd.conf
日志配置:
#将日志级别设置为 1(调试)
log_level = 1
#指定日志输出文件名称
log_outputs="1:file:/var/log/libvirt/libvirtd.log"
注意:
libvirtd. 日志文件可能会飞速增长。 用户应配置logrotate ,否则 /var 文件系统最后会装满内容。
以上的日志的输出级别为debug级别.这个级别的日志是最多的,一般只在开发以及测试的时候使用.而在生产运行环境中,日志的级别为info,warn,error,fatal. 以下前面的数字为他们的level.
1 debug
2 info
3 warn
4 error
5 fatal
重启 libvirtd:
/etc/init.d/libvirtd restart
如果在目录下还是没发现日志文件,那么你可能需要使用一下命令来运行 libvirtd:
libvirtd --daemon --listen --config /etc/libvirt/libvirtd.conf
快速克隆VM
本机克隆
现有本地 VM 需要先停止。
查看本地VM:
$ virsh list --all
Id 名称 状态
---------------------------------------------------
- vm-k8s 关闭
从 vm-k8s 克隆一个 vm-master1,执行克隆操作,使用磁盘文件 vm-master1.img
virt-clone -o generic -n vm-k8s -f /data/image/vm-master1.img
启动 VM:
virsh start vm-master1
启动后修改主机名、IP等
复制配置文件和硬盘文件跨机克隆
查看现有 VM:
$ virsh list --all
Id Name State
----------------------------------------------------
8 vm-k8s running
这里将从 vm-k8s
克隆另一个 vm-master2
导出 vm-k8s
配置文件
virsh dumpxml vm-k8s > vm-master2.xml
查看 vm-k8s
磁盘文件所在位置:
$ virsh edit vm-k8s
<source file='/data/image/vm-k8s.img'/>
复制 vm-k8s
磁盘文件为 vm-master2.img
cd /data/image
cp vm-k8s.img vm-master2.img
通过 SCP 把磁盘文件和配置文件复制到目标机器。
修改 vm-master2.xml
:
<domain type='kvm' id='10'>
<name>`vm-master2</name>
<uuid>fe1f692d-34d5-4e0c-ab36-ba84eb024ee5</uuid>
……
<source file='/data/image/vm-master2.img'/>
……
定义 vm-master2
配置文件:
$ virsh define vm-master2.xml
Domain vm-master2 defined from vm-master2.xml
此时会看到 vm-master2
已经生成
$ virsh list –all
Id Name State
----------------------------------------------------
- vm-master2 shut off
启动 vm-master2
,重新更改主机名、IP等。
性能优化
CPU优化
kvm 是一个进程,是受 CPU 的调度,对于物理 CPU,同一个 core 的 threads 共享 L2 Cache,同一个 socket 的 cores 共享 L3 cache,所以 VM 的 vcpu 应当尽可能在同一个 core 和 同一个 socket 中,增加 cache 的命中率,从而提高性能。IBM 测试过,合理绑定 vcpu 能给 JVM 来的 16% 的性能提升。
VM vcpu 尽可能限定在一个 core 或者一个 socket 中。例如:当 vcpu 为 2 时,2 个 vcpu 应限定在同一个 core 中,当 vcpu 大于 2 小于 12 时,应限定在同一个 socket 中。
我们可以使用 taskset 来进行操作:
$ taskset -cp 0 8337
pid 8337's current affinity list: 0-3
# 表示当前8337会在0-3CPU上调度
pid 8337's new affinity list: 0
#表示当前8337会在cpu0上进行调度
8377 是进程号,通过 ps -ef|grep kvm 来获取到
-p pid 指定进程
-c 指定cpu(可以写多个)
提示:可以减少开机 miss,性能可以提高10%
内存优化
关闭 KSM
当 Linux 启用了KSM 之后,KSM 会检查多个运行中的进程,并比对它们的内存。如果任何区域或者分页是一样的,KSM 就会毫不犹豫地合并他们成一个分页。 那么新分页也是被标记成 copy on write。如果 VM 要修改内存的话,那么 Linux 就会分配新的内存给这个VM。
优点:
- 一个 VM 启动,则只继承了父进程(qemu-kvm)的内存。一台 VM 的内存,可以让相同操作系统或者运行相同应用的 VM共享。
- 当开启了 KSM,常用的进程数据存在缓存和主内存中。这样可以减少 VM 的缓存未命中,同时也提高了 VM 性能。
- 共享内存降低了 VM 的总体内存使用率,从而允许更高的密度和更大的资源利用率。
缺点:
- 利用 KSM 使内存超用。这会导致消耗一定的计算资源用于内存扫描,加重了 CPU 的消耗。内存超用,使得频繁地使用 swap 交互,导致 VM 性能下降。
- KSM使用了边通道(side channels),可能存在泄露客户信息的潜在风险。为此就要考虑在 VM 上关闭 KSM。
所以总结一下应用的场景:
- 生产环境慎用,应急时可开启。
- 测试环境建议使用。
- 桌面虚拟化环境建议使用,但要注意内存使用情况。
关闭 KSM:
1)禁止某个访客与其他访客共享内存,XML文件可配置为:
<memoryBacking>
<nosharepages/>
</memoryBacking>
2)禁止所有访客直接共享内存,主机配置为:
echo 0 > /sys/kernel/mm/ksm/pages_shared
echo 0 > /sys/kernel/mm/ksm/pages_sharing
打开 huge page
KVM Guest 可以开启大的页内存支持,从而通过增加事务后备缓冲区(TLB)的 CPU 缓存命中率来提高性能。
打开透明大页方式有两种:
- 允许某个 Guest 开启透明大页
<memoryBacking>
<hugepages/>
</memoryBacking>
echo 25000 > /pro c/sys/vm/nr_hugepages
mount -t hugetlbfs hugetlbfs /dev/hugepages
service libvirtd restart
- 允许 Host 中所有 Guest 开启透明大页
echo always > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
echo 0 > /sys/kernel/mm/transparent_hugepage/khugepaged/defrag
IO 优化
kvm 就使用 virtio。
Virtio是一种半虚拟化技术,让磁盘知道你是运行在 VM 里面。这是一种半虚拟化技术,有兴趣可以了解一下。
IO cache
kvm 支持多种 VM 多种 IO Cache 方式:writeback, none, writethrough 等。
- 性能上: writeback > none > writethrough
- 安全上: writeback < none < writethrough。
权衡安全性和性能,KVM 推荐使用 none:
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' cache='none'/> # cache 可为 writeback, none, writethrough,directsync,unsafe 等
...
</disk>
调度算法
Linux kernel 提供了三种 Disk IO 的调度策略,分别为 noop,deadline,cfq。(CentOS 6 有四种)
- noop: noop is often the best choice for memory-backed block devices (e.g. ramdisks) and other non-rotational media (flash) where trying to reschedule I/O is a waste of resources
- deadline: deadline is a lightweight scheduler which tries to put a hard limit on latency
- cfq: cfq tries to maintain system-wide fairness of I/O bandwidth
相关资料:
- http://www.cnblogs.com/zhenjing/archive/2012/06/20/linux_writeback.html
- http://jackyrong.iteye.com/blog/898938
由于一个宿主机上会运行大量 VM ,为了防止某个因某个 VM 频繁的 IO 操作影响其它 VM ,所以应该选择 cfq 这种公平的调度策略。
查看当前调度算法
$ cat /sys/block/sda/queue/scheduler
noop [deadline] cfq
更改调度算法如下:
echo “noop” > /syc/block/sda/queue/scheduler
磁盘格式
KVM 常用 Raw 和 Qcow2 格式作为 VM 的镜像文件。对 VM 而言,通俗的说,Raw 格式相当于裸盘,Qcow2 是 copy on write
,二者对比如下:
- 性能:Raw > Qcow2
- 节省空间:Qcow2 > Raw
- 安全:Qcow2 > Raw
Qcow2 格式发展到现在,已经有和 Raw 相近的性能,同时能较好的节省空间,所以推荐使用 Qcow2 镜像,但是要最大可能的发挥性能,使用 Raw 格式也未尝不可。
网络优化
启用 vhost_net
VhostNet provides better latency (10% less than e1000 on my system) and greater throughput (8x the normal virtio, around 7~8 Gigabits/sec here) for network.
modprobe vhost-net
网卡多队列
对 VM 而言,virtio-net 不能并行的处理网络包,当网络流量很大时,单个 vCPU 有限的处理能力将直接影响 VM 的网络流量,所以可以通过多队列的 virtio-net 提高 VM 网络吞吐量。
<devices>
<interface type='network'>
...
<driver name='vhost' txmode='iothread' ioeventfd='on' event_idx='off' queues='N'/> # queues=N
</interface>
</devices>
vm 查看队列是否生效:
$ ll /sys/class/net/eth0/queues/
总用量 0
drwxr-xr-x 2 root root 0 12月 20 01:24 rx-0
drwxr-xr-x 2 root root 0 12月 20 01:24 rx-1
drwxr-xr-x 2 root root 0 12月 20 01:24 rx-2
drwxr-xr-x 2 root root 0 12月 20 01:24 rx-3
drwxr-xr-x 2 root root 0 12月 20 01:24 rx-4
drwxr-xr-x 2 root root 0 12月 20 01:24 rx-5
drwxr-xr-x 2 root root 0 12月 20 01:24 rx-6
drwxr-xr-x 2 root root 0 12月 20 01:24 rx-7
drwxr-xr-x 3 root root 0 12月 20 01:24 tx-0
drwxr-xr-x 3 root root 0 12月 20 01:24 tx-1
drwxr-xr-x 3 root root 0 12月 20 01:24 tx-2
drwxr-xr-x 3 root root 0 12月 20 01:24 tx-3
drwxr-xr-x 3 root root 0 12月 20 01:24 tx-4
drwxr-xr-x 3 root root 0 12月 20 01:24 tx-5
drwxr-xr-x 3 root root 0 12月 20 01:24 tx-6
drwxr-xr-x 3 root root 0 12月 20 01:24 tx-7
小结
最后用一张脑图小结一下:
参考资料:
- 点赞
- 收藏
- 关注作者
评论(0)