利用KVM技术构建跨平台虚拟化环境,新手指南
一、虚拟化概念
虚拟化是指对资源的逻辑抽象、隔离、再分配、管理的一个过程,通常对虚拟化的理解有广义狭义之分。广义包括平台虚拟化、应用程序虚拟化、存储虚拟化、网络虚拟化、设备虚拟化等等。狭义的虚拟化专门指计算机上模拟运行多个操作系统平台。
虚拟化的目的是通过对硬件资源的抽象和管理,实现资源的高效利用、灵活性、隔离和安全性,从而提供更高效、可靠和可扩展的计算环境。
虚拟化技术和云计算的关系:
- 维基百科云计算定义:云计算是一种通过因特网以服务的方式提供动态可伸缩的虚拟化的资源的计算模式。
- 云计算是建立在虚拟化技术的基础上,通过互联网提供按需的计算资源和服务。云计算提供了虚拟化技术的更高层次的抽象和服务,如虚拟机实例、容器服务、函数计算等。它提供了多租户环境、自动化管理和弹性扩展等特性,使用户可以根据实际需求快速获取和释放计算资源。
- 虚拟化技术为云计算提供了基础的资源池和资源管理能力,使云计算可以实现资源的共享和动态分配。而云计算为虚拟化技术提供了更广阔的应用场景和服务,使其得以更好地应用于实际业务和服务交付。
二、KVM虚拟化技术
KVM全称是Kernel-based Virtual Machine,即基于内核的虚拟机,是采用硬件辅助虚拟化技术的全虚拟化解决方案。对于I/O设备(如硬盘、网卡等),KVM即支持QEMU(虚拟操作系统模拟器)仿真的全虚,也支持virtio方式的半虚。KVM从诞生开始就定位于基于硬件虚拟化支持的全虚实现,由于其在Linux内核2.6版本后被集成,通过内核加载模式使得Linux内核变成一个事实上的Hypervisor(虚拟机管理器,也叫VMM(Virtual Machine Monitor)),但是硬件管理还是由Linux Kernel来完成。
Hypervisor和VMM:
可以把hypervisor和VMM(virtual machine monitor)理解为同一样东西,它们都是用于监控和控制虚拟机操作系统。在创建虚拟机的过程中,会虚拟出一整套的硬件资源,例如硬盘、内存、CPU、网络设备等,这些工作都是由hypervisor负责,除此之外,它还负责虚拟系统运行过程的资源分配和虚拟机的生命周期管理等。
一个KVM客户机就对应一个Linux进程,每个vCPU对应这个进程下的一个线程,还有单独处理I/O的线程,属于同一个进程组。所以,宿主机上Linux Kernel可以像调度普通Linux进程一样调度KVM虚拟机,这种机制使得Linux Kernel的进程优化和调度功能优化等策略,都能用于KVM虚拟机。比如:通过进程权限限定功能可以限制KVM客户机的权限和优先级等。
由于KVM嵌入Linux内核中,除了硬件辅助虚拟化(如VT-d)的硬件设备能被虚拟机看见外,其他的I/O设备都是QEMU模拟出来的,所以QEMU是KVM天生的好基友。
可以说KVM就是在硬件辅助虚拟化技术之上构建起来的VMM。但并非要求所有硬件虚拟化技术都支持才能运行KVM虚拟化,KVM对硬件最低的依赖是CPU的硬件虚拟化支持(比如:Intel的VT-x技术和AMD的AMD-V技术),而其他的内存和I/O的硬件虚拟化支持,会让整个KVM虚拟化下的性能得到更多的提升。所以在虚拟机部署KVM功能时,首先就是要查看宿主机Host(也就是主机上的虚拟机,这里是在VMware Workstations的虚拟机打开CPU虚拟化功能。
然后在Linux系统中可以通过如下命令确定支持VT-x功能:如果什么输出都没有,那说明你的系统并没有支持虚拟化的处理 ,不能使用KVM。
"vmx" 是 Intel CPU 的虚拟化技术标识,"svm" 是 AMD CPU 的虚拟化技术标识。
安装KVM及相关的工具:
sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virt-manager
- qemu-kvm:KVM虚拟化的基本包
- libvirt-daemon-system:libvirt守护程序,提供API和管理虚拟化功能
- libvirt-clients:包含用于与libvirt守护程序通信的客户端实用程序
- bridge-utils:用于创建和管理网络桥接的工具集
- virt-manager:用于管理虚拟机的图形化工具
确认libvirtd服务已启动并运行:
sudo systemctl start libvirtd
sudo systemctl status libvirtd
#确保在系统启动时自动启动
sudo systemctl enable libvirtd
通过virt-manger(图形化工具)来创建或者管理虚拟机
或者通过virsh(命令行工具)来创建或者管理虚拟机
下面是一些常用的virsh命令:
virsh list: 列出当前运行的虚拟机 virsh start <domain>: 启动指定名称的虚拟机 virsh shutdown <domain>: 关闭指定名称的虚拟机 virsh reboot <domain>: 重启指定名称的虚拟机 virsh create <xmlfile>: 根据指定的XML文件创建虚拟机 virsh destroy <domain>: 强制停止指定名称的虚拟机 virsh undefine <domain>: 删除指定名称的虚拟机配置 virsh console <domain>: 进入指定名称的虚拟机控制台 virsh dominfo <domain>: 显示指定名称的虚拟机信息 virsh domstate <domain>: 显示指定名称的虚拟机状态
接下来分析一下kvm的Makefile :
可以看出kvm的Makefile主要生成三个模块,kvm.o和kvm-intel.o、kvm-amd.o。
- kvm.o是kvm的核心模块,kvm基本只实现硬件辅助虚拟化相关部分,而不支持的用Qemu来模拟实现。
- kvm-intel.o是intel平台架构虚拟化模块,平台相关
- kvm-amd.o是amd架构虚拟化模块,平台相关
三、KVM架构
KVM是在硬件虚拟化支持下的全虚拟化技术,所以它能在相应硬件上运行几乎所有的操作系统,KVM虚拟化的核心主要由以下两个模块组成:
1)KVM内核模块,它属于标准Linux内核的一部分,是一个专门提供虚拟化功能的模块,主要负责CPU和内存的虚拟化,包括:客户机的创建、虚拟内存的分配、CPU执行模式的切换、vCPU寄存器的访问、vCPU的执行。
2)QEMU用户态工具,它是一个普通的Linux进程,为客户机提供设备模拟的功能,包括模拟BIOS、PCI/PCIE总线、磁盘、网卡、显卡、声卡、键盘、鼠标等。同时它通过ioctl系统调用与内核态的KVM模块进行交互。
如上图中,在KVM虚拟化架构下,每个客户机就是一个QEMU进程,在一个宿主机上有多少个虚拟机就会有多少个QEMU进程。客户机中的每一个虚拟CPU对应QEMU进程中的一个执行线程,一个宿主机Host中只有一个KVM内核模块,所有虚拟机都与这个内核模块进行交互。
3.1KVM内核模块
VM内核模块是KVM虚拟化的核心模块,它在内核中由两部分组成:一个是处理器架构无关的部分,用lsmod命令中可以看到,叫作kvm模块;另一个是处理器架构相关的部分,在Intel平台上就是kvm_intel这个内核模块。如下图所示,KVM的主要功能是初始化CPU硬件,打开虚拟化模式,然后将虚拟机运行在虚拟环境下,并对虚拟机的运行提供一定的支持。
以Intel CPU架构服务器为例,KVM打开并初始化硬件以支持虚拟机运行的过程如下:
Step1:在被内核加载的时候,KVM模块会先初始化内部的数据结构。
Step2:做好准备之后,KVM模块检测系统当前的CPU,然后打开CPU控制寄存器CR4中的虚拟化模式开关,并通过执行VMXON指令将宿主操作系统(包括KVM模块本身)置于CPU虚拟化模式中的根模式root operation,详细参见本站计算虚拟化之CPU虚拟化一文。
Step3:KVM模块创建特殊设备文件/dev/kvm并等待来自用户空间的命令。
Step4:后续虚拟机的创建和运行,其本质上就是是一个用户空间的QEMU和内核空间的KVM模块相互配合的过程。
这里面的/dev/kvm这个设备比较关键,它可以被当作一个标准的字符设备,用来缓存用户空间与内核空间切换的上下文,也就是ioctl调用上下文,是KVM模块与用户空间QEMU的通信接口。:
3.2QEMU用户态设备模拟
QEMU原本就是一个著名的开源虚拟机软件项目,既是一个功能完整的虚拟机监控器,也在QEMU-KVM的软件栈中承担设备模拟的工作。
QEMU最初实现的虚拟机是一个纯软件的实现,也就是我们常说的通过二进制翻译来实现虚拟机的CPU指令模拟,所以性能比较低。但是,其优点是跨平台,甚至可以支持客户机与宿主机并不是同一个架构,比如在x86平台上运行ARM客户机。同时,QEMU能与主流的Hypervisor完美契合,包括:Xen、KVM、Hyper-v,以及VMware各种Hypervisor等,为上述这些Hypervisor提供虚拟化I/O设备。
而QEMU与KVM密不可分的原因,就是我们常说的QEMU-KVM软件协议栈。虚拟机运行期间,QEMU会通过KVM内核模块提供的系统调用ioctl进入内核,由KVM内核模块负责将虚拟机置于处理器的特殊模式下运行。一旦遇到虚拟机进行I/O操作时,KVM内核模块会从上次的系统调用ioctl的出口处返回QEMU,由QEMU来负责解析和模拟这些设备。除此之外,虚拟机的配置和创建,虚拟机运行依赖的虚拟设备,虚拟机运行时的用户操作环境和交互,以及一些针对虚拟机的特殊技术,比如动态迁移,都是由QEMU自己实现的。
总之,KVM 本身不执行任何模拟,需要用户空间应用程序 QEMU
通过 /dev/kvm
接口设置一个客户机虚拟服务器的地址空间,向它提供模拟的 I/O,KVM 模块实现处理器的虚拟化和内存虚拟化。在硬件虚拟化技术的支持下,内核的 KVM 模块与 QEMU 的设备模拟协同工作,构成一套和物理计算机系统完全一致的虚拟化计算机软硬件系统。
四、监控KVM事件
bcc程序中提供了一个例子用来监控kvm相关事件
源码:
kvm_hypercall.pyhttps://github.com/iovisor/bcc/blob/master/examples/tracing/kvm_hypercall.py
运行结果如下:
这个程序使用了kvm相关的以下几个tracepoint静态跟踪点:
kvm_entry:当虚拟机的vCPU(虚拟中央处理单元)从主机CPU切换到虚拟机CPU并开始执行虚拟指令时,触发kvm_entry跟踪点,vcpu_id用于标识特定的虚拟CPU。
kvm_exit:当虚拟机的vCPU执行完一段虚拟指令并从虚拟机CPU切换回主机CPU时,触发kvm_exit跟踪点,exit_reason表示虚拟cpu推出到主机cpu的具体原因。
kvm_hypercall:用于跟踪虚拟机中的超级调用(hypercall)。当虚拟机的Guest OS需要执行一些更高权限的操作(如:页表的更新、对物理资源的访问等)时,由于自身在非特权域无法完成这些操作,于是便通过超级调用交给Hypervisor来完成这些操作,其中nr代表超级调用号。
kvm_exit中的exit_reason:
上图中的12,18,32分别代表访问任务优先级寄存器(TP),操作系统特定事件,处理器处于AP复位保持状态。
hypercall_nr(超级调用号):5号超级调用表示请求Hypervisor程序将处于休眠状态的 vCPU 唤醒。
五、DPDK在KVM虚拟机中使用
那什么样的程序员适合学习dpdk技术?
对于dpdk来说,它更看重计算机原理和底层技术,和业务上的关联不大,适合:
- 计算机相关专业,对底层技术原理感兴趣的应届生;
- 对网络原理、dpdk、高性能网络开发的在职工程师;
- 工作中从事dpdk/vpp/ovs等开发的工程师;
- 有良好的计算机原理和底层技术基础,想往互联网行业发展的桌面开发,c++开发工程师等等。
这里给大家推荐零声教育全网独家的【dpdk-网络协议栈-vpp-OVS-DDos-虚拟化技术】课程体系,通过32个项目案例,2W+行手写代码,全面解析4个dpdk技术方向:
5.1DPDK网络专栏
(1)dpdk基础知识
- 1.多队列网卡,vmxnet/e1000
- 2.igb_ uio与vfio模块
- 3.kni模块
- 4.hugepage的理解
- 5.零拷贝
- 6.dpdk与netmap区别
- 7.dpdk的工作环境
(2)网络协议栈
- 1.dpdk-arp
- 2.netsh静态arp表设置
- 3.dpdk-icmp
- 4.udp协议格式分析
- 5.udp协议sendto, recvfrom实现
- 6.dpdk-ip
- 7.dpdk-tcp
- 8.tcp协议栈bind,listen, accept实现
- 9.tcp协议栈recv, send, close的实现
- 10.tcp三次握手实现
- 11.tcp四次挥手实现
- 12.tcp acknum与seqnum的确认机制实现
- 13.tcp的并发连接设计
- 14.epoll并发的实现
- 15.tcp协议栈与epoll之间的回调实现
(3)dpdk组件项目
- 1.dpdk-ac
- 2.dpdk-kni
- 3./dev/ kni的原理分析
- 4.kni_ dev的流程
- 5.kni的t缓冲区,rx缓冲区
- 6.kni的用户空间与内核空间映射
- 7.mbuf如何转化为kernel的sk_ buff
- 8.dpdk- timer
- 9.bpftrace的使用
- 10.dpdk- bpf源码流程
(4)dpdk经典项目
- 1.dpdk- dns
- 2.dpdk- gateway
- 3.dpdk-ddos熵计算源码
- 4.ddos attach检测精确度调试
- 5.ddos attach测试T具hping3
- 6.布谷鸟hash原理与使用
5.2储存技术专栏
(1)高效磁盘io读写spdk(C)
- 1.存储框架spdk,为技术栈打开扇存储的大门
- 2.spdk运行环境与vhost
- 3.NVMe与PCl的关系
- 4.手把手实现spdk_ server
- 5.nvme与pcie以及手写nvme读写操作
- 6.bdev与blob之间的关系
- 7.实现blob异步读写
- 8.blobstore的读写操作实现与rpc的关系
- 9.fio性能测试性能对比libaio,io_ uring,psync
- 10.fio plugin工作流程
- 11.fio plugin开发
(2)spdk文件系统的实现
- 1.文件系统功能拆解
- 2.spdk_ env_ init与spdk_ app init的差别
- 3.spdk_ _thread_ poll实现rpc回调
- 4.fs_ operations结构体定义
- 5.file_ operations结构体定义
- 6.dir_ operations结构体定义
- 7.syscall的hook实现
- http://8.io内存管理
- 9.基数树对文件系统内存管理
- 10.spdk_ blob的open,read,write,close
- 11.测试用例与调试入口函数
(3)spdk kv存储的实现
- 1.KV存储拆解Set, Get, Mod, Del
- 2.app/.a库/so库对于kv存储的选择
- 3.bdev与blob对于kv存储的选择
- 4.kv service启动blob资源操作
- 5.kv service关闭blob资源回收
- 6.kv service接口set,get,modify,delete
- 7.kv遍历与查找实现
- 8.page存储chunk的管理
- 9.pagechunk的get与put
- 10.page单查找与多页查找
- 11.btree, artree, hashmap,radixtree, rbtree之间的选择
- 12.slab的实现
- 13.slab分配slot与释放slot
- 14.为kv加上conf文件
- 15.测试用例与性能测试
5.3安全与网关开发专栏
(1)可扩展的矢量数据包处理框架vpp(c/c++)
- 1.vpp命令详解
- 2.mac/ip转发plugin
- 3.load_ balance plugin
- 4.flowtable plugin
- 5.vpp源码之间的差异
- 6.多网卡数据接收与转发
- 7.解决plugin编译加载
- 8.vpp启动load so的流程
- 9.vpp的结构体vlib_ _main实现分析
- 10.vpp的结构体vnet_ main
- 11.vector的操作实现
- 12.vpp vcl库与LD_ PRELOAD实现分析
- 13.vcl原理讲解
- 14.vcl tcpserver实现原理
- 15.vcl tcpclient实现原理
- 16.vcl与iperf3的客户端与服务器
- 17.vcl与nginx的wrk性能测试
- 18.vcl与haproxy的性能测试
- 19.vpp 1801版本与vpp 2206版本
- 20.vpp httpserver的实现源码
- 21.vpp plugin quic源码分析
- 22.vpp plugin hs_ app的源码
- 23.vpp plugin rdma的实现分析
- 24.vpp plugin loadbalance
- 25.vpp plugin nat的源码分析
- 26.vpp host-stack tcp协议实现
- 27.vpp plugin的测试用例实现
(2)golang的网络开发框架nff-go(golang)
- 1.nff-go实现的技术原理
- 2.nff-go/low.h实现分析
- 3.nff- go数据接收的实现
- 4.nff-go数据发送的实现
- 5.ipsec协议解析与strongswan的ipsec
- 6.nff go的缺陷与不足
5.4虚拟化与云原生专栏
(1)DPDK的虚拟交换机框架OvS
- 1.ovs编译安装,ovs核心组件内容
- 2.ovs-vswitchd的工作原理
- 3.ovs-vswitchd与dpdk的关系
- 4.ovs-vsctl的网桥,网口操作
- 5.qemu-system-x86_ 64构建多子网
- 6.ovs与qemu数据流分发
- 7.ovs搭建docker跨主机通信
- 8.ovsdb server与ovsdb协议
- 9.json-rpc为控制面提供开发
- 10.ovs-tcpdump/ovs-l3ping
- 11.OvS 4种数据路径
- 12.VXL AN数据协议
- 13.ovs流量统计
(2)高性能4层负载均衡器DPVS
- 1.dpvs的技术组件与功能边界
- 2.lvs+keepalived配置高可用server
- 3.dpvs与|lvs+ keepalived的关系
- 4.dpvs.conf的配置文件
- 5.dpvs的FNat/NAT/SNAT模式
- 6.dpvs的DR模式
- 7.dpvs的tun模式
- 8.通过quagga配置ospf
- 9.dpvs的tc流控操作与源码实现
- 10.dpvs代码架构分析
- 11.dpvs测试用例ipset, tc,mempool
5.5测试工具专栏
(1)perf3
- 1.vpp vcl的perf3接口hook
- 2.perf3测网络带宽
- 3.tcp吞吐量测试
- 4.udp丢包与延迟测试
- 5.json测试结果输出
(2)TRex
- 1.TRex的运行原理
- 2.TRex与dpdk
- 3.构建TRex测试系统
- 4.t-rex -64- debug gdb调试
- 5.bg-sim- 64模拟单元测试
- 6.YAML文件编写
- 7.流编排与自动化框架
- 8.报文变量设置
(3)dpdk-pktgen
- 1.pktgen命令讲解
- 2.default.cfg配置文件分析
- 3.120M bits/s的转发速率
(4)fio
- 1.ioengine的实现
- 2.ioengine_ ops的分析
- 3.iodepth的分析
- 4.spdk_ nvme的fio分析
- 5.spdk_ bdev的fio分析
- 6.spdk_ blob的ioengine实现
- 7.psync,io_ uring, libaio性能对比
5.6性能测试专栏
(1)性能指标
- 1.吞吐量bps
- 2.拆链/建链pps
- 3.并发
- 4.最大时延
- 5.最小时延
- 6.平均时延
- 7.负载
- 8.包速fps
- 9.丢包率
(2)测试方法
- 1.测试用例
- 2.vpp sandbox
- 3.perf3灌包
- 4.rfc2544
还不熟悉的朋友,这里可以先领取一份dpdk新手学习资料包(入坑不亏):
DPDK学习地址:Dpdk/网络协议栈/vpp/OvS/DDos/NFV/虚拟化/高性能专家
学习后可从事开发岗位:
- 高级网络开发工程师
- DPDK开发工程师
- 云产品研发工程师
- 云基础开发工程师
- 高性能优化工程师
- SDN开发工程师
- NFV开发工程师
写在最后:
Dpdk作为目前在互联网越来越流行的底层技术,受到越来越多的优秀互联网公司的欢迎与使用。但对于不少程序员来说可能只是见过或是听过,并没有深入的学习和使用。