KVM 折腾记

折腾KVM虚拟机需要一台Linux物理机,自己的笔记本已经配置了WSL,所以不想再装双系统了,但自己又想直接在个人笔记本上操作:),so !挖出老古董联想 B490A-ITH装了系统并开启SSH服务,客户端用Xshell连接,用起来美滋滋!

我的新书《LangChain编程从入门到实践》 已经开售!推荐正在学习AI应用开发的朋友购买阅读!
LangChain编程从入门到实践

理论篇

KVM 架构

基于内核的虚拟机 Kernel-based Virtual Machine(KVM)是一种内建于 Linux 中的开源虚拟化技术,具体而言,KVM 可将 Linux 转变为虚拟机监控程序,使主机计算机能够运行多个隔离的虚拟环境,即虚拟机(VM)。

  1. qemu-kvm 通过对 /dev/kvm 的一系列 ioctl 命令控制虚拟机。
  2. 一个 KVM 虚拟机即一个 Linux qemu-kvm 进程,与其他Linux 进程一样被Linux 进程调度器调度。
  3. KVM 虚拟机包括虚拟内存、虚拟CPU和虚拟机 I/O设备,其中,内存和 CPU 的虚拟化由 KVM 内核模块负责实现,I/O 设备的虚拟化由 QEMU 负责实现。
  4. KVM 虚拟机系统的内存是 qumu-kvm 进程的地址空间的一部分。
  5. KVM 虚拟机的 vCPU 作为 线程运行在 qemu-kvm 进程的上下文中。
    vCPU、QEMU 进程、LInux 进程调度和物理CPU之间的逻辑关系:.jpg

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 进行管理。

KVM 虚拟机的创建过程.jpg

libvirt 是什么

libvirt 是对各种虚拟机进行管理的工具和应用程序接口(API),包括一个API库、一个daemon程序进程(libvirtd)和一个默认命令行管理工具(virsh)。而且一些常用的虚拟机管理工具(如virsh、virt-install、virt-manager等)和 OpenStack 都在底层使用libvirt的应用程序接口。

QEMU/KVM libvirt 驱动.jpg

libvirtd 可以被本地的virsh调用,也可以被远程的virsh调用,然后 libvirtd 调用 qemu-kvm 操作KVM 虚拟机

libvirt 功能

  1. 虚拟机生命周期管理,包括不同的领域生命周期操作,比如:启动、停止、暂停、保存、恢复和迁移。支持多种设备类型的热插拔操作,包括:磁盘、网卡、内存和CPU。
  2. 使用 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 这样的驱动程序源代码文件。
  3. 作为中间适配层,让底层 Hypervisor 对上层用户空间的管理工具是可以做到完全透明的,因为 libvirt 屏蔽了底层各种 Hypervisor 的细节,为上层管理工具提供了一个统一的、较稳定的接口(API)。
  4. 使用 XML 来定义各种虚拟机相关的受管理对象。
  5. 虚拟网络管理:可以用来管理和创建虚拟网络,管理物理和逻辑的网络接口

安装

有两种方式来安装 libvirt:

  1. 下载 libvirt 的源代码,然后编译和安装
  2. 从各 Linux 的发行版中直接安装,比如 Ubuntu 上运行 sudo apt install libvirt-bin(这篇就是这么操作的)

实操篇

开启SSH服务

在开启服务之前,其实可以不用考虑本机有没有安装SSH服务,直接安装,但是为了更好的了解过程,一步一步的去开启更好。

1
2
3
4
5
6
7
8
9
10
# 试着开启SSH服务
sudo /etc/init.d/ssh start
# 安装
sudo apt update
sudo apt install openssh-server
# 检查SSH服务
sudo ps -e | grep ssh
# 再次开启SSH服务
$ sudo /etc/init.d/ssh start
[ ok ] Starting ssh (via systemctl): ssh.service.

看到服务starting了,服务成功开启。客户端打开Xshell,输入用户名、密码连接即可。

两点说明

  1. 使用ifconfig获得物理机的ip地址,客户端连接要用到
  2. 注意端口号默认22,一般还是查一下,而且防火墙也要设置开启端口

SSH的配置文件部分补充

有关ssh服务的详细配置说明可以输入命令man sshd_config查看
通过命令sudo vi /etc/ssh/sshd_config对这个配置文件进行自定义

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
# This is the sshd server system-wide configuration file.
# 设置sshd服务器绑定的IP地址
ListenAddress 0.0.0.0

# 设置包含计算机私人密匙的文件
HostKey /etc/ssh/ssh_host_rsa_key

# 设置如果用户不能成功登录,在切断连接之前服务器需要等待的时间
LoginGraceTime 2m

# 设置root能不能用ssh登录。这个选项一定不要设成“yes”
PermitRootLogin prohibit-password

# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes

# 设置ssh在接收登录请求之前是否检查用户家目录和rhosts文件的权限和所有权。这通常是必要的,因为新手经常会把自己的目录和文件设成任何人都有写权限。
StrictModes yes

# 设置sshd是否在用户登录的时候显示“/etc/motd”中的信息
PrintMotd no

# 设置在记录来自sshd的消息的时候,是否给出“facility code”
SyslogFacility AUTH

# 设置记录sshd日志消息的层次,INFO是一个好的选择
LogLevel INFO

# 设置是否允许口令验证
PasswordAuthentication yes

# 设置是否允许用口令为空的帐号登录
PermitEmptyPasswords no

# AllowUsers 后面可以跟着任意数量的用户名匹配串(patterns)或user@host这样的匹配串,这些字符串用空格隔开
AllowUsers admin

安装 KVM

首先确认CPU是否支持硬件虚拟化,里面有 vmx 或者 svm 即表示可以支持

1
2
3
4
5
6
7
$ egrep -o '(vmx|svm)' /proc/cpuinfo
vmx
vmx
vmx
vmx
# 查看主机上的 CPU 物理情况
$ numactl --hardware

注意:除了这里显示支持,还要启动BIOS的虚拟化设置,确认开启CPU虚拟化

安装 KVM 相关依赖包

1
2
3
4
5
6
7
8
9
sudo apt install qemu-kvm
# gui虚拟机管理工具,类似于windows上的vmware workstation
sudo apt install virt-manager
sudo apt install virt-viewer
# 虚拟机创建(virt-install)和克隆工具(vrit-clone)等
sudo apt install virtinst
sudo apt install libvirt-bin
# Linux 系统网桥管理工具 brctl
sudo apt install bridge-utils

检查一下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

参考链接

KVM 介绍(1):简介及安装
Dive into the KVM hypervisor
什么是KVM?

作者

莫尔索

发布于

2020-05-02

更新于

2024-05-24

许可协议

评论