KVM 折腾记
折腾KVM虚拟机需要一台Linux物理机,自己的笔记本已经配置了WSL,所以不想再装双系统了,但自己又想直接在个人笔记本上操作:),so !挖出老古董联想 B490A-ITH装了系统并开启SSH服务,客户端用Xshell连接,用起来美滋滋!
我的新书《LangChain编程从入门到实践》 已经开售!推荐正在学习AI应用开发的朋友购买阅读!
理论篇
KVM 架构
基于内核的虚拟机 Kernel-based Virtual Machine(KVM)是一种内建于 Linux 中的开源虚拟化技术,具体而言,KVM 可将 Linux 转变为虚拟机监控程序,使主机计算机能够运行多个隔离的虚拟环境,即虚拟机(VM)。
- qemu-kvm 通过对 /dev/kvm 的一系列 ioctl 命令控制虚拟机。
- 一个 KVM 虚拟机即一个 Linux qemu-kvm 进程,与其他Linux 进程一样被Linux 进程调度器调度。
- KVM 虚拟机包括虚拟内存、虚拟CPU和虚拟机 I/O设备,其中,内存和 CPU 的虚拟化由 KVM 内核模块负责实现,I/O 设备的虚拟化由 QEMU 负责实现。
- KVM 虚拟机系统的内存是 qumu-kvm 进程的地址空间的一部分。
- KVM 虚拟机的 vCPU 作为 线程运行在 qemu-kvm 进程的上下文中。
qemu-kvm 与 KVM 内核模块
qemu-kvm
QEMU 原本不是 KVM 的一部分,它自己就是一个纯软件实现的虚拟化系统,但是性能低下,QEMU 代码中包含整套的虚拟机实现,包括处理器虚拟化,内存虚拟化,以及 KVM 需要使用到的虚拟设备模拟(网卡、显卡、存储控制器和硬盘等)。为了简化代码,KVM 在 QEMU 的基础上做了修改,即qemu-kvm ,VM 运行期间,qemu-kvm 会通过 KVM 模块提供的系统调用进入内核,由 KVM 负责将虚拟机置于处理的特殊模式运行。当虚拟机进行 I/O 操作时,KVM 会从上次系统调用出口处返回 qemu-kvm,由 qemu-kvm 来负责解析和模拟这些设备。
从 QEMU 角度看,相当于 QEMU 使用了 KVM 模块的虚拟化功能,为自己的虚拟机提供了硬件虚拟化加速。
KVM 内核模块
KVM 内核模块在运行时按需加载进入内核空间运行,KVM 本身不执行任何设备模拟,需要 QEMU 通过 /dev/kvm 接口设置一个 GUEST OS 的地址空间,向它提供模拟的 I/O 设备,并将它的视频显示映射回宿主机的显示屏。KVM 内核模块是 KVM 虚拟机的核心部分,其主要功能是初始化 CPU 硬件,打开虚拟化模式,并对虚拟机的运行提供一定的支持。以在 Intel 上运行为例,KVM 模块被加载过程:
- 首先初始化内部的数据结构;
- 接着 KVM 模块检测当前的 CPU,然后打开 CPU 控制及存取 CR4 的虚拟化模式开关,并通过执行 VMXON 指令将宿主操作系统置于虚拟化模式的根模式;
- 最后 KVM 模块创建特殊设备文件 /dev/kvm 并等待来自用户空间的指令。
工作过程
虚拟机的创建和运行将是 QEMU 和 KVM 相互配合的过程,两者的通信接口主要是一系列针对特殊设备文件 /dev/kvm 的 ioctl 调用。其中最重要的是创建虚拟机,可以理解成 KVM 为了某个特定的虚拟机创建对应的内核数据结构,同时,KVM 返回一个文件句柄来代表所创建的虚拟机。
针对该句柄的调用可以对虚拟机做相应地管理,比如创建用户空间虚拟地址和客户机物理地址、真实物理地址之间的映射关系;再比如创建多个 vCPU,KVM 为每一个 vCPU 生成对应的文件句柄,对其相应地 ioctl 调用,就可以对 vCPU 进行管理。
libvirt 是什么
libvirt 是对各种虚拟机进行管理的工具和应用程序接口(API),包括一个API库、一个daemon程序进程(libvirtd)和一个默认命令行管理工具(virsh)。而且一些常用的虚拟机管理工具(如virsh、virt-install、virt-manager等)和 OpenStack 都在底层使用libvirt的应用程序接口。
libvirtd 可以被本地的virsh调用,也可以被远程的virsh调用,然后 libvirtd 调用 qemu-kvm 操作KVM 虚拟机
libvirt 功能
- 虚拟机生命周期管理,包括不同的领域生命周期操作,比如:启动、停止、暂停、保存、恢复和迁移。支持多种设备类型的热插拔操作,包括:磁盘、网卡、内存和CPU。
- 使用 C 语言编写,可以由 Python,Ruby, Perl, PHP, Java 等语言调用,通过一种基于驱动程序的架构,来实现对KVM,vmware,XEN,Hyper-v, LXC 等在内的多种不同 Hypervisor 的驱动。在 libvirt 源代码中,可以很容易找到 qemu_driver.c、xen_driver.c xenapi_driver.c、vmware_driver.c、vbox_driver.c 这样的驱动程序源代码文件。
- 作为中间适配层,让底层 Hypervisor 对上层用户空间的管理工具是可以做到完全透明的,因为 libvirt 屏蔽了底层各种 Hypervisor 的细节,为上层管理工具提供了一个统一的、较稳定的接口(API)。
- 使用 XML 来定义各种虚拟机相关的受管理对象。
- 虚拟网络管理:可以用来管理和创建虚拟网络,管理物理和逻辑的网络接口
安装
有两种方式来安装 libvirt:
- 下载 libvirt 的源代码,然后编译和安装
- 从各 Linux 的发行版中直接安装,比如 Ubuntu 上运行
sudo apt install libvirt-bin
(这篇就是这么操作的)
实操篇
开启SSH服务
在开启服务之前,其实可以不用考虑本机有没有安装SSH服务,直接安装,但是为了更好的了解过程,一步一步的去开启更好。
1 | # 试着开启SSH服务 |
看到服务starting了,服务成功开启。客户端打开Xshell,输入用户名、密码连接即可。
两点说明
- 使用
ifconfig
获得物理机的ip地址,客户端连接要用到 - 注意端口号默认22,一般还是查一下,而且防火墙也要设置开启端口
SSH的配置文件部分补充
有关ssh服务的详细配置说明可以输入命令man sshd_config
查看
通过命令sudo vi /etc/ssh/sshd_config
对这个配置文件进行自定义
1 | # This is the sshd server system-wide configuration file. |
安装 KVM
首先确认CPU是否支持硬件虚拟化,里面有 vmx 或者 svm 即表示可以支持
1 | $ egrep -o '(vmx|svm)' /proc/cpuinfo |
注意:除了这里显示支持,还要启动BIOS的虚拟化设置,确认开启CPU虚拟化
安装 KVM 相关依赖包
1 | sudo apt install qemu-kvm |
检查一下kvm模块是否已经加载至内核
1 | lsmod | grep kvm |
重启libvirt服务
1 | sudo service libvirt-bin restart |
查看KVM节点(服务器)信息
1 | sudo virsh nodeinfo |
查看当前主机上hypervisor的链接路径
1 | sudo virsh uri # qemu:///system |
默认情况下,安装完上述环境后,会自动配置好一个默认的网络环境default
1 | sudo virsh net-list --all |
启用KVM虚拟系统管理器
1 | sudo virt-manager |