Centos7.2 KVM的搭建(一)
这里主要是对kvm操作的讲解,原理性的东西可以看KVM权威指南,有一个系统性的了解。
一、KVM的介绍
1.1 KVM简介
KVM仅仅是linux内核的一个模块,管理和创建完成的KVM虚拟机需要更多的辅助工具。
KVM是基于虚拟化扩展(Intel VT或者ADM-V)的开源的linux原生的全虚拟化解决方案。KVM中,虚拟机被实现为常规的linux进程,由标准linux调度程序进调度;虚拟的每个虚拟cpu被实现为一个常规的linux进程。
KVM本身不执行任何硬件模式,需要客户空间程序通过/dev/kvm接口设置一个客户机虚拟服务器的地址空间,向它提供模拟的I/O,并将它的视频显示映射回宿主机的显示屏。目前这个应用程序是QEMU。
KVM架构:
Guest:客户机系统,包括CPU(vCPU)、内存、驱动(Console、网卡、I/O 设备驱动等),被 KVM 置于一种受限制的 CPU 模式下运行。
KVM:运行在内核空间,提供CPU 和内存的虚级化,以及客户机的 I/O 拦截。Guest 的 I/O 被 KVM 拦截后,交给 QEMU 处理。
QEMU:修改过的为 KVM 虚机使用的 QEMU 代码,运行在用户空间,提供硬件 I/O 虚拟化,通过 IOCTL调用(执行虚拟处理器)/dev/kvm 设备和 KVM 交互。
1.2 KVM模块
KVM模块是KVM虚拟机的核心部分。其主要功能是初始化CPU硬件,打开虚拟化模式,然后将虚拟客户及运行在虚拟机模式下,并对虚拟客户机的运行提供一定的支持。KVM仅支持硬件虚拟化。KVM模块与用户空间QEMU的通信接口主要是一系列针对特殊设备文件的LOCTL调用。
除了处理器的虚拟化,内存虚拟化也是由KVM模块实现的。在客户机运行时候,处理器真正使用的也表并不是客户机操作系统维护的页表,而是KVM模块根据这个也表维护的另外一套影子页表。影子也表实现复杂,新的处理器再硬件上做了增强(Intel的EPT技术)。通过引入第二级也表来描述客户机虚拟地址和真实物理地址的转换,硬件可以自动进行两级转换生成正确的内存访问地址。KVM模块称其为二维分页机制。
外接设备的模拟一般不由KVM模块负责,只有对性能要求比较高的虚拟设备才会由KVM内核模块来直接负责,比如虚拟终端控制器和虚拟时钟,这样可以大量减少处理器的模式切换的开销,大部分的输入和输出设备由QEMU来负责。
1.3 QEMU设备类型
QEMU本身并不是KVM的一部分,QEMU虚拟机是一个纯软件的实现,性能低下但是支持QEMU本身编译运行的平台上可以实现虚拟机的功能。为了简化开发和代码重用,KVM在QEMU的基础上进行了修改。虚拟机运行期间,QEMU会调用KVM模块提供的系统调用进入内核,由KVM模块负责将虚拟机置于处理器的特殊模式运行,遇到虚拟机进行输入输出操作,KVM模块会从上次的系统调用出口处返回QEMU,由QEMU来负责解析和模拟这些设备。 从 QEMU 的角度看,也可以说是 QEMU 使用了 KVM 模块的虚拟化功能,为自己的虚机提供了硬件虚拟化加速。除此以外,虚机的配置和创建、虚机运行说依赖的虚拟设备、虚机运行时的用户环境和交互,以及一些虚机的特定技术比如动态迁移,都是 QEMU 自己实现的。
1.4 简述
KVM现在主要用的是virtio这种半虚拟化技术,如果再对性能要求比较高呢,用SR-IOV(博通网卡基本不支持,Inter的好多网卡支持)这种形式。同时呢宿主机的操作系统可以考虑用Centos7系列的系统,因为Centos7系列的系统支持多队列virtio网卡。
关于网卡这块呢,如果资金富裕的话,用万兆光纤网卡做bond模式然后做成桥接为虚拟机提供服务会好一点。当然如果对网络之间数据传输要求没有那么高的话,可以用服务器自带的四个千兆网卡做Bond0然后做桥接提供给客户机使用。当然要想使用SR-IOV这种虚拟VF网卡的形式就要换INTER的网卡了。(这里有一个问题没有解决,就是在使用桥接形式,上面的虚拟机某个虚拟机可能会出现网络不通的情况,要重启网卡才能继续通信。https://bugs.centos.org/view.php?id=5526)
关于硬盘,因为我们大部分虚拟机的空间要求都不太大,可以考虑24盘符的sas的300G的小盘,每块物理盘上面运行一块虚拟机,这样可以保证虚拟机的IO读写性能。如果需要大的盘符的话,可以考虑远程挂载的方式。
关于内存,虽然KVM支持内存过载使用,也就是分配的虚拟内存总和大于物理服务器实际的内存总和,但是书上和个人的使用经验还是不建议这么做。关于提到的bollooning这种内存气球的模式,来实现虚拟机内存的动态调整而不是关机来调整内存大小的形式,缺点是内存的动态增加和减少可能会使用内存被过度碎片化,从而降低内存使用时的性能,另外内存的变化会影响到客户机内核对内存使用的优化,所以个人也没有在生产场景中使用这种形式。
二、KVM的安装和使用
2.1 KVM的安装
第一步:查看服务器CPU目前是否支持硬件虚拟化
# dmidecode |grep -A 8 "System Information"|grep 'Product Name' #我的服务器为R720xd
Product Name: PowerEdge R720xd
# cat /etc/redhat-release #我的操作系统版本为Centos7.2
CentOS Linux release 7.2.1511 (Core)
# grep -E '(vmx|svm)' /proc/cpuinfo |uniq #通过检查cpuinfo文件中的CPU特性标志(flags)来查看CPU目前是否支持硬件虚拟化。
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm ida arat pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt
#Intel系统CPU支持虚拟化的标志位“vmx",AMD系列CPU的标志位“svm”一般我们的CPU模式就是打开支持的,如果没有打开可以通过更改BIOS设置。
第二步:安装前的准备
关闭防火墙,selinux,NetworkManager和时间同步,如:systemctl stop firewalld.service
第三步:安装KVM
当然你可以再做系统的时候就选择Development==》Development tools进行安装
一般我们都是在安装完操作系统之后再进行安装,因为一般我们的系统都是无人值守安装出一个通用的系统的形式再安装对应的软件,系统特殊定制化的比较少。
# yum -y install kvm python-virtinst libvirt tunctl bridge-utils virt-manager qemu-kvm-tools virt-viewer virt-v2v virt-install #除了安装kvm模块以外,还安装了一些对应的包组,如tunctl bridge-utils 网卡桥接管理,libvirt管理工具,virt-manager virt-viewer GUI图形管理工具
# yum -y install libguestfs-tools #安装kvm虚拟化管理工具包
# lsmod |grep kvm #查看kvm模块是否加载
kvm_intel 162153 0
kvm 525259 1 kvm_intel
# service libvirtd start #启动libvirt虚拟化工具服务
Redirecting to /bin/systemctl start libvirtd.service
# virsh -c qemu:///system list #用命令检查KVM是否成功安装,下面为正常。
Id 名称 状态
----------------------------------------------------
#如果显示的是一个错误信息,说明有些东西出现了问题,如:
# virsh -c qemu:///system list
错误:连接到管理程序失败
错误:将插槽连接到 '/var/run/libvirt/libvirt-sock' 失败: 没有那个文件或目录 #因为没有启动libvirtd服务造成
博文来自:www.51niux.com
2.2 通过图形界面创建kvm虚拟机
第一步:Centos7安装图形界面:
# # yum -y groups install "GNOME Desktop"
# yum install gnome-classic-session gnome-terminal nautilus-open-terminal control-center liberation-mono-fonts fontforge -y
第二步:安装VNC(不做详细解释了)
# yum install tigervnc-server -y #安装vnc软件
# vncpasswd #设置vnc连接密码
Password:
Verify:
# vncserver :1 #启动vnc
下面是另一种方式:
# cp /lib/systemd/system/vncserver\@.service /etc/systemd/system/vncserver\@:1.service
# vi /etc/systemd/system/vncserver\@\:1.service
将:
Type=forking
ExecStart=/usr/sbin/runuser -l <USER> -c "/usr/bin/vncserver %i"
替换为:
Type=simple
ExecStart=/usr/sbin/runuser -l root -c "/usr/bin/vncserver %i"
# systemctl daemon-reload
# systemctl start vncserver@:1.service
2.3 网卡做桥接
第一步:前提查看
# lsmod |grep tun #查看tun模块是否加载(需要tunctl bridge-utils 这两个进行yum安装)
tun 27141 1
# ll /dev/net/tun #检查权限,需要让当前用户拥有可读写权限。
crw-rw-rw-. 1 root root 10, 200 Jan 4 2017 /dev/net/tun
#查看linux是否支持bonding,大部分发行版都支持
# modinfo bonding |more #如果输出下面的信息则说明支持bonding,如果没有说明内核不支持bonding,需要重新编译内核。
filename: /lib/modules/3.10.0-514.2.2.el7.x86_64/kernel/drivers/net/bonding/bonding.ko
author: Thomas Davis, tadavis@lbl.gov and many others
description: Ethernet Channel Bonding Driver, v3.7.1
version: 3.7.1
license: GPL
srcversion: B664145ACFBCC961505C750
vermagic: 3.10.0-514.2.2.el7.x86_64 SMP mod_unload modversions
第一步:我们先对两个光纤网卡做bond0模式(这种模式交换机要做设置)
# cat /etc/sysconfig/network-scripts/ifcfg-p5p1 #只粘贴做了修改的地方
BOOTPROTO=none
ONBOOT=yes
MASTER="bond0"
SLAVE="yes"
#cat /etc/sysconfig/network-scripts/ifcfg-p5p2 #只粘贴做了修改的地方
BOOTPROTO=none
ONBOOT=yes
MASTER="bond0"
SLAVE="yes"
# cat /etc/sysconfig/network-scripts/ifcfg-bond0
DEVICE="bond0"
BOOTPROTO="static"
NM_CONTROLLED="no"
ONBOOT="yes"
TYPE="Ethernet"
USERCTL="no"
MASTER="yes"
BONDING_OPTS="mode=0 miimon=100"
BRIDGE=br0 #如果单纯的做bond,就不加这个选项,直接配置IP地址等信息了。
第二步:做桥接配置
# cat /etc/sysconfig/network-scripts/ifcfg-br0
DEVICE="br0"
BOOTPROTO="static"
NM_CONTROLLED="no"
ONBOOT="yes"
TYPE="Bridge"
USERCTL="no"
IPADDR=192.168.1.100
NETMASK=255.255.255.0
GATEWAY=192.168.1.254
DNS1=114.114.114.114
DNS2=223.5.5.5
第三步:重启网卡
# /etc/init.d/network restart
第四步:查看
# cat /proc/net/bonding/bond0 #查看bond是否两个万兆网卡都加载
Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011)
Bonding Mode: load balancing (round-robin)
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 0
Down Delay (ms): 0
Slave Interface: p5p1
MII Status: up
Speed: 10000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: a0:36:9f:80:7c:50
Slave queue ID: 0
Slave Interface: p5p2
MII Status: up
Speed: 10000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: a0:36:9f:80:7c:52
Slave queue ID: 0
# brctl show
bridge name bridge id STP enabled interfaces
br0 8000.be6b6465eab2 no bond0
virbr0 8000.5254008c9e07 yes virbr0-nic
博文来自:www.51niux.com
2.4 VNC图形界面创建虚拟机
# virt-manager #在终端界面输入此命令,virt-manager是一个基于Python和pygtk编写的虚拟机管理工具前端,通过引用libvirt来进行桌面环境下的虚拟机管理
默认就已经连接了QEMU,如果没有的话虚拟系统管理器里面点击文件==》添加连接》选择连接
创建虚拟机:
第一步:点击文件==》新建虚拟机==》本地安装介质(还可以选择其他的安装方式)==》前进
第二步:选择要安装的ISO系统镜像
第三步:设置内存和CPU大小
第四步:设置虚拟机磁盘大小和镜像位置
第五步:更改虚拟机名称和网卡设备
第六步:进行自定义配置(设置网卡和硬盘的半虚拟化)
注:这里对存储格式说一下:
raw:
原始的磁盘镜像格式,这种格式的文件的优势在于它非常简单并且容易移植到其他模式器上去使用。支持“空洞”,节省磁盘空间。dd命令创建的镜像也是raw格式,不过一开始就让镜像实际占用了分配的空间,而没有使用稀疏文件的方式对待空洞来节省磁盘空间。这种一开始就占用的方式,在数据第一次写入的时候要比稀疏文件方式好一点。
qcow2:
是QEMU目前推荐的镜像格式,它是功能最多的格式。它支持稀疏文件,支持可选的AES加密以提高镜像文件安全性,支持基于zlib的压缩,支持在一个镜像文件中有多个虚拟机快照。因为qcow2具有加密的安全性,所以在对磁盘IO性能要求并非很高时建议选择qcow2类型的镜像文件。
第七步:点击开始安装
第八步:剩下的就跟光盘安装一样了,自行安装吧。
第九步:系统安装结束后,进行网卡配置并重启网卡测试。
第十步:我们来处理几个问题
第一个问题:图形界面能管理虚拟机开机,强制关机(一般不强制关系容易造成虚拟机系统出问题),但是不能控制虚拟机正常关机。
解决方法:
# yum install acpid
# service acpid start
# systemctl enable acpid.service(Centos7系列是这样)或者# chkconfig acpid on(Centos6是这样)
这是因为linux系统少一个服务:acpid(电源管理服务),导致宿主机无法对虚拟机进行正常的关机操作,只能强制关机。
第二个问题:用VNC方式光盘创建系统的时候,可能会出现鼠标找不到或者乱跑的现象导致你只能通过键盘来进行选项选择。
解决方法:
三、虚拟机的配置文件讲解
通过上图可以看到我们创建了两个虚拟机,宿主机就创建了两个虚拟网卡,我们的虚拟机是以进程的方式运行,这里就涉及到libvirt这个应用程序接口。
博文来自:www.51niux.com
3.1 libvirt简介
libvirt是目前使用最为广泛的对KVM虚拟机进行管理的工具和应用程序接口,而且一些常用的管理工具(如virsh、virt-install、virt-manager等)和云计算框架平台(如OpenStack、OpenNebula、Eucalyptus等)都在底层使用libvirt的应用程序接口。
从上图可以看出,libvirt作为中间使配层,让底层Hypervisor对上层用户空间的管理工具可以是完全透明的,因为libvirt屏蔽了底层各种Hypervisor的细节,为上层管理工具提供了一个统一的、较稳定的接口(API)。通过libvirt,用户空间管理工具可以管理各种不同的Hypervisor和上面运行的客户机。
libvirt的管理主要包含如下五个部分:
(1). 域管理。包括对域的各个生命周期的管理,如启动、停止等。也包括对各种设备类型的热插拔操作,包括磁盘、网卡、内存等。
(2). 远程节点的管理。只要物理节点上运行了libvirtd这个守护进程,远程的管理程序就可以连接到该节点进行管理操作。
(3). 存储的管理。任何运行了libvirtd守护进程的主机,都可以通过libvirt来管理不同类型的存储,对存储的管理也是支持远程管理的。
(4). 网络的管理,可以管理物理的和逻辑的网络接口。
(5). 提供一个稳定、可靠、高效的应用程序接口以便完成上面的4个管理功能。
libvirt由三部分组成:
(1). 应用程序编程接口库,为其他虚拟机管理工具(如virt-manager等)提供虚拟机管理的程序库支持。
(2). libvirtd守护进程,负责执行对节点上的域管理工作,一种是root权限的,权限较大可以完成所有支持的管理工作,一种是普通用户权限,能力受限制。
(3). 默认命令行管理工具:virsh。
3.2 libvirtd配置文件说明
# tree -L 2 /etc/libvirt/ #libvirt相关配置文件都在/etc/libvirt目录之中
/etc/libvirt/
|-- libvirt-admin.conf
|-- libvirt.conf #libvirt.conf 文件是用于配置一些常用 libvirt 连接
|-- libvirtd.conf # libvirt 的守护进程 libvirtd 的配置文件
|-- lxc.conf
|-- nwfilter
| |-- allow-arp.xml
| |-- allow-dhcp-server.xml
| |-- allow-dhcp.xml
| |-- allow-incoming-ipv4.xml
| |-- allow-ipv4.xml
| |-- clean-traffic.xml
| |-- no-arp-ip-spoofing.xml
| |-- no-arp-mac-spoofing.xml
| |-- no-arp-spoofing.xml
| |-- no-ip-multicast.xml
| |-- no-ip-spoofing.xml
| |-- no-mac-broadcast.xml
| |-- no-mac-spoofing.xml
| |-- no-other-l2-traffic.xml
| |-- no-other-rarp-traffic.xml
| |-- qemu-announce-self-rarp.xml
| `-- qemu-announce-self.xml
|-- qemu #目录下存放的是QEMU驱动的域的配置文件,如下面是两个域命名的xml文件
| |-- 192.168.1.101.xml
| |-- 192.168.1.102.xml
| `-- networks #保存了创建一个域时默认使用的网络配置
|-- qemu-lockd.conf
|-- qemu.conf #是libvirt对QEMU的驱动的配置文件
|-- storage #此目录里面记录了挂载storage的信息
| |-- ISO.xml
| |-- autostart
| |-- data01.xml
| |-- data02.xml
| `-- default.xml
|-- virtlockd.conf
`-- virtlogd.conf
配置文件实例:
(1). libvirt.conf 配置文件实例
# cat /etc/libvirt/libvirt.conf
uri_aliases = [
"100=qemu+ssh://root@192.168.1.100/system", #100是别名的形式,代表后面的远程连接方式,也可以字母别名
"130=qemu+ssh://root@192.168.1.130/system",
]
# service libvirtd reload #更改完重新加载
查看结果:
(2). libvirtd.conf 配置文件实例
# vi /etc/sysconfig/libvirtd #修改此配置文件用来启用tcp端口,将下面两句话的注释去掉
LIBVIRTD_CONFIG=/etc/libvirt/libvirtd.conf
LIBVIRTD_CONFIG=/etc/libvirt/libvirtd.conf
# vi /etc/libvirt/libvirtd.conf #修改守护进程文件,下面的配置文件模式都是注释状态,要修改并去掉
listen_tls = 0 #关闭TLS安全认证的连接(默认值是打开的)
listen_tcp = 1 #打开TCP连接(默认是关闭TCP连接)
tcp_port = "16666" #设置TCP监听的端口
listen_addr = "192.168.1.130" #监听IP
unix_sock_dir = "/var/run/libvirt" #sock的保存目录
auth_tcp = "none" #不使用认证授权方式
注:
要让TCP、TLS等连接生效,需要在启动libvirtd时加上--listen参数(简写为-l),默认的启动命令启动时候没有带--listen参数,所以如果不修改/etc/sysconfig/libvirtd 配置文件的话,启动方式应该为:# libvirtd --listen -d(先要关闭libvirtd服务:/etc/init.d/libvirtd stop)
查看结果:
# virsh -c qemu+tcp://192.168.1.130:16666/system
Welcome to virsh, the virtualization interactive terminal.
Type: 'help' for help with commands
'quit' to quit
virsh # list
Id Name State
----------------------------------------------------
(3). 虚拟机域的XML配置文件,这里以我们定义的第一台虚拟机192.168.1.101举例(所有有效的配置都在<domain>和</domain>标签之间,这表明该配置文件是一个域的配置。XML文档中注释在两个特殊的标签之间,如<!--注释-->。通过libvirt启动虚拟机,经过文件解析和命令参数的转换,最终也会调用qemu-kvm命令行工具来实际完成客户机的创建。)
# vi /etc/libvirt/qemu/192.168.1.101.xml
<!--
WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
OVERWRITTEN AND LOST. Changes to this xml configuration should be made using:
virsh edit 192.168.1.101
or other application using the libvirt API.
-->
<domain type='kvm'> #虚拟机类型kvm,可以为xen、kvm、qemu等,另一个是id,其值是一个数字用于在该宿主机的libvirt中唯一标识一个运行着的客户机,如果不设置id属性,libvirt会按顺序分配一个最小的可用ID。
<name>192.168.1.101</name> #虚拟机名称
<uuid>2e9d1632-86fd-406a-86f5-7decbe8afc1d</uuid> #虚拟机的uuid
<memory unit='KiB'>2097152</memory> #虚拟机的内存,即可以使用的最大内存
<currentMemory unit='KiB'>2097152</currentMemory> #虚拟机的启动时候分配给虚拟机的内存,一般跟上面一致
<vcpu placement='static'>2</vcpu> #cpu的个数,2表示有两个
<os> #os标签定义了客户机系统类型及其启动顺序
<type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type> #客户机类型是HVM,硬件虚拟化,操作系统架构是x86_64,rhel7.0.0宿主机系统
<boot dev='hd'/> #硬盘启动,hd代表硬盘
</os>
<features> #features标签表示Hypervisor为客户机打开或关闭CPU或其他硬件的特性,这里打开了ACPI、APIC、PAE 等特性。pae:扩展物理地址模式,使32位的客户端支持大于4GB的内存 。acpi:用于电源管理。 hap:启用硬件辅助分页(如果在硬件中可用)
<acpi/>
<apic/>
</features>
<cpu mode='custom' match='exact'>
<model fallback='allow'>IvyBridge</model>
</cpu>
<clock offset='utc'> #客户端的时间初始化来自宿主机的时间,大多数操作系统期望硬件时钟保持UTC格式,UTC也是默认格式,然而Windows机器却期望它是'localtime'(当引导时客户端时钟同步到主机时钟所在的时区)。
<timer name='rtc' tickpolicy='catchup'/>
<timer name='pit' tickpolicy='delay'/>
<timer name='hpet' present='no'/>
</clock>
<on_poweroff>destroy</on_poweroff> #当客户端请求poweroff时执行特定的动作
<on_reboot>restart</on_reboot> #当客户端请求reboot时执行特定的动作
<on_crash>restart</on_crash> #当客户端崩溃时执行的动作
每种状态下可以允许指定如下四种行为:
destory:domain将会被完全终止,domain的所有资源会被释放
restart:domain会被终止,然后以相同的配置重新启动
preserver:domain会被终止,它的资源会被保留用来分析
rename-restart:domain会被终止,然后以一个新名字被重新启动
<pm>
<suspend-to-mem enabled='no'/>
<suspend-to-disk enabled='no'/>
</pm>
<devices>
<emulator>/usr/libexec/qemu-kvm</emulator> #emulator标签中配置模拟器的绝对路径。
<disk type='file' device='disk'> #disk标签是虚拟机磁盘配置主标签,type属性表示磁盘使用哪种类型作为磁盘来源,值为file、block、dir或network
<driver name='qemu' type='qcow2'/> #name属性用于指定宿主机中使用后端驱动名称,KVM仅支持name='quemu',但type类型可以很多种。
<source file='/KVM/data01/192.168.1.101.img'/> #磁盘的来源,因为前面type=file了所以这里是名称,如果设置为block,这里应该是/dev/sdb
<target dev='vda' bus='virtio'/> #target表示将磁盘暴露给客户机时的总线类型和设备名称。dev属性表示在虚拟机中该磁盘设备的逻辑设备名称,而bus属性表示该磁盘被模拟挂载的总线类型,bus属性的值可以为ide,scsi,sata,virtio等。如果省略了bus属性,libvirt则会根据dev属性中的名称来推测bus属性的值,例如,sda会被推测是scsi,而vda被推测为virtio
<address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> #磁盘设备在客户机中的PCI地址,如果标签不存在,libvirt自动分配一个地址。
</disk>
<disk type='file' device='cdrom'>
<driver name='qemu' type='raw'/>
<target dev='hdb' bus='ide'/>
<readonly/>
<address type='drive' controller='0' bus='0' target='0' unit='1'/>
</disk>
<controller type='usb' index='0' model='ich9-ehci1'> #libvirt默认会为虚拟机模拟一些不要的PCI控制器(而不需要再XML配置文件中指定),而一些PCI控制器需要显式的在XML配置文件中配置。在虚拟机中执行lspci可以看到。
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x7'/>
</controller>
<controller type='usb' index='0' model='ich9-uhci1'>
<master startport='0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0' multifunction='on'/>
</controller>
<controller type='usb' index='0' model='ich9-uhci2'>
<master startport='2'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x1'/>
</controller>
<controller type='usb' index='0' model='ich9-uhci3'>
<master startport='4'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x2'/>
</controller>
<controller type='pci' index='0' model='pci-root'/>
<controller type='ide' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
</controller>
<controller type='virtio-serial' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
</controller>
<interface type='bridge'> #表示使用桥接方式
<mac address='52:54:00:97:31:d7'/> #虚拟机的mac地址
<source bridge='br0'/> #使用宿主机的br0网络接口来建议网桥
<model type='virtio'/> #表示虚拟机中使用virtio-net驱动的网卡设备
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> #网卡再虚拟机中pci设备编号为:0000:00:03.0
</interface>
<serial type='pty'> #串口的配置,type为pty,使用宿主机中的伪终端(pty),由于没有指定哪个虚拟终端,libvirt会自己选择一个空闲的虚拟机终端,可以用<source path='/dev/pts/1'/>来明确使用哪个虚拟终端
<target port='0'/>
</serial>
<console type='pty'> #控制台的配置
<target type='serial' port='0'/> #控制台(console)配置在客户机中的类型为'serial',此时如果没有配置serial串口,则会将控制台的配置复制到串口配置中,如果已经配置了串口,则libvirt会将控制台的配置项忽略。为了让控制台能够与客户机狡猾,也需要在虚拟机上面配置将信息输出到串口。
</console>
<channel type='spicevmc'>
<target type='virtio' name='com.redhat.spice.0'/>
<address type='virtio-serial' controller='0' bus='0' port='1'/>
</channel>
<input type='mouse' bus='ps2'/> #input 输入设备,type是设备类型,mouse就是鼠标,ps2会让QEMU模拟PS2接口的鼠标
<input type='keyboard' bus='ps2'/>
<graphics type='spice' autoport='yes'>
<listen type='address'/>
<image compression='off'/>
</graphics>
<sound model='ich6'> #sound标签表示的是声卡配置,model属性表示模拟出来的声卡类型
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</sound>
<video> #video标签表示的是显卡配置
<model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/> #type表示模拟的显卡的类型,vram表示显卡的显卡容量(单位为KB),heads表示显卡屏幕的序号
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<redirdev bus='usb' type='spicevmc'>
<address type='usb' bus='0' port='1'/>
</redirdev>
<redirdev bus='usb' type='spicevmc'>
<address type='usb' bus='0' port='2'/>
</redirdev>
<memballoon model='virtio'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
</memballoon>
</devices>
</domain>
博文来自:www.51niux.com
3.3 添加虚拟机开机自启动
一般如果不设置,当我们宿主机因为断电等原因关机启动后,我们的虚拟机是不启动的,需要手工开机操作,如果我们希望在宿主机断电重启之后,虚拟机也能自行启动的话,需要做下面的操作。
# virsh list --all #查看一下我们现在又三个域,而且三个都是在运行状态
Id Name State
----------------------------------------------------
5 192.168.1.101 running
6 192.168.1.102 running
7 192.168.1.103 running
# virsh autostart 192.168.1.101 #virsh 后面跟autostart参数 后面跟虚拟机的域
Domain 192.168.1.101 marked as autostarted
# pwd #现在我们所在的目录为:/etc/libvirt/qemu
/etc/libvirt/qemu
# ll
total 20
-rw-------. 1 root root 4081 Jan 3 19:55 192.168.1.101.xml
-rw-------. 1 root root 4439 Jan 4 10:44 192.168.1.102.xml
-rw-------. 1 root root 4439 Jan 5 10:20 192.168.1.103.xml
drwxr-xr-x. 2 root root 30 Jan 5 10:24 autostart #新增了一个autostart 目录
drwx------. 3 root root 52 Jan 4 11:08 networks
# ls -l autostart/ #autostart目录是kvm虚拟机开机自启动目录,可以看到该目录中有KVM配置文件链接。
total 0
lrwxrwxrwx. 1 root root 35 Jan 5 10:24 192.168.1.101.xml -> /etc/libvirt/qemu/192.168.1.101.xml
下面我们将宿主机重启,看下效果,是否设置192.168.1.101的虚拟机能启动起来:
#从上图看192.168.1.101已经可以开机自启动了
四、虚拟机的的串口和控制台配置
有的时候我们可能需要通过图形界面的方式来操作服务器,如服务器是windows机器,或者我们需要通过光盘或者PXE的方式安装虚拟机,或者虚拟机初始化后我们需要上去进行一些网卡之类的配置,或者虚拟机网络问题连不上了,那我们我们可以通过vnc的方式来进行连接,但是又不能每次去操作某一台虚拟机就要宿主机开启vnc进行操作,那么怎么设置之后,不用登陆宿主机也可以对虚拟机进行远程操作呢?
4.1 虚拟机的控制台配置设置
方法一:
# virsh edit 192.168.1.102 #修改域192.168.1.102的配置文件,在 </devices>父标签里面机上下面这句话:
<graphics type='vnc' port='5910' autoport='no' listen='0.0.0.0' keymap='en-us' passwd='12345678'> #port是虚拟机vnc端口,keymap是映射键盘语言,passwd后面是vnc的密码可以不加。autoport='no'不自己分配端口
<listen type='address' address='0.0.0.0'/>
</graphics>
方法二:可以通过宿主机的VNC界面对虚拟机进行vnc的添加操作:
注:但是不管哪种操作都需要重启虚拟机的时候才能生效,所以如果要设置最好在创建虚拟机的时候就设置好。
让我们查看一下结果:
然后你会发现当你打开虚拟机的VNC的时候,明明连接成功了,但是VNC窗口一闪就消失了。
解决办法:
依次打开vnc客户端--->依次点击option--->Advanced--->Expert--->找到ColourLevel,默认的值是pal8,修改为rgb222或full. 如下图:
#注vnc连接的IP是宿主机的IP地址,端口则是我们设置的虚拟机的vnc端口。
下面让我们再次查看一下结果:
# vncserver -list #在宿主机上面查看一下并没有vnc端口启动
TigerVNC server sessions:
X DISPLAY # PROCESS ID
因为宿主机上面还有其他的虚拟机,而且宿主机老开着vnc显然不合适,所以如果你想通过远程vnc的形式操作虚拟机的话,可以给虚拟机单配vnc的方式,来通过vnc来管理机器装机啊或者其他什么操作。
4.2 宿主机通过Console口管理虚拟机的设置
上面说的vnc的方式,可能我们需要依赖于图形界面进行操作,如果虚拟机vnc连接不过去或者我们不想通过vnc这种形式连接,又或者虚拟机可能并没有死机但是网络不通了呢,等等情况,所以我们需要另一种形式,Console口管理
虚拟机是Centos6系列上面的操作:
第一步:
# sed -i 's#quiet#quiet console=ttyS0#' /etc/grub.conf #通过为内核传递参数 console=ttyS0,来让内核把输出定向至 ttyS0.
第二步:
# echo "S0:12345:respawn:/sbin/agetty ttyS0 115200" >> /etc/inittab #通过在 inittab 里加一个 ttyS0 ,来使得系统启动时能够生成一个 ttyS0 来接收来自内核的数据
第三步:
# echo "ttyS0" >> /etc/securetty #由于 /etc/securetty 文件允许你规定 root 用户可以从哪个 TTY 设备登录,因此我们需要添加 ttyS0 的安全许可,即将 ttyS0 添加至该文件,来允许我们的 root 用户登录。
第四步:
重启虚拟机,重启才能生效,所以这里也是创建虚拟机的时候就创建好
我们对我们的域192.168.1.101进行了操作,下面我们看一下操作结果:
# virsh console 192.168.1.101 #为操作命令,virsh console参数 要登录的域
#记住一定要先exit退出操作系统,然后按下Crtl+] 来退出console窗口
虚拟机是Centos7系列上面的操作:
# cat /etc/redhat-release #查看操作系统版本
CentOS Linux release 7.2.1511 (Core)
# grubby --update-kernel=ALL --args="console=ttyS0" #执行命令
# reboot #重启操作系统
再次查看结果,也是可以的,这里就不截图了。
五、virtio网卡中断与多队列的创建
网卡中断:
X86体系结构的计算机采用中断机制来协同处理与其他设备的工作。当一台设备需要与处理器通信时,就会向处理器发出一个中断信号。
以网卡威力,当网卡接收到数据包时会产生中断,通知内核有新数据包,然后内核调用中断处理程序进行响应。把数据包从网卡缓存复制到内存。因为网卡缓存大小有限,不及时复制出数据的话,后续数据包将会因为缓存溢出而被丢弃,因此这一工作需要立即完成。剩下的处理和操作数据包的工作就会交给软中断。
高负载网卡是软中断产生的大户,在相当长的时期内网卡中断都是通过CPU 0来处理的。造成CPU 0的压力很高、其他CPU 相对空闲的情况。多网卡队列就是将网卡的数据请求通过多个CPU处理。多队列网卡可以将每个队列产生的中断分布到CPU的多个核,实现负载均衡,避免单个核被占用过高、而其他核还处于空闲的情况。多队列网卡的每个队列的中断都使用单独的中断线。
Centos系统依靠irqbalance服务优化中断分配,它会自动收集系统数据以分析使用模式,并依据系统负载情况将工作状态置于Performance mode(将中断均匀的发给各个CPU core)或Power-save mode(将中断集中分配给第一个CPU,以保证其他空闲CPU的睡眠时间降低能耗)。此服务在大压力情况下,尤其是万兆网卡上,有中断漂移及分配不平衡的现象。如果压力比较大,可以手工调整系统的网卡中断。用网卡绑定中断脚本需要关闭此服务。
# mpstat -P ALL #观察服务器CPU情况
Linux 3.10.0-514.2.2.el7.x86_64 (localhost.localdomain) 02/20/17 _x86_64_ (12 CPU)
14:34:17 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
14:34:17 all 0.89 0.00 0.25 0.06 0.00 0.00 0.00 0.21 0.00 98.58
14:34:17 0 1.18 0.01 0.44 0.08 0.00 0.00 0.00 0.38 0.00 97.91
14:34:17 1 1.28 0.01 0.34 0.06 0.00 0.00 0.00 0.29 0.00 98.02
%usr: 表示处理用户进程所使用的的CPU的百分比
%nice: 表示使用nice命令影响的用户进程所使用的CPU的百分比,nice值可以影响进程的优先级
%sys:表示内核进程使用的CPU百分比。
%iowait: 表示等待I/O使用的CPU百分比。
%irq: 表示处理中断使用的CPU百分比。
%soft: 表示处理软中断使用的CPU百分比。
%guest: 表示虚拟机消耗的CPU百分比
%idle: 表示CPU空闲的百分比
多队列Virtio网卡:
# ls /sys/class/net/p5p1/queues/ #RSS是网卡的硬件特性,实现多队列,将不同的流分发到不同的CPU上,同一数据流始终在同一CPU上。如果服务器的网卡支持RSS,会看到网卡对应多个发送和接收队列。
rx-0 rx-1 rx-10 rx-11 rx-2 rx-3 rx-4 rx-5 rx-6 rx-7 rx-8 rx-9 tx-0 tx-1 tx-10 tx-11 tx-2 tx-3 tx-4 tx-5 tx-6 tx-7 tx-8 tx-9
目前的高端服务器都有多个处理器,虚拟使用的虚拟CPU数目也不断增加。默认的 virtio-net 不能并行地传送或者接收网络包,因为 virtio_net 只有一个TX 和 RX 队列。而多队列 virtio-net 提供了一个随着虚机的虚拟CPU增加而增强网络性能的方法,通过使得 virtio 可以同时使用多个 virt-queue 队列。
centos 7开始支持virtio网卡多队列,可以大大提高虚拟机网络性能。
它在以下情况下具有明显优势:
网络流量非常大
虚机同时有非常多的网络连接,包括虚拟机之间的、虚机到主机的、虚机到外部系统的等
virtio 队列的数目和虚机的虚拟CPU数目相同。这是因为多队列能够使得一个队列独占一个虚拟CPU。
注意:对队列 virtio-net 对流入的网络流工作得非常好,但是对外发的数据流偶尔会降低性能。打开对队列 virtio 会增加中的吞吐量,这相应地会增加CPU的负担。 在实际的生产环境中需要做必须的测试后才确定是否使用。
下面是操作步骤:
第一步:宿主机上面的操作
# virsh edit 192.168.1.103
<interface type='bridge'>
<mac address='52:54:00:55:32:3c'/>
<source bridge='br0'/>
<model type='virtio'/>
<driver name='vhost' queues='8'/> #加上了这句话,表示我们开启8个队列网卡,N 1-8,最多支持8个队列
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
第二步:虚拟机上面的操作(测试虚拟机是Centos6.8版本是支持的,Centos6.4的版本不生效):
# echo '/usr/sbin/ethtool -L eth0 combined 8' >>/etc/rc.d/rc.local #将要执行的命令添加到开机自启动里面 ,Centos6.8为# echo '/sbin/ethtool -L eth0 combined 8' >>/etc/rc.local
# chmod +x /etc/rc.d/rc.local #Centos7系列的版本,要对这个文件授权,开机启动才能生效
然后要对虚拟机进行shutdown那种类似于断电的操作,再启动虚拟机,才能生效
现在我们对虚拟机进行了shutdown操作,又通过宿主机将192.168.1.103虚拟机启动起来了,再次查看:
# ethtool -l eth0
Channel parameters for eth0:
Pre-set maximums:
RX: 0
TX: 0
Other: 0
Combined: 8
Current hardware settings:
RX: 0
TX: 0
Other: 0
Combined: 8