一、虚拟机磁盘的格式
1.1 根据存储数据方式的不同可以分为两种格式,一种是稀疏模式。一种是全镜像模式,全镜像模式无法做快照,IO层面是有qemu模拟的,CPU和内存是有KVM实现的,以下是KVM的功能
KVM 所支持的功能包括:
支持 CPU 和 memory 超分(Overcommit)
支持半虚拟化 I/O (virtio)
支持热插拔 (cpu,块设备、网络设备等)
支持实时迁移(Live Migration)
支持 PCI 设备直接分配和 单根I/O 虚拟化 (SR-IOV)
支持 内核同页合并 (KSM )
支持 NUMA (Non-Uniform Memory Access,非一致存储访问结构 )
1.2 KVM工具集合
libvirt:操作和管理 KVM 虚机的虚拟化 API,使用 C 语言编写,可以由 Python, Ruby, Perl, PHP, Java 等语言调用。可以操作包括 KVM,vmware,XEN,Hyper-v,LXC 等 Hypervisor。
Virsh:基于 libvirt 的 命令行工具 (CLI)
Virt-Manager:基于 libvirt 的 GUI 工具
virt-v2v:虚机格式迁移工具
virt-* 工具:包括 Virt-install (创建KVM虚机的命令行工具), Virt-viewer (连接到虚机屏幕的工具),Virt-clone(虚机克隆工具),virt-top 等
sVirt:安全工具
1.3 磁盘格式
- raw
指定多大就创建多大,直接占用指定大小的空间
老牌的格式了,用一个字来说就是裸,也就是赤裸裸,你随便dd一个file就模拟了一个 raw 格式的镜像。由于裸的彻底,性能上来说的话还是不错的。目前来看,KVM 和 XEN 默认的格式好像还是这个格式。因为其原始,有很多原生的特性,例如直接挂载也是一件简单的事情。裸的好处还有就是简单,支持转换成其它格式的虚拟机镜像对裸露的它来说还是很简单的(如果其它格式需要转换,有时候还是需要它做为中间格式),空间使用来看,这个很像磁盘,使用多少就是多少(du -h 看到的大小就是使用大小),但如果你要把整块磁盘都拿走的话得全盘拿了(copy 镜像的时候),会比较消耗网络带宽和 I/O。接下来还有个有趣的问题,如果那天你的硬盘用着用着不够用了,你咋办,在买一块盘。但raw格式的就比较犀利了,可以在原来的盘上追加空间:
dd if=/dev/zero of=zeros.raw bs=1024k count=4096(先创建4G的空间)
cat foresight.img zeros.raw > new-foresight.img(追加到原有的镜像之后)
当然,好东西是吹出来的,谁用谁知道,还是有挺多问题的。由于原生的裸格式,不支持 snapshot 也是很正常的。传说有朋友用版本管理软件对 raw 格式的文件做版本管理从而达到 snapshot 的能力,估计可行,但没试过,这里也不妄加评论。但如果你使用 LVM 的裸设备,那就另当别论。说到 LVM 还是十分的犀利的,当年用 LVM 做虚拟机的镜像,那性能杠杠的。而且现在好多兄弟用虚拟化都采用LVM来做的。在 LVM 上做了很多的优化,国外听说也有朋友在 LVM 增量备份方面做了很多的工作。目前来 LVM 的 snapshot、性能、可扩展性方面都还是有相当的效果的。目前来看的话,备份的话也问题不大。就是在虚拟机迁移方面还是有很大的限制。但目前虚拟化的现状来看,真正需要热迁移的情况目前需求还不是是否的强烈。虽然使用 LVM 做虚拟机镜像的相关公开资料比较少,但目前来看牺牲一点灵活性,换取性能和便于管理还是不错的选择。对于 LVM 相关的特性及使用可以参考如下链接:
http://www.ibm.com/developerworks/linux/library/l-lvm2/index.html - cow
曾经 qemu 的写时拷贝的镜像格式,目前由于历史遗留原因不支持窗口模式。从某种意义上来说是个弃婴,还没得它成熟就死在腹中,后来被 qcow 格式所取代 - qcow
一代的 qemu 的 cow 格式,刚刚出现的时候有比较好的特性,但其性能和 raw 格式对比还是有很大的差距,目前已经被新版本的 qcow2 取代。其性能可以查看如下链接:
http://www.linux-kvm.org/page/Qcow2 - qcow2
是openstack默认也是比较推荐的格式,将差异保存在一个文件,文件比较小而且做快照也比较小,空间是动态增长的
现在比较主流的一种虚拟化镜像格式,经过一代的优化,目前 qcow2 的性能上接近 raw 裸格式的性能,这个也算是 redhat 的官方渠道了,对于 qcow2 的格式,几点还是比较突出的,qcow2 的 snapshot,可以在镜像上做 N 多个快照:更小的存储空间,即使是不支持 holes 的文件系统也可以(这下 du -h 和 ls -lh 看到的就一样了),支持多个 snapshot,对历史 snapshot 进行管理,支持 zlib 的磁盘压缩,支持 AES 的加密 - vmdk
VMware 的格式,这个格式说的蛋疼一点就有点牛X,原本 VMware 就是做虚拟化起家,自己做了一个集群的 VMDK 的 pool,做了自己的虚拟机镜像格式。又拉着一些公司搞了一个 OVF 的统一封包。从性能和功能上来说,vmdk 应该算最出色的,由于 vmdk 结合了 VMware 的很多能力,目前来看,KVM 和 XEN 使用这种格式的情况不是太多。但就 VMware 的 Esxi 来看,它的稳定性和各方面的能力还是可圈可点 - vdi
VirtualBox 1.1 compatible image format, for exchanging images with VirtualBox.
SUN 收购了 VirtualBox,Oracle 又收购了 SUN,这么说呢,vdi 也算虚拟化这方面的一朵奇葩,可惜的是入主的两家公司。SUN 太专注于技术(可以说是 IT 技术最前端也不为过),Oracle 又是开源杀手(mysql 的没落)。单纯从能力上来说 vdi 在 VirtualBox 上的表现还是不错的。也是不错的 workstation 级别的产品
1.4 磁盘格式的转换
- raw 转换为 qcow2
此步骤使用 qemu-img 工具实现,如果机器上没有,可以通过 rpm 或 yum 进行安装,包名为 qemu-img
qemu-img 是专门虚拟磁盘映像文件的 qemu 命令行工具。
具体命令如下:
qemu-img convert -f raw centos.img -O qcow2 centos.qcow2
参数说明:convert 将磁盘文件转换为指定格式的文件
-f 指定需要转换文件的文件格式
-O 指定要转换的目标格式
转换完成后,将新生产一个目标映像文件,原文件仍保存
- qcow2 转换为 raw
qemu-img convert -O qcow2 my.raw myqow.qcow
- VMDK 转换为 qcow2
qemu-img convert -f vmdk -O qcow2 xxx.vmdk xxx.img
http://www.ibm.com/developerworks/cn/linux/l-cn-mgrtvm3/index.html
1.5 raw 实际空间的大小
[root@linux-node1 opt]# qemu-img convert -O qcow2 CentOS-7-x86_64.raw myqcow.qcow
[root@linux-node1 opt]# ll -h
总用量 7.4G
-rw-r--r-- 1 qemu qemu 4.1G 9月 3 13:23 CentOS-7-x86_64-DVD-1511.iso
-rw-r--r-- 1 root root 10G 9月 10 11:09 CentOS-7_x86_64.raw
-rw-r--r-- 1 qemu qemu 10G 9月 22 21:16 CentOS-7-x86_64.raw # raw 格式直接占用实际分配的空间大小
-rw-r--r-- 1 root root 1.1G 9月 22 21:17 myqcow.qcow # 转化为 qcow2 格式之后在占用的是实际空间大小
1.6 查看磁盘详细信息
[root@linux-node1 opt]# qemu-img info CentOS-7-x86_64.raw # 查看 raw 格式的磁盘信息
image: CentOS-7-x86_64.raw
file format: raw
virtual size: 10G (10737418240 bytes)
disk size: 1.1G
[root@linux-node1 opt]# qemu-img info myqcow.qcow # 查看 qcow 格式的磁盘信息
image: myqcow.qcow
file format: qcow2
virtual size: 10G (10737418240 bytes)
disk size: 1.1G
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
二、关于网络
2.1 默认是使用的 nat 网络,会成为虚拟机的瓶颈,因此需要创建一个桥接网卡并把虚拟机桥接至网卡,然后将虚拟机桥接一下即可使用物理网络
- 通过命令创建桥接网卡
[root@linux-node1 opt]# brctl addbr br0
[root@linux-node1 opt]# brctl addif br0 eth0 # 会断网,这是将 br0 和 eth0 进行关联
ip addr del dev eth0 192.168.56.11/24 # 删除网卡的 IP 地址信息
ifconfig br0 192.168.56.11/24 up # 为 br0 配置 IP 并启动网卡,此时可以远程连接
[root@linux-node1 ~]# route add default gw 192.168.56.2
[root@linux-node1 ~]# ping www.baidu.com
PING www.a.shifen.com (112.80.248.73) 56(84) bytes of data.
64 bytes from 112.80.248.73: icmp_seq=1 ttl=128 time=70.0 ms
64 bytes from 112.80.248.73: icmp_seq=2 ttl=128 time=74.7 ms
- 通过配置文件文件创建桥接网卡
cd /etc/sysconfig/network-scripts/
cp ifcfg-eth0 ifcfg-br0
vim ifcfg-eth0 # 去掉 eth0 网卡配置文件中的UUID/MAC/IP等信息
BOOTPROTO=static
DEVICE=eth0
ONBOOT=yes
BRIDGE=br0 # 添加一个桥接到 br0 的配置
NM_CONTROLLED=no
# br0的配置信息如下
vim ifcfg-br0 # 里面也不要有 UUID 和 MAC 等信息,IP 地址配置成 eth0 使用的地址即可,当然也可以是其他可以使用的 IP
TYPE=Bridge # 类型为桥接
BOOTPROTO=static
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
IPV6_FAILURE_FATAL=no
NAME=br0 # 网卡名称
DEVICE=br0 # 设备名称
ONBOOT=yes
IPADDR=192.168.10.128
NETMASK=255.255.255.0
GATEWAY=192.168.10.2
DNS1=192.168.10.2
最后重启服务器,验证重启服务器之后 br0 网卡生效,然后在服务器上创建的虚拟机就可以通过桥接网卡的方式使用和物理机同网段的 IP 地址连接外网了
2.2 修改虚拟机配置文件
[root@linux-node1 ~]# virsh edit CentOS-7-x86_64
<interface type='bridge'> # 类型改为 bridge
<mac address='52:54:00:60:84:d0'/>
<source bridge='br0'/> # 注意是 bridgr='br0'
<model type='virtio'/> # 类型为通过 virtio 实现的
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
2.3 重启虚拟机
[root@linux-node1 ~]# virsh shutdown CentOS-7-x86_64
域 CentOS-7-x86_64 被关闭
[root@linux-node1 ~]# virsh start CentOS-7-x86_64
域 CentOS-7-x86_64 已开始
2.4 编辑虚拟机网卡,配置 IP 和网关
2.5 将上一步保存退出后重启网络访问并测试连接及确认可以通过外网安装服务
三、宿主机的优化
全虚拟化和半虚拟化,内核态 Ring 0 可以直接访问周边的硬件设备,CPU、内存、网卡和硬盘等,应用运行在 Ring 3 是用户态,用户态不能直接操作硬件,如果要操作硬件会产生系统调用,客户端的操作系统不能工作在 Ring 0,因此 Intel
提供 vt-x 提供加速上下文切换,KVM 在系统里面是一个 qemu 进程,进程要受到 CPU 的调度,在多核 CPU 进程可能会被调度到任意 CPU 核心,CPU 的一级缓存是使用静态内存做的,二级缓存是使用高速的动态内存,缓存是将经常访问的数据缓存下来以加速访问速度,将进程绑定在一个 CPU 可以提高缓存的命中率
3.1 CPU绑定优化
[root@linux-node1 ~]# taskset --help
用法:taskset [选项] [掩码 | cpu列表] [pid|命令 [参数...]]
选项:
-a, --all-tasks 在给定 pid 的所有任务(线程)上操作
-p, --pid 在存在的给定 pid 上操作
-c, --cpu-list 以列表格式显示和指定 CPU
-h, --help 显示此帮助
-V, --version 输出版本信息
默认行为是运行一条新命令:
taskset 03 sshd -b 1024
您可以获取现有任务的掩码:
taskset -p 700
或设置掩码:
taskset -p 03 700
使用逗号分隔的列表格式而不是掩码:
taskset -pc 0,3,7-11 700
列表格式中的范围可以带一个跨度参数:
例如 0-31:2 与掩码 0x55555555 等效
[root@linux-node1 ~]# taskset -cp 2 42340 # 将进程号为 42340 的进程指定运行在第二核心 CPU
pid 42340's current affinity list: 0-3
pid 42340's new affinity list: 2
3.2 内存优化
- 内存EPT技术
系统将内存识别为虚拟内存,包含物理内存和交换分区,KVM 是一个进程,EPT 是 Intel 用于加快内存映射的技术 - 大页内存,加快内存寻址
[root@linux-node1 ~]# cat /proc/meminfo
MemTotal: 3866944 kB
MemFree: 166796 kB
MemAvailable: 1775636 kB
Buffers: 1632 kB
Cached: 1691036 kB
SwapCached: 52 kB
Active: 1682932 kB
Inactive: 1594028 kB
Active(anon): 1090476 kB
Inactive(anon): 558692 kB
Active(file): 592456 kB
Inactive(file): 1035336 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 2097148 kB
SwapFree: 2096024 kB
Dirty: 36 kB
Writeback: 0 kB
AnonPages: 1584492 kB
Mapped: 78708 kB
Shmem: 64876 kB
Slab: 283776 kB
SReclaimable: 234440 kB
SUnreclaim: 49336 kB
KernelStack: 10528 kB
PageTables: 10088 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 4030620 kB
Committed_AS: 2855828 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 193548 kB
VmallocChunk: 34359483232 kB
HardwareCorrupted: 0 kB
AnonHugePages: 1181696 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB # Centos 7 默认已开启
DirectMap4k: 100160 kB
DirectMap2M: 4093952 kB
- 开启内存合并
[root@linux-node1 ~]# cat /sys/kernel/mm/transparent_hugepage/enabled
# 将连续的没有使用的内存合并为 2M 一个表,减少内存碎片
[always] madvise never
- IO优化
使用 virtIO 半虚拟化的 IO 技术,让磁盘知道其运行在虚拟机环境当中 - 磁盘的调度算法:顺序读写远大于随机读写,系统的 IO 调度器是
[root@linux-node1 ~]# cat /sys/block/sda/queue/scheduler # Centos 7 默认只有 3 个,Centos 6 有 4 个
noop:不进行调度,用于 SSD
[deadline]:最后期限算法,防止写操作因为不能读取而被饿死的情况
cfq:完全公平,公平分配 IO 访问,Centos 6 的默认算法
- 写入磁盘的几种方式
-
writeback:同时使用了虚拟机和物理机的 pagecache,会被同时写入到虚拟机和物理机的 pagecache 在写入到物理磁盘缓存,这种方式写入速度快但是假如突然断电会导致出现数据丢失而导致数据一致性出现问题,本方式性能最好但是不安全
-
None:将数据直接写入到物理磁盘缓存在写入磁盘,速度次于 writeback
-
writethrough:直接写入到物理磁盘,突然断电的话数据丢失最少,但是速度比较慢,因为绕过了上面的两层 pagecache 即没有使用缓存。
-
web 站点适用于使用 writeback,即读多写少的情况,对于需要提供数据安全的场景必须数据库等推荐使用 writethrough,KVM 默认就是使用的 writethrough
作者:Alexander_Zz
链接:https://www.jianshu.com/p/f215f95c4ecd
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
来源:oschina
链接:https://my.oschina.net/u/4442211/blog/3831946