KVM是指基于Linux内核的虚拟机(Kernel-base Virtual Machine),在KVM模型中,每一个虚拟机都是一个由Linux调度程序管理的标准进程,你可以在用户空间启动客户机操作系统,一个普通的Linux进程有两种运行模式:内核和用户,KVM增加了第三种模式:客户模式(有自己的内核和用户模式)

KVM虚拟机的管理工具
准确的来说,KVM仅仅是Linux内核的一个模块,管理和创建完整的KVM虚拟机,需要更多的辅助工具
QEMU-KVM:在Linux系统中,首先我们可以用modprobe命令加载KVM模块,如果用RPM安装KVM软件包,系统会在启动时自动加载模块,QEMU是一个强大的虚拟软件,它可以虚拟不同的构架
Virt-manager:尽管QEMU-KVM工具可以创建和管理KVM虚拟机,RedHat为KVM开发了更多的辅助工具,比如 libvirt libguestfs等,原因是QEMU工具效率不高,不易于使用

安装前准备

首先需要CPU支持虚拟化功能(VT-X/AMD-V)并开启,如果机器支持虚拟化需要在BIOS开启。如有有,把Virtualization Technology这个功能打开即可

环境:
   Centos 6.6

清除iptables规则和Selinux

1
2
3
4
5
[root@localhost ~]# /etc/init.d/iptables status
iptables: Firewall is not running.
[root@localhost ~]# getenforce
Disabled
[root@localhost ~]#

检查你的系统是否支持虚拟化。如果有输出内容,则支持,其中intel cpu支持会有vmx,amd cpu支持会有svm

1
2
3
4
[root@localhost ~]# grep -Ei 'vmx|svm' /proc/cpuinfo
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov
pat pse36 clflush dts mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc up arch_perfmon pebs bts xtopology tsc_reliable nonstop_tsc aperfmperf unfair_spinlock pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm ida arat epb xsaveopt pln pts dts tpr_shadow vnmi ept vpid fsgsbase bmi1 avx2 smep bmi2 invpcid
[root@localhost ~]#

注:我这里使用的是Vmware Workstation,如果本身机器支持并开启了,但这里还是查不到。需要检查vmware虚拟机是否开启了虚拟化功能
vmware_vmset

安装KVM虚拟机

1
[root@localhost ~]# yum -y install kvm python-virtinst libvirt libvirt-client bridge-utils virt-manager qemu-kvm qemu-kvm-tools virt-viewer virt-v2v avahi dmidecode tunctl

说明:
kvm:软件包中含有KVM内核模块,它在默认linux内核中提供kvm管理程序
libvirts:安装虚拟机管理工具,使用virsh等命令来管理和控制虚拟机
bridge-utils:设置网络网卡桥接
virt-*:创建、克隆虚拟机命令,以及图形化管理工具virt-manager
qemu-img:安装qemu组件,使用qemu命令来创建磁盘等

1
2
3
4
5
6
7
[root@localhost ~]# /etc/init.d/libvirtd restart
[root@localhost ~]# /etc/init.d/messagebus restart
[root@localhost ~]# /etc/init.d/avahi-daemon restart
[root@localhost ~]# chkconfig libvirtd on
[root@localhost ~]# chkconfig messagebus on
[root@localhost ~]# chkconfig avahi-daemon on

检查KVM模块是否加载:

1
2
3
4
5
#如果没有加载KVM模块,执行下modprobe kvm-intel试试,如果还不行,就重启下
[root@localhost ~]# lsmod |grep kvm
kvm_intel 55496 0
kvm 337772 1 kvm_intel
[root@localhost ~]#

1
2
3
4
5
6
7
8
9
[root@localhost ~]# virsh list --all
Id Name State
----------------------------------------------------
[root@localhost ~]# virt-install --version
0.600.0
[root@localhost ~]# virsh --version
0.10.2
[root@localhost ~]#

KVM网络配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@localhost ~]# cd /etc/sysconfig/network-scripts/
[root@localhost network-scripts]# cp ifcfg-eth0 ifcfg-br0
[root@localhost network-scripts]# cat ifcfg-br0
DEVICE=br0
TYPE=Bridge
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=static
IPADDR=192.168.1.160
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
DNS1=114.114.114.114
[root@localhost network-scripts]#
[root@localhost network-scripts]# cat ifcfg-eth0
DEVICE=eth0
HWADDR=00:0C:29:BA:C8:85
TYPE=Ethernet
UUID=9f21503e-9a56-4f7c-97dc-4516fb960816
ONBOOT=yes
NM_CONTROLLED=no
BOOTPROTO=none
BRIDGE=br0
[root@localhost network-scripts]# /etc/init.d/network restart

查看网络接口列表

1
2
3
4
5
[root@localhost ~]# brctl show
bridge name bridge id STP enabled interfaces
br0 8000.000c29bac885 no eth0
virbr0 8000.52540045e79f yes virbr0-nic
[root@localhost ~]#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@localhost ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP ql
en 1000 link/ether 00:0c:29:ba:c8:85 brd ff:ff:ff:ff:ff:ff
inet6 fe80::20c:29ff:feba:c885/64 scope link
valid_lft forever preferred_lft forever
3: virbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOW
N link/ether 52:54:00:45:e7:9f brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 500
link/ether 52:54:00:45:e7:9f brd ff:ff:ff:ff:ff:ff
6: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
link/ether 00:0c:29:ba:c8:85 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.160/24 brd 192.168.5.255 scope global br0
inet6 fe80::20c:29ff:feba:c885/64 scope link
valid_lft forever preferred_lft forever
[root@localhost ~]#
1
2
3
4
5
6
7
8
9
10
11
[root@localhost ~]# mkdir -p /kvm_data/{iso,system}
[root@localhost ~]# ls /kvm_data/iso/ #安装镜像放这里
CentOS-6.6-x86_64-bin-DVD1.iso
[root@localhost ~]#
#制作虚拟机镜像
[root@localhost ~]# mkdir -p /kvm_data/system/centos6_1
[root@localhost ~]# cd /kvm_data/system/centos6_1/
[root@localhost centos6_1]# qemu-img create -f qcow2 centos6_1.qcow2 30G
Formatting 'centos6_1.qcow2', fmt=qcow2 size=32212254720 encryption=off cluster_size=65536
[root@localhost centos6_1]#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#模版demo_template.xml
[root@localhost ~]# cat /kvm_data/demo_template.xml
<domain type='kvm'>
<name>centos6</name> //虚拟机名称
<uuid>77a83ddb-5ac8-43c3-be22-f8e7156d5784</uuid>
<memory>524288</memory> //最大内存,单位kb
<currentMemory>524288</currentMemory> //可用内存,单位kb
<vcpu>1</vcpu> //虚拟cpu个数
<os>
<type arch='x86_64' machine='pc'>hvm</type>
<boot dev='hd'/> //从硬盘启动
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<clock offset='localtime'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/libexec/qemu-kvm</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/kvm_data/system/centos6_1/centos6_1.qcow2'/> //目的镜像路径
<target dev='hda' bus='ide'/>
</disk>
<disk type='file' device='cdrom'>
<source file='/kvm_data/iso/CentOS-6.6-x86_64-bin-DVD1.iso'/> //光盘镜像路径
<target dev='hdb' bus='ide'/>
</disk>
<interface type='bridge'> //虚拟机网络连接方式
<source bridge='br0'/> //当前主机网桥的名称
<mac address="00:16:00:1e:5a:0d"/> //为虚拟机分配mac地址,务必唯一,否则dhcp获得同样ip,引起冲突
</interface>
<input type='mouse' bus='ps2'/>
<graphics type='vnc' port='-1' autoport='yes' listen = '0.0.0.0' keymap='en-us'/>//vnc方式登录,端口号自动分配,自动
加1,可以通过virsh vncdisplay来查询 </devices>
</domain>
[root@localhost ~]#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#复制模版demo_template.xml
[root@localhost centos6_1]# cp /kvm_data/demo_template.xml ./centos6_1.xml
[root@localhost centos6_1]# ls
centos6_1.qcow2 centos6_1.xml
[root@localhost centos6_1]#
#定义虚拟机,define告诉libvirt,要被libvirt管理
[root@localhost centos6_1]# virsh define centos6_1.xml
Domain centos6 defined from centos6_1.xml
[root@localhost centos6_1]# virsh list --all
Id Name State
----------------------------------------------------
- centos6 shut off
[root@localhost centos6_1]#
#启动虚拟机
[root@localhost centos6_1]# virsh start centos6
Domain centos6 started
#查看虚拟机vnc端口
[root@localhost centos6_1]# virsh vncdisplay centos6
:0
[root@localhost centos6_1]#
#安装vncviewer和xhost用于图形化安装Linux系统
[root@localhost ~]# yum -y install tigervnc xhost
[root@localhost ~]# export DISPLAY=192.168.1.105:0.0
#需要打开Xmanager - Passive
[root@localhost ~]# xhost +
[root@localhost ~]# vncviewer 192.168.1.160:0

接下来开始安装系统(略)
kvm_install
kvm_install

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#kvm虚拟机安装成功
[root@localhost ~]# virsh list --all
Id Name State
----------------------------------------------------
2 centos6 running
[root@localhost ~]# virsh autostart centos6 #设定kvm虚拟机开机自启
Domain centos6 marked as autostarted
[root@localhost ~]# qemu-img info /kvm_data/system/centos6_1/centos6_1.qcow2
image: /kvm_data/system/centos6_1/centos6_1.qcow2
file format: qcow2
virtual size: 30G (32212254720 bytes)
disk size: 2.1G
cluster_size: 65536
[root@localhost ~]#

1
2
3
4
5
6
7
[root@localhost ~]# ll /var/lib/libvirt/qemu
total 12
srwxr-xr-x 1 qemu qemu 0 May 14 11:41 centos6.monitor #这里的文件,是libvirtd在重启后,虚拟机也随着自动重启
drwxr-xr-x 2 root root 4096 May 14 11:05 dump
drwxr-xr-x 2 qemu qemu 4096 May 14 11:05 save
drwxr-xr-x 2 qemu qemu 4096 May 14 11:05 snapshot
[root@localhost ~]#
1
2
3
4
5
6
7
#动态查询kvm资源占用情况,每一台VM,对应一个qemu-kvm进程
[root@localhost ~]# top -d 1 | grep kvm
2601 qemu 20 0 796m 530m 3928 S 1.0 28.5 5:27.72 qemu-kvm
2601 qemu 20 0 796m 530m 3928 S 1.0 28.5 5:27.73 qemu-kvm
2601 qemu 20 0 796m 530m 3928 S 1.0 28.5 5:27.74 qemu-kvm
[root@localhost ~]#

部署多台KVM虚拟机

  1. 使用qemu-img创建虚拟机镜像
  2. 拷贝demo_template.xml模版配置文件并修改里的参数,如:UUID/MASK地址/镜像存储位置/ISO镜像目录等
  3. virsh define vm_name和virsh start vm_name即可

常见问题解决办法

如果报这个错,把NetworkManager服务关掉就OK了,因为和桥接有冲突

1
Bringing up interface br0: Error: Connection activation failed: Failed to determine connection's virtual interface name

如果出现下面的错误,需要安装一个avahi软件

1
ERROR Failed to connect socket to '/var/run/libvirt/libvirt-sock': No such file or directory

解决办法:

1
2
3
4
[root@localhost ~]# yum -y install avahi
[root@localhost ~]# /etc/init.d/messagebus restart
[root@localhost ~]# /etc/init.d/avahi-daemon restart
[root@localhost ~]# /etc/init.d/libvirtd restart

如果报这个错,表示disk path选项中的size指定的值大于当前实际磁盘空间

1
2
WARNING The filesystem will not have enough free space to fully allocate the sparse file when the guest is running. 6144
0 M requested > 42184 M available

如果报这个错,是因为存在相同名字的虚拟机,即使删掉虚拟机的配置文件也会报这个错
kvm和xen不同,xen的半虚拟化要想重装,只要把创建好的虚拟机配置文件删掉就可以了,kvm如果想要重装相同名字的虚拟机,只需要在虚拟机停止的状态下执行如下命令

1
ERROR Guest name 'Kvm_centos6.6' is already in use.

解决办法:

1
2
3
4
5
6
[root@localhost ~]# virsh destroy Kvm_centos6.6
Domain Kvm_centos6.6 destroyed
[root@localhost ~]# virsh undefine Kvm_centos6.6
Domain Kvm_centos6.6 has been undefined
[root@localhost ~]#

如果出现下面的错误,

1
kvm cpu0 disabled perfctr wrmsr 0xc1 data 0xabcd

KVM常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
#virsh -c qemu:///system list
#virsh list
#virsh list --all //查看所有状态的虚拟机
#virsh shutdown myWin7 //关闭myWin7虚拟机
#virsh destroy myWin7 //删除myWin7虚拟机
#virsh start node4 //开机虚拟机
#virsh define /etc/libvirt/qemu/node5.xml #根据主机配置文档添加虚拟机
#virsh dumpxml node4 > /etc/libvirt/qemu/node6.xml //将node4虚机的配置文件保存至node6.xml
#virsh edit node6 //修改node6的配置文件
#virsh suspend vm_name //暂停虚拟机
#virsh resume vm_name //恢复虚拟机
Kvm配置文件路径 :
/etc/libvirtd/qemu/***.xml 可以通过vim对配置文件进行管理,编辑后需要#service libvirtd restart(不会对现有VM有影响)

其他问题

  1. 图形化配置:从菜单中启动,或者运行virt-manager进入图形管理界面,比较简单,不过img的位置需要注意一下,kvm安装后会有一个默认位置,不注意的话容易占满空间。或者直接硬盘分区时单独给/var分一个区
  2. 虚拟机重新配置:
    虚拟机的配置文件保存在/etc/libvirt/qemu目录下,扩展名是xml。修改相应的文件即可重新配置虚拟机
  3. 虚拟机备份及恢复:
    备份:拷贝/etc/libvirt/qemu目录下的xml配置文件,以及xml中设置的img文件
    恢复:进入virsh,执行define 目录下的xml文件路径

    1
    2
    [root@localhost ~]# virsh
    virsh # define /etc/libvirt/qemu/winxp.xml
  4. 开机自动启动虚拟机:

    1
    [root@vfeelit qemu]# virsh autostart Winxp
  5. 克隆KVM虚拟机:

    1
    [root@vfeelit ~]# virt-clone -o Winxp -n winxpclong -f /var/lib/libvirt/images/winxpclong.img

(-o 原始客体的名称,-n新客户端的名称,-f作为新客户端磁盘映像的新文件)

  1. 虚拟机意外关机报下述错误:
    1
    2
    3
    [root@vfeelit qemu]# virsh start winxp
    错误:开始域 winxp 失败
    错误:Unable to read from monitor: Connection reset by peer

解决方法:

1
virsh managedsave-remove winxp

Virsh语法参考

命令 解释
Autostart 自动开始一个域
Create 从一个XML文件创建一个域
Define 从一个XML文件定义(但不开始)一个域
edit 编辑某个域的 XML 配置
shutdown 关闭一个域
start 开始一个(以前定义的)非活跃的域
reboot 重新启动一个域
suspend 挂起一个域
resume 重新恢复一个域
vncdisplay vnc 显示

使用save来备份当前虚拟机的状态

1
2
3
4
5
6
7
8
9
10
[root@localhost ~]# virsh save --bypass-cache centos6 /var/lib/libvirt/images/test_centos6 --running
Domain centos6 saved to /var/lib/libvirt/images/test_centos6
[root@localhost ~]#
[root@localhost ~]# virsh list
Id Name State
----------------------------------------------------
[root@localhost ~]#

这个命令将Kvm_centos6.6的当前状态保存到/var/lib/libvirt/images/文件中。–running参数表示下次restore回来的时候能够自动启动RedHat,这个命令会导致RedHat被关闭
现在还原:必须先关闭虚拟机

1
2
3
4
5
6
7
8
[root@localhost ~]# virsh restore /var/lib/libvirt/images/test_centos6 --bypass-cache --running (还原时不要指定虚拟机名称)
[root@localhost ~]# virsh list --all
Id Name State
----------------------------------------------------
6 centos6 running
[root@localhost ~]#

附件:
demo_template.xml


本文出自”Jack Wang Blog”:http://www.yfshare.vip/2017/05/14/部署KVM虚拟机/