KVM详情

KVM介绍

  Kernel-based Virtual Machine的简称,是一个开源的系统虚拟化模块,自Linux 2.6.20之后集成在Linux的各个主要发行版本中。它使用Linux自身的调度器进行管理,所以相对于Xen,其核心源码很少。KVM目前已成为学术界的主流VMM之一。

KVM的虚拟化需要硬件支持(如Intel VT技术或者AMD V技术)。是基于硬件的完全虚拟化。而Xen早期则是基于软件模拟的Para-Virtualization,新版本则是基于硬件支持的完全虚拟化

KVM虚拟化结构

  KVM是嵌入在Linux操作系统标准内核中的一个虚拟化模块,它能够将一个Linux标准内核转换成为一个VMM,嵌有KVM模块的Linux标准内核可以支持通过kvm tools来进行加载的GuestOS。所以在这样的操作系统平台下,计算机物理硬件层上直接就是VMM虚拟化层,而没有独立出来的HostOS操作系统层。在这样的环境中HostOS就是一个VMM。

每个由KVM创建的GuestOS都是HostOS(或VMM)上的一个单个进程。而在GuestOS上的User-space中运行的Applications可以理解为就是进程中的线程。

libvirt介绍

  虚拟云实现的三部曲:虚拟化技术实现-->虚拟机管理-->集群资源管理(云管理)。各种不同的虚拟化技术都提供了基本的管理工具。比如,启动,停用,配置,连接控制台等。这样在构建云管理的时候就存在两个问题:    

  1) 如果采用混合虚拟技术,上层就需要对不同的虚拟化技术调用不同管理工具,很是麻烦。    

  2) 虚拟化技术发展很迅速,系统虚拟化和容器虚拟化均在发展和演化中。可能有新的虚拟化技术更加符合现在的应用场景,需要迁移过去。这样管理平台就需要大幅改动。     为了适应变化,我们惯用的手段是分层,使之相互透明,在虚拟机和云管理中设置一个抽象管理层。libvirt就是扮演的这个角色。有了它,上面两个问题就迎刃而解。libvirt提供各种API,供上层来管理不同的虚拟机。
    Libvirt是管理虚拟机和其他虚拟化功能,比如存储管理,网络管理的软件集合。它包括一个API库,一个守护程序(libvirtd)和一个命令行工具(virsh);libvirt本身构建于一种抽象的概念之上。它为受支持的虚拟机监控程序实现的常用功能提供通用的API。     libvirt的主要目标是为各种虚拟化工具提供一套方便、可靠的编程接口,用一种单一的方式管理多种不同的虚拟化提供方式。

Libvirt主要支持的功能

  虚拟机管理:包括不同的领域生命周期操作,比如:启动、停止、暂停、保存、恢复和迁移。支持多种设备类型的热插拔操作,包括:磁盘、网卡、内存和CPU。
    远程机器支持:只要机器上运行了libvirt daemon,包括远程机器,所有的libvirt功能就都可以访问和使用。支持多种网络远程传输,使用最简单的SSH,不需要额外配置工作。
    存储管理:任何运行了libvirt daemon的主机都可以用来管理不同类型的存储:创建不同格式的文件镜像(qcow2、vmdk、raw等)、挂接NFS共享、列出现有的LVM卷组、创建新的LVM卷组和逻辑卷、对未处理过的磁盘设备分区、挂接iSCSI共享,等等等等。因为libvirt可以远程工作,所有这些都可以通过远程主机使用。
    网络接口管理:任何运行了libvirt daemon的主机都可以用来管理物理和逻辑的网络接口。
    虚拟NAT和基于路由的网络:任何运行了libvirt daemon的主机都可以用来管理和创建虚拟网络。

当前主流 Linux 平台上默认的虚拟化管理工具 virt-manager(图形化),virt-install (命令行模式)等均基于 libvirt 开发而成。

从上图中可以看出 libvirt 本身不是一种工具,它是一种可以建立工具来管理客户操作系统的API,libvirtd 为守护进程。

KVM安装

KVM:
    必须在64位系统上运行
    CPU必须支持HVM (硬件虚拟化)

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#检查系统是否支持虚拟化(intel VT技术,AMD V技术)如果在虚拟机环境下要勾选虚拟化
[root@controller ~]# grep  -Eo 'svm|vmx' /proc/cpuinfo
vmx
vmx
装载模块:
[root@controller ~]#  modprobe kvm_intel kvm_amd kvm
[root@controller ~]# lsmod |grep kvm
kvm_intel             170200  0
kvm                   566604  1 kvm_intel
irqbypass              13503  1 kvm
 
安装kvm:
    Virtualization
        提供qemu-kvm工具
    Virtualization Client
    Virtualization Platform
        提供libvirt, libvirt-client,virt-who,virt-what
    Virtualization Tools
        提供libguestfs
 
[root@controller ~]# yum -y groupinstall "Virtualization" "Virtualization Client" "Virtualization Platform"
使用virt-install创建虚拟机并安装GuestOS
 
需要依赖libvirtd服务
# service libvirtd start
启动 libvirtd 守护进程:                                   [确定]
 
 
virt-install是一个命令行工具,它能够为KVM,Xen或其它支持libvirt
  
API的hypervisor创建虚拟机并完成GuestOS的安装;此外,它能够基于串行控制台,VNC或SDL支持文本或图形安装界面。安装过程可以使用本地的安装介质如CDROM,也可以通过网络方式如NFS,HTTP或FTP服务实现。对于通过网络安装的方式,virt-install可以自动加载必要的文件以启动安装过程而无须提供额外引导工具。当然,virt-install也可以支持PXE方式的安装过程,也能够直接使用现有的磁盘映像直接启动安装过程。
 
virt-install命令有许多选项,这些选项可分为以下几大类:
 
1)一般选项,指定虚拟机的名称,内存大小、VCPU个数及特性等
    -n <name>:虚拟机名称,全局惟一
    -r <memory>:虚拟机内存大小 ,单位为MB
    --vcpus=VCPUS[,maxvcpus=MAX][,sockets=#][,core=#],[threads=#]:VCPU个数及相关配置
    --cpu=CPU:CPU模式及特性,如coreduo等;可以使用qemu-kvm --cpu ?来获取CPU支持的模式
         
2)安装方法:指定安装方法,GuestOS类型等
    -c CDROM:光盘安装介质
    -l LOCATION:安装源URL,支持FTP/http/nfs等,如:ftp://10.1.1.1/pub
    --pxe:基于PXE完成安装
    --livecd:把光盘当作LiveCD
    --os-type=DISTRO_TYPE:操作系统类型,如linux,unix或windows等
    --os-variant=DISTRO_VARIANT:某类型操作系统的变体,如rhel5,fedora8
    -x EXTRA:根据--location指定的方式安装GuestOS时,用于传递给内核的额外选项,例如指定kickstart文件的位置,--extra-args "ks=http://10.1.1.1/class.cfg"
    --boot=BOOTOPTS:指定安装过程完成后的配置选项,如指定引导设备次序,使用指定的而非安装的kernel/initrd来引导系统.例如,--boot cdrom,hd,network指定引导次序
    --boot kernel=KENEL,initrd=INITRD,kernel_args="console=/dev/ttyS0":指定启动系统的内核及initrd文件
 
3)存储配置:指定存储类型,位置及属性
    --disk=DISKOPTS:指定存储设备及其属性,格式为--disk /some/storage/path,opt1=value,opt2=value;常用的选项有:
        device:设备类型,如cdrom,disk或floppy等,默认为disk
        bus:磁盘总线类型,其值可以为ide,scsi,usb,virtio或xen
        perms:访问权限,如rw,ro,sh(共享的可读写),默认为rw
        size:新建磁盘映像的大小,单位为GB
        cache:缓存模型,其值有none,writethrouth(缓存读)和writeback(缓存读写)
        format:磁盘映像格式,如raw, qcow2,vmdk等
        sparse:磁盘映像使用稀疏格式,即不立即占用指定大小的空间
        --nodisks:不使用本地磁盘,在LiveCD模式中常用
 
4)网络配置:指定网络接口的网络类型及接口属性如MAC地址、驱动模式等
    -w NETWORK,--network=NETWORK,opt1=value,opt2=value:将虚拟机连入宿主机的网络中,其NETWORK可以为:
        bridge=BRIDGE:连接至名为"BRIDGE"的桥设备
        network=NAME:连接至名为"NAME"的网络
         
其他常用选项有:
    model:GuestOS中看到的网络设备型号,如e1000,rtl839或virtio
    mac:固定的MAC地址;省略此选项时将使用随机地址,但无论何种方式,对于KVM来说,其前三段必须为52:54:00
    --nonetworks:虚拟机不使用网络功能
     
5) 图形配置:定义虚拟机显示功能相关的配置,如VNC相关配置
    --graphics TYPE,opt1=value,opt2=value:指定图形显示相关的配置,此选项不会配置任何显示硬件,而是仅指定虚拟机启动后对其进行访问的接口
    TYPE:指定显示类型,可以为vnc,sd1,spice或none等,默认为vnc
    port:TYPE为vnc或splice时其监听的端口
    listen:TYPE为vnc或splice时所监听的IP地址,默认为127.0.0.1,可以通过修改/etc/libvirt/qemu.conf定义新的默认值
    password:TYPE为vnc或splice时,为远程访问监听的服务指定认证密码
    --noautoconsole:禁止自动连接至虚拟机控制台
     
5)设备选项:指定文本控制台,声音设备,串行接口,并行接口,显示接口等
    --serial=CHARPORTS:附加一个串行设备至当前虚拟机,根据设备类型的不同,可以使用不同的选项,格式为"--serial type,opt1=value,opt2=value",例如:
        --serial pty:创建伪终端
        --serial dev,path=HOSTPATH:附加主机设备到此虚拟机
        --vedio=VEDIO:指定显卡设备模型,可用取值为cirrus,vga,qxl或vmvga
         
6) 虚拟化平台:虚拟化模型(hvm或paravirt)、模拟的cpu平台类型、模拟的主机类型、hypervisor类型以及当前虚拟机的UUID等
    -v:当物理机同时支持完全虚拟化和半虚拟机时,指定使用完全虚拟化
    -p:指定使用半虚拟化
    --vir-type:使用的hypervisor,如kvm,qemu,xen等;所有可用值可以使用"virsh capabilities"命令获取
     
7) 其他
    --autostart:指定虚拟机是否在物理机启动后自动启动
    --print-xml:如果虚拟机不需要安装过程,则显示生成的XML而不是创建虚拟机;默认情况下,此选项仍会创建磁盘映像
    --force:禁止命令进行交互式模式,如果有需要回答yes或no选项,则自动回答为yes
    --dry-run:执行创建虚拟机的整个过程,但不真正创建虚拟机、改变主机上的设备配置信息及将其创建的需要通知给libvirt
    -d,--debug:显示debug信息
     
尽管vir-install命令有许多选项,但实际使用中,其必须提供的选项仅包括--name,--ram,--disk及安装过程相关的选项。此外,有时还需要使用--connect=CONNECT选项来指定连接至一个非默认的hypervisor。
 
 
 
下面这个示例创建一个名为rhel5的虚拟机,其hypervisor为KVM,内存大小为512M,磁盘为8G的映像文件/var/lib/libvirt/images/rhel5.8.img,通过boot.iso光盘镜像来引导
 
# virt-install \
--connect qemu:///system \
--virt-type kvm \
--name rhel5 \
--ram 512 \
--disk path=/var/lib/libvirt/images/rhel5.img,size=8 \
--graphics vnc \
--cdrom /tmp/boot.iso \
--os-variant rhel5        
         
         
查看当前主机支持的连接hypervisor方式
# virsh uri
qemu:///system       
         
# virsh define:根据事先存在的xml文件创建虚拟机,创建后不会自动启动
# virsh create:创建虚拟机,创建后会自动启动
# virsh undefine:删除虚拟机
         
         
下面的示例将创建一个名为rhel6的虚拟机,其有两个虚拟CPU,安装方法为FTP,并指定了ks文件的位置,磁盘映像文件为稀疏格式,连接至物理主机上的名为brnet0的桥接网络
 
# virt-install \
--connect qemu:///system \
--virt-type kvm \
--name rhel6 \
--ram 1024 \
--vcpus 2 \
--network bridge=brnet0 \
--disk path=/VMs/images/rhel6.img,size=120,sparse \
--location ftp://10.1.1.1/rhel6/dvd \
--extra-args="ks=http://10.1.1.1/rhel6.cfg" \
--os-variant rhel6 \
--force
 
下面的示例将创建一个名为rhel5.8的虚拟机,磁盘映像文件为稀疏模式的格式为qcow2且总线类型为virtio,安装过程不启动图形界面,但会启动一个串行终端将安装过程以字符形式显示在当前文本模式下,虚拟机显卡类型为cirrus
 
# virt-install \
--connect qemu:///system \
--virt-type kvm \
--name rhel5.8 \
--vcpus 2,maxvcpus=4 \
--ram 512 \
--disk path=/VMs/images/rhel5.8.img,size=120,format=qcow2,bus=virtio,sparse \
--network bridge=brnet0,model=virtio \
--nographics \
--location ftp://10.1.1.1/pub \
--extra-args "ks=http://10.1.1.1/class.cfg console=ttyS0 serial" \
--os-variant rhel5 \
--force \
--video=cirrus
 
下面的示例则利用已经存在的的磁盘映像文件(已经有安装好的系统)创建一个名为rhel 5.8的虚拟机
 
# virt-install \
--name rhel5.8 \
--ram 512 \
--disk /VMs/rhel5.8.img \
--import
 
每个虚拟机创建后,其配置信息保存在/etc/libvirt/qemu目录中,文件名与虚拟机名称相同,格式为XML

KVM常用命令
1.磁盘管理工具qemu-img
镜像模式有两种,一种是全镜像模式,另一种是稀疏模式;
全镜像模式:
    保存了虚拟硬盘中的所有字节数据,其中㛑包括对用户而言无效的数据;raw格式就是全镜像模式。但是 qemu-img 建立的是稀疏格式模式的。
稀疏模式:
只保存对用户和文件系统有效的数据,只占用必要的存储空间,这种模式的镜像文件在存放数据时使用的可能不是连续的物理磁盘空间;

创建镜像目前比较流行的格式有:
qcow2:只能增大,不支持缩小;性能比 raw 稍差
raw:因为实现简单,所以不支持诸如压缩、快照、加密和 CoW 等特性

1)查看镜像信息
[root@controller ~]# qemu-img info 镜像名
2)创建镜像文件
#建立一个名字为test1的raw格式,大小为10G
[root@controller ~]# qemu-img create test1 10G
Formatting 'test1', fmt=raw size=10737418240
[root@controller ~]# ll -h test1
-rw-r--r-- 1 root root 10G Nov 30 01:00 test1
[root@controller ~]# file test1
test1: data
[root@controller ~]# qemu-img info test1
image: test1
file format: raw
virtual size: 10G (10737418240 bytes)
disk size: 0
[root@controller ~]# du -sh test1         
0       test1
我们可以看到磁盘格式是raw的,但是其 type 是 sparse,也就是稀疏文件。稀疏文件指文件中有“洞”
(hole)的文件。raw 格式文件在创建时指定大小之后,就占用了宿主机指定大小的空间,而不像 qcow2 等稀
疏模式的镜像格式可以从很小的文件按需地增长可以通过 dd 或者 qemu-img 生成 raw 格式的磁盘,但是 type 为全镜像模式的磁盘则占据。
#dd建立一个100M的test2.img
[root@controller ~]# dd if=/dev/zero of=/root/test2.img bs=1M count=100   100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 0.457005 s, 229 MB/s
[root@controller ~]# du -sh test2.img
100M    test2.img

#建立一个名字为q1的qcow2格式,大小为1G的文件
#raw 是 qemu-img 默认的格式,所以不用指定格式,qcow2 则需要
[root@controller ~]# qemu-img create -f qcow2 q1.qcow2 1G
Formatting 'q1.qcow2', fmt=qcow2 size=1073741824 encryption=off cluster_size=65536 lazy_refcounts=off
[root@controller ~]# du -sh q1.qcow2
196K    q1.qcow2
3)增大和缩小镜像
#增大名字为test1的raw镜像为20G
[root@controller ~]# qemu-img resize test1 +10G
Image resized.
[root@controller ~]# ll -h test1
-rw-r--r-- 1 root root 20G Nov 30 01:22 test1
#缩小test1镜像为10G;不能缩小到比物理大小还小,否则数据会丢失;
[root@controller ~]# qemu-img resize test1 -10G
Image resized.
[root@controller ~]# ll -h test1               
-rw-r--r-- 1 root root 10G Nov 30 01:25 test1
#qcow2只能增大,不支持缩小,否则会报错。如下:
[root@controller ~]# qemu-img resize q1.qcow2 -1K
qemu-img: qcow2 doesn't support shrinking images yet
qemu-img: This image does not support resize
4)镜像格式转换
qemu-img convert -p -f 原格式 -O 新格式 原文件名 新文件名
-p 表示进度
-f 表示原有的镜像格式
-O 表示输出的镜像格式
[root@controller ~]# qemu-img convert -p -f raw -O qcow2 test1 test1.qcow2
    (100.00/100%)
[root@controller ~]# qemu-img info test1.qcow2
image: test1.qcow2
file format: qcow2
virtual size: 10G (10737418240 bytes)
disk size: 196K
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false
5)创建快照
#为test1.qcow2创建一个名为s1的快照,用-c参数
[root@controller ~]# qemu-img snapshot test1.qcow2 -c s1
#查看快照-l参数
[root@controller ~]# qemu-img snapshot test1.qcow2 -l
Snapshot list:
ID        TAG                 VM SIZE                DATE       VM CLOCK
1         s1                        0 2017-11-30 01:35:59   00:00:00.000
#还原快照用-a参数
[root@controller ~]# qemu-img snapshot test1.qcow2 -a s1
#删除快照-d参数
[root@controller ~]# qemu-img snapshot test1.qcow2 -d s1



posted @   西门运维  阅读(675)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类
点击右上角即可分享
微信分享提示