一、简介
虚拟化是指计算机组件在虚拟的基础上而不是在真实的基础上运行,虚拟化技术可以扩大硬件的容量,简化软件的重新配置过程,允许一个平台同时运行多个操作系统,并且应用程序都可在相互独立的空间运行而相互不影响彼此,从而提高计算机的运行效率。KVM是一个开源的虚拟化软件,英文名为kernel-base virtual machine,基于内核的虚拟机,KVM在2007年2月被导入Linux 2.6.20核心中,以可加载核心模块的方式被移植到FreeBSD上。
虚拟化技术分类:
主机虚拟化:完全虚拟化(KVM)、半虚拟化(XEN)
用户空间虚拟化:LXC,OPENVZ
应用程序虚拟化:JVM
![1.png wKiom1hNBdXyGY7xAAEP_ZkZ-Qk054.png]()
![2.png wKioL1hNBsCTnqjhAAPbZ4PpAj0608.png]()
![d.png wKiom1hNBEDC3STlAAAPkHCoQJQ086.png]()
KVM相关简介:
KVM是开源软件,全称是kernel-based virtual machine(基于内核的虚拟机)。
是x86架构且硬件支持虚拟化技术(如 intel VT 或 AMD-V)的Linux全虚拟化解决方案。
它包含一个为处理器提供底层虚拟化 可加载的核心模块kvm.ko(kvm-intel.ko或kvm-AMD.ko)。
KVM还需要一个经过修改的QEMU软件(qemu-kvm),作为虚拟机上层控制和界面。
KVM能在不改变linux或windows镜像的情况下同时运行多个虚拟机,(它的意思是多个虚拟机使用同一镜像)并为每一个虚拟机配置个性化硬件环境(网卡、磁盘、图形适配器……)。
在主流的Linux内核,如2.6.20以上的内核均已包含了KVM核心。
KVM 内存管理:
KVM 继承了 Linux 系统管理内存的诸多特性,比如,分配给虚拟使用的内存可以被交换至交换空间、能够使用大内存页以实现更好的性能,以及对 NUMA 的支持能够让虚拟机高效访问更大的内存空间等。
KVM 基于 Intel 的 EPT ( ExtendedPage Table )或 AMD 的 RVI ( Rapid Virtualization Indexing )技术可以支持更新的内存虚拟功能,这可以降低 CPU 的占用率,并提供较好的吞吐量。
此外,KVM 还借助于 KSM ( Kernel Same-pageMerging )这个内核特性实现了内存页面共享 。 KSM 通过扫描每个虚拟机的内存查找各虚拟机间相同的内存页,并将这些内存页合并为一个被各相关虚拟机共享的单独页面。在某虚拟机试图修改此页面中的数据时, KSM 会重新为其提供一个新的页面副本。实践中,运行于同一台物理主机上的具有相同 GuestOS 的虚拟机之间出现相同内存页面的概率是很的,比如共享库、内核或其它内存对象等都有可能表现为相同的内存页,因此, KSM 技术可以降低内存占用进而提高整体性能。
KVM组件:
/dev/kvm:管理虚拟机的设备节点,用户空间的程序可通过其ioctl()系统调用集来完成虚拟机的创建启动等管理工作;它是一个字符设备;其主要完成的操作包括:
qemu进程:工作于用户空间的组件,用于仿真PC机的I/O类硬件设备;
qemu全称Quick Emulator。是独立虚拟软件,能独立运行虚拟机(根本不需要kvm)。kqemu是该软件的加速软件。kvm并不需要qemu进行虚拟处理,只是需要它的上层管理界面进行虚拟机控制。虚拟机依旧是由kvm驱动。
二、KVM虚拟化安装
前提:
①确保cpu执行HVM
grep -E "(svm|vmx)" /proc/cpuinfo
②内核编译提供了KVM模块
modinfo kvm
[root@node1 ~]# grep -E "(vmx|svm)" /proc/cpuinfo #确保支持使用虚拟化
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl tsc_reliable nonstop_tsc aperfmperf pni pclmulqdq ssse3 fma cx16 sse4_1 sse4_2 x2apic popcnt aes xsave avx f16c hypervisor lahf_lm svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw xop fma4 tbm arat npt svm_lock nrip_save vmcb_clean flushbyasid decodeassists bmi1
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl tsc_reliable nonstop_tsc aperfmperf pni pclmulqdq ssse3 fma cx16 sse4_1 sse4_2 x2apic popcnt aes xsave avx f16c hypervisor lahf_lm svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw xop fma4 tbm arat npt svm_lock nrip_save vmcb_clean flushbyasid decodeassists bmi1
[root@node1 ~]#
[root@node1 ~]# modinfo kvm #确保存在此模块
filename: /lib/modules/3.10.0-327.el7.x86_64/kernel/arch/x86/kvm/kvm.ko
license: GPL
author: Qumranet
rhelversion: 7.2
srcversion: 13ED0467630AC8D418AB2C8
depends:
intree: Y
vermagic: 3.10.0-327.el7.x86_64 SMP mod_unload modversions
signer: CentOS Linux kernel signing key
sig_key: 79:AD:88:6A:11:3C:A0:22:35:26:33:6C:0F:82:5B:8A:94:29:6A:B3
sig_hashalgo: sha256
parm: ignore_msrs:bool
parm: min_timer_period_us:uint
parm: kvmclock_periodic_sync:bool
parm: tsc_tolerance_ppm:uint
parm: lapic_timer_advance_ns:uint
parm: halt_poll_ns:uint
[root@node1 ~]# ll /dev/kvm #虚拟主机节点管理
crw-rw-rw-+ 1 root kvm 10, 232 Dec 11 15:11 /dev/kvm
安装:
yum -y install libvirt virt-manager virt-viewer virt-install qemu-kvm
#其中libvirt提供虚拟化服务,其配置文件为/etc/libvirt/libvirt.conf,unit file:libvirtd.service
#以下为用户空降管理工具
virt-manager
virt-viewer
virt-install
#配置好后启动服务
systemctl start libvirtd.service
三、项目部署kvm虚拟化
在部署之前需准备配置环境:关闭网络管理,创建桥接接口,虚拟机网卡充当交换机的作用。
[root@node1 ~]# systemctl stop NetworkManager
[root@node1 ~]# virsh iface-bridge eno16777736 br0 -no-stp #配置成桥接接口
[root@node1 ~]# ifconfig
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.1.10.65 netmask 255.255.0.0 broadcast 10.1.255.255
inet6 fe80::20c:29ff:fe2e:3557 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:2e:35:57 txqueuelen 0 (Ethernet)
RX packets 694 bytes 57740 (56.3 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 101 bytes 13261 (12.9 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
#此时物理机接口就类似于交换机使用
eno16777736: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 00:0c:29:2e:35:57 txqueuelen 1000 (Ethernet)
RX packets 270458 bytes 37652584 (35.9 MiB)
RX errors 0 dropped 85 overruns 0 frame 0
TX packets 5761 bytes 826732 (807.3 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@node1 ~]#virt-manager #启动图形化界面创建虚拟机
图形化安装图示:
使用virsh-manager命令后将出现此图形界面,注意如未此命令需安装virt-manager程序包,需选择安装源。
![22.png wKiom1hNDZnDbFk3AACb6sAZpdI421.png]()
配置其内存大小及其cpu核心个数
![33.png wKioL1hNDZmj9MXDAAB9fEAzBoo299.png]()
设置主机名存储空间大小等配置
![44.png wKiom1hNDZnQsdx4AACXsliNjR4640.png]()
本过程使用已搭建好的cobbler自动化安装
![cobbler.png wKiom1hNDZrinyXuAABEmPavaYA757.png]()
![55.png wKioL1hNDZrDI2RQAABDZWB0hCc279.png]()
如下为在虚拟机中虚拟出一个虚拟机:
![66.png wKioL1hNDZrw7VNRAAA4MNdeqMI636.png]()
四、virsh命令使用及其实现虚拟磁盘扩容
virsh命令使用:
create:创建并启动域
domuuid:获取域的uuid
domid:获取域的id
dominfo:域的信息
reboot:重启域
destroy:关闭域
shutdown:关闭域
save:保存状态至某文件中
pause:暂停域
resume:恢复暂停的域
管理域的资源:
setmem:改变内存大小,不能超过装机时的最大值
setvcpus:修改域的vcpu数量
setmaxmem:设置内存最大值
vcpuinfo:显示vcpu的信息
实时修改内存大小:
[root@node1 ~]# virsh list #显示已创建的虚拟机,此处在虚拟机中运行着两台使用kvm虚拟化出来的虚拟机
Id Name State
----------------------------------------------------
3 centos6s running
4 centos6.6 running
[root@node1 ~]#
[root@node1 ~]# virsh vcpuinfo centos6.6 #查看其虚拟cup的状态信息
VCPU: 0
CPU: 0
State: running
CPU time: 0.2s
CPU Affinity: yy
VCPU: 1
CPU: 1
State: running
CPU time: 0.1s
CPU Affinity: yy
[root@node1 ~]# virsh dominfo
error: command 'dominfo' requires <domain> option
[root@node1 ~]# virsh dominfo centos6.6
Id: 4
Name: centos6.6
UUID: 9f12e96f-7bf4-469d-b3e8-79f7e1cf4eee
OS Type: hvm
State: running
CPU(s): 2
CPU time: 6.8s
Max memory: 524288 KiB
Used memory: 524288 KiB
Persistent: yes
Autostart: disable
Managed save: no
Security model: none
Security DOI: 0
#指定域的xml格式配置文件,使用此配置文件可快速创建kvm虚拟机
#将此配置文件作出相应的修改提供镜像模板,及其xml配置文件即可快速生成大批量虚拟机
#如下标签需修改:<naem>/<uuid>/<source>/<mac address>等,需与此虚拟机不一样即可
[root@node1 ~]# virsh dumpxml centos6.6
<domain type='kvm' id='4'>
<name>centos6.6</name>
<uuid>9f12e96f-7bf4-469d-b3e8-79f7e1cf4eee</uuid>
<memory unit='KiB'>524288</memory>
<currentMemory unit='KiB'>524288</currentMemory>
<vcpu placement='static'>2</vcpu>
<resource>
<partition>/machine</partition>
</resource>
<os>
<type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type>
<boot dev='hd'/>
</os>
<features>
<acpi/>
<apic/>
</features>
<cpu mode='custom' match='exact'>
<model fallback='allow'>Opteron_G5</model>
</cpu>
<clock offset='utc'>
<timer name='rtc' tickpolicy='catchup'/>
<timer name='pit' tickpolicy='delay'/>
<timer name='hpet' present='no'/>
</clock>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>
<pm>
<suspend-to-mem enabled='no'/>
<suspend-to-disk enabled='no'/>
</pm>
<devices>
<emulator>/usr/libexec/qemu-kvm</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/var/lib/libvirt/p_w_picpaths/centos6.6.qcow2'/>
<backingStore/>
<target dev='vda' bus='virtio'/>
<alias name='virtio-disk0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
</disk>
<controller type='usb' index='0' model='ich9-ehci1'>
<alias name='usb'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x7'/>
</controller>
<controller type='usb' index='0' model='ich9-uhci1'>
<alias name='usb'/>
<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'>
<alias name='usb'/>
<master startport='2'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x1'/>
</controller>
<controller type='usb' index='0' model='ich9-uhci3'>
<alias name='usb'/>
<master startport='4'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x2'/>
</controller>
<controller type='virtio-serial' index='0'>
<alias name='virtio-serial0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
</controller>
<controller type='pci' index='0' model='pci-root'>
<alias name='pci.0'/>
</controller>
<interface type='bridge'>
<mac address='52:54:00:ee:5e:ce'/>
<source bridge='br0'/>
<target dev='vnet0'/>
<model type='virtio'/>
<alias name='net0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
<serial type='pty'>
<source path='/dev/pts/2'/>
<target port='0'/>
<alias name='serial0'/>
</serial>
<console type='pty' tty='/dev/pts/2'>
<source path='/dev/pts/2'/>
<target type='serial' port='0'/>
<alias name='serial0'/>
</console>
<channel type='unix'>
<source mode='bind' path='/var/lib/libvirt/qemu/channel/target/domain-centos6.6/org.qemu.guest_agent.0'/>
<target type='virtio' name='org.qemu.guest_agent.0' state='disconnected'/>
<alias name='channel0'/>
<address type='virtio-serial' controller='0' bus='0' port='1'/>
</channel>
<channel type='spicevmc'>
<target type='virtio' name='com.redhat.spice.0' state='disconnected'/>
<alias name='channel1'/>
<address type='virtio-serial' controller='0' bus='0' port='2'/>
</channel>
<input type='tablet' bus='usb'>
<alias name='input0'/>
</input>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<graphics type='spice' port='5900' autoport='yes' listen='127.0.0.1'>
<listen type='address' address='127.0.0.1'/>
<p_w_picpath compression='off'/>
</graphics>
<sound model='ich6'>
<alias name='sound0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</sound>
<video>
<model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1'/>
<alias name='video0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<redirdev bus='usb' type='spicevmc'>
<alias name='redir0'/>
</redirdev>
<redirdev bus='usb' type='spicevmc'>
<alias name='redir1'/>
</redirdev>
<memballoon model='virtio'>
<alias name='balloon0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
</memballoon>
</devices>
</domain>
[root@node1 ~]# ll /var/lib/libvirt/p_w_picpaths/centos6.6.qcow2 #此处为虚拟机的镜像文件存储路径
-rw-r--r-- 1 qemu qemu 85912715264 Dec 11 16:47 /var/lib/libvirt/p_w_picpaths/centos6.6.qcow2
[root@node1 ~]# ll /etc/libvirt/qemu/centos6.6.xml #上诉dump出来配置文件在此路径下
-rw------- 1 root root 3913 Dec 10 21:09 /etc/libvirt/qemu/centos6.6.xml
[root@node1 ~]#
虚拟磁盘扩容:
[root@node1 ~]# qemu-img create -f qcow2 -o ?
Supported options:
size Virtual disk size
compat Compatibility level (0.10 or 1.1)
backing_file File name of a base p_w_picpath
backing_fmt Image format of the base p_w_picpath
encryption Encrypt the p_w_picpath
cluster_size qcow2 cluster size
preallocation Preallocation mode (allowed values: off, metadata, falloc, full)
lazy_refcounts Postpone refcount updates
#创建磁盘映像文件大小为20G
[root@node1 ~]# qemu-img create -f qcow2 -o preallocation=metadata /tmp/test.qcow2 20G
Formatting '/tmp/test.qcow2', fmt=qcow2 size=21474836480 encryption=off cluster_size=65536 preallocation='metadata' lazy_refcounts=off
[root@node1 ~]# ls -lh /tmp/test.qcow2
-rw-r--r-- 1 root root 21G Dec 11 17:12 /tmp/test.qcow2
#将磁盘映像文件添加至kvm虚拟机中
[root@node1 ~]# virsh attach-disk centos6.6 /tmp/test.qcow2 vdb
Disk attached successfully #表示添加成功
[root@node1 ~]#
#在创建的kvm虚拟机中查看是否存在此虚拟磁盘
[root@localhost ~]# fdisk -l
Disk /dev/vda: 85.9 GB, 85899345920 bytes
16 heads, 63 sectors/track, 166440 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000ab84c
Device Boot Start End Blocks Id System
/dev/vda1 * 3 409 204800 83 Linux
Partition 1 does not end on cylinder boundary.
/dev/vda2 409 125239 62914560 8e Linux LVM
Partition 2 does not end on cylinder boundary.
Disk /dev/mapper/vg0-root: 21.5 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
Disk /dev/mapper/vg0-swap: 2147 MB, 2147483648 bytes
255 heads, 63 sectors/track, 261 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
Disk /dev/mapper/vg0-usr: 10.7 GB, 10737418240 bytes
255 heads, 63 sectors/track, 1305 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
Disk /dev/mapper/vg0-var: 21.5 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
#查看到此vdb时则说明添加至此的虚拟磁盘生效,可对其进行分区格式化使用
Disk /dev/vdb: 21.5 GB, 21478375424 bytes
16 heads, 63 sectors/track, 41617 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
[root@localhost ~]# fdisk -cu /dev/vdb
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel with disk identifier 0x67288332.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.
Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)
Command (m for help):
Disk /dev/vdb: 21.5 GB, 21478375424 bytes
16 heads, 63 sectors/track, 41617 cylinders, total 41949952 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x35c26476
Device Boot Start End Blocks Id System
/dev/vdb1 2048 20480 9216+ 83 Linux
/dev/vdb2 20481 41949951 20964735+ 83 Linux
Command (m for help): #后续即格式化挂载使用即可
总结:kvm虚拟化技术有着隔离的功能,应用程序都可在相互独立的空间运行而相互不影响彼此,在大型公司运用广泛,上诉所写的内容只是一个入门级别,知道相应的原理之后可结合使用脚本完成自动化的部署,通过脚本自动完成创建虚拟机。