debian 10 中运行 xen

本文详细介绍了Xen虚拟机的安装、配置及管理流程,包括主机操作系统(Dom0)与客户机操作系统(DomU)的设置,解决设备文件生成、根分区挂载等问题,以及使用virt-manager进行管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

xen 相关知识

xen 主要由管理程序、主机操作系统(Dom0)、客户机操作系统(DomU) 组成。

管理程序用来生成、删除、管理虚拟机的 cpu 或内存等资源信息。主机操作系统具有向管理程序请求虚拟机环境控制处理的权限。主机操作系统中存在叫做 xend 的守护进程或者设备仿真器 qemu-dm 进程。

xend 是接受生成客户端操作系统请求的守护进程,从 xen 命令处接受处理要求,基金共有主机操作系统向管理程序请求生成虚拟机等。

qemu-dm 也称为设备模型,它是用来仿真虚拟机设备的进程,用来仿真 VGA 或 IDE 等设备。

安装 xen

执行如下命令安装 xen:

sudo apt-get install xen-hypervisor-4.11-amd64

安装过程输出的 log 中有与 grub 相关的信息,记录如下:

Including Xen overrides from /etc/default/grub.d/xen.cfg
WARNING: GRUB_DEFAULT changed to boot into Xen by default!
         Edit /etc/default/grub.d/xen.cfg to avoid this warning.
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-4.19.0-8-amd64
Found initrd image: /boot/initrd.img-4.19.0-8-amd64
Found linux image: /boot/vmlinuz-4.19.0-8-amd64
Found initrd image: /boot/initrd.img-4.19.0-8-amd64
Found linux image: /boot/vmlinuz-4.19.0-8-amd64
Found initrd image: /boot/initrd.img-4.19.0-8-amd64
Found linux image: /boot/vmlinuz-4.19.0-8-amd64
Found initrd image: /boot/initrd.img-4.19.0-8-amd64
done

安装成功后查看 /boot 目录,发现有添加新的文件。/boot 目录中文件内容列表如下:

longyu@virt-debian10:~$ ls /boot
config-4.19.0-8-amd64  initrd.img-4.19.0-8-amd64          System.map-4.19.0-8-amd64  xen-4.11-amd64.config  xen-4.11-amd64.gz
grub                   initrd.img-4.19.0-8-amd64-changed  vmlinuz-4.19.0-8-amd64     xen-4.11-amd64.efi

xen-xx 的文件是多出来的,这是我上一步执行的安装命令添加的。

运行 xen

执行 xen 命令有如下报警:

Can't find hypervisor information in sysfs

上述信息表明我当前系统不支持 hypervisor,上面我只是安装了 xen,要生效需要重启,并选择 xen 的引导项目。

进入系统后重新执行 xen 命令,有如下输出信息:

longyu@virt-debian10:~$ sudo xen list
Name                                        ID   Mem VCPUs	State	Time(s)
Domain-0                                     0  1893     7     r-----      11.4

Dom0 就是 xen 的主机操作系统,上述输出表明 xen 工作正常,主机操作系统正常运行。我执行 ps 命令查找与 xen 相关的进程,获取到了如下信息:

longyu@virt-debian10:~$ ps aux | grep xen
root        48  0.0  0.0      0     0 ?        S    20:58   0:00 [xenbus]
root        49  0.0  0.0      0     0 ?        S    20:58   0:00 [xenwatch]
root       588  0.0  0.2  15928  3800 ?        S    20:58   0:00 /usr/lib/xen-4.11/bin/oxenstored --pid-file /var/run/xenstore.pid
root       594  0.0  0.0  68512  1660 ?        Sl   20:58   0:00 /usr/lib/xen-4.11/bin/xenconsoled --pid-file /var/run/xenconsoled.pid
root       601  0.0  0.5 209492 10548 ?        Sl   20:58   0:00 /usr/bin/qemu-system-i386 -xen-domid 0 -xen-attach -name dom0 -nographic -M xenpv -daemonize -monitor /dev/null -serial /dev/null -parallel /dev/null -pidfile /var/run/qemu-dom0.pid

创建客户机操作系统 DOMU

确认主机操作系统正常运行后,就可以部署客户机操作系统 DOMU 了。

我参考《Linux 内核精髓-精通 Linux 内核的必会的 75 个绝技》一书,使用如下配置文件:

kernel = "/boot/vmlinuz-4.19.0-9-amd64"
ramdisk = "/boot/initrd.img-4.19.0-9-amd64"
memory = 1024
name = "debian"
disk = [ 'file:/home/longyu/xen.img,xvda1,w' ]
root = "/dev/xvda1,ro"
extra = " 3"

制作一个简单的根文件系统

上述配置文件中,xen.img 根文件系统是我按照《Linux 内核精髓-精通 Linux 内核的必会的 75 个绝技》一书指导制作的,主要的步骤如下:

  1. 使用 dd 生成一个固定大小的 xen.img 文件
  2. 使用 mkfs.ext4 为 xen.img 进行分区
  3. 挂载 xen.img 到 /mnt 目录下,拷贝一些必要的文件与目录到其中,然后卸载

这个 xen.img 相当于 rootfs,我们需要拷贝 /usr、/etc/、/bin 等信息,并根据情况修改 initab 脚本。

创建 xen 虚拟机

完成了 rootfs 的制作后,就可以执行 xl 命令创建虚拟机了。我执行如下命令创建一个配置文件为 debian 的 xen 虚拟机。

sudo xl create -c /etc/xen/debian

执行后开始打印内核初始化信息,在执行挂载 rootfs 的操作时报 No such file or directory 的错误。这个 No such file or directory 问题可能是 /dev/xvda1 设备文件没有生成,或者 /root 目录没有创建,根据我之前对 debian 启动过程的研究,我判断这个问题大概率应该是 /dev/xvda1 设备文件没有生成。

修改 initrd 确认问题

为了进一步确认问题,我修改 initrd 文件,在其中 init 脚本中直接调用 sh,这样下一次引导的时候就能够在 shell 中手动执行一些操作,确认问题。

我重新执行命令创建 xen 虚拟机,进入 shell 后,我直接 ls /dev/xvda1 ,发现确实没有这个文件。这个问题也不算是啥大问题,应该是某些驱动模块没有加载导致 /dev/xvda1 设备文件没有生成。

/dev/xvda1 设备文件如何生成

在之前研究 debian 的启动过程时,我发现设备文件的创建首先要加载相关的模块,模块内部可能有自动创建的处理,也可能需要 systemd-udevd 守护进程来创建。我搜索虚拟机中的进程,发现没有找到 systemd-udevd 守护进程。

百度了一下,发现可以执行 xl block-list 来显示 xen 虚拟机中的 block 设备列表,命令执行示例如下:

longyu@virt-debian10:~/xen-4.11.3+24-g14b62ab3e5/docs/misc$ sudo xl block-list debian
Vdev  BE  handle state evt-ch ring-ref BE-path                       
51713 0   11     1     -1     -1       /local/domain/0/backend/vbd/11/51713

根据这个结果,我确认 xen 虚拟机中已经 attach 了 xen.img block 设备。《Linux 内核精髓-精通 Linux 内核的必会的 75 个绝技》一书中在制作 initrd 的时候提到要指定 xennet、xenblk 驱动加入到 initrd,我没有在我的系统中搜索到这两个内核模块,同时也没有注意到其中提到的前端驱动程序的说法。

我判断这个问题应该是没有加载一些与 xen 相关的驱动。

于是我搜索 /lib 目录,搜索以 xen 开始的 .ko 文件,果然搜索到了一些。我同时查看宿主机中加载的 xen 模块,得到了如下信息:

longyu@virt-debian10:~$ sudo lsmod  | grep xen
xen_netback            65536  2
xen_blkback            49152  1
xen_gntdev             24576  1
xen_evtchn             16384  2
xenfs                  16384  1
xen_privcmd            24576  35 xenfs

我尝试在 xen 虚拟机中执行 modprobe xen-blkback,加载了后发现没有任何效果,同时继续加载 scsi_mod 与 sd_mod 模块,发现 /dev/xvda1 设备文件仍旧没有生成,这让我非常困惑。网上搜索了一下也没有找到类似的问题,感觉应该是要加载 xen 相关的一些内核模块就能生成,但是结果却失败了。

xen-blkfront 内核模块

一段时间的尝试后,我注意到了启动 xen 虚拟机时终端输出的如下行:

xenbus_probe_frontend: Device with no driver: device/vbd/51713

看到这一行,我确定这个问题就是没有加载需要的驱动。我继续在 /lib 中搜索 xen 相关的模块,这时我终于注意到了 xen-blkfront.ko 这个内核模块。我之前试过加载 xen-blkend.ko 没成功,但是可不可能是加载的模块不对呢?

我执行 modprobe 加载 xen-blkfront.ko 文件,终端中有如下输出信息:

Invalid max_queues (4), will use default max: 1.
blkfront: xvda1: flush diskcache: enabled; persistent grants: enabled; indirect descriptors: enabled;

从输出信息来看 /dev/xvda1 设备文件应该正常生成了,我执行 ls 命令查看,果然有了。这时我才意识到其实 Dom0 所在的宿主机中属于 backend,而其它的 xen guest 虚拟机都属于 frontend,故而需要加载 xen-xxfront 这种模块。

挂载根分区失败的问题

成功创建了 /dev/xvda1 设备文件后,我尝试执行 mount /dev/xvda1 /root 挂载根分区,结果却发现失败了。研究了下发现是没有指定分区的文件系统,添加了 -t ext4 后发现仍旧失败,这时我意识到没有加载 ext4 模块,成功加载 ext4 模块后,正常挂载,chroot 能成功执行。

使用 busybox 重新制作 initramfs 文件系统

我修改了 initrd.img-4.19.0-9-amd64 这个 initrd 文件内容,结果却发现进入系统后登录不成功,考虑到宿主机这个 initrd 里面包含了太多东西,我就尝试使用 busybox 来重新制作 initramfs 文件系统。

主要步骤如下:

  1. 获取 busybox 源码
  2. make menuconfig 选择静态编译后执行 make 命令进行编译
  3. make install 安装 busybox 工具链到 _install 目录中
  4. 修改 _instatll 目录中的文件,拷贝宿主机的 /lib 目录,添加 init 脚本重新制作 initrd

initrd 文件制作的问题

在 initrd 文件制作时,我遇到了一个小问题,这个小问题耽搁了我几个小时的时间。我最开始生成 initrd 文件的过程记录如下:

  1. cd _install
  2. find ./ -type f > list
  3. cpio -o -H newc -O initrd < list
  4. gzip initrd

表明上看来好像没有啥问题,但是当我尝试用制作出来的 initrd 文件来引导时,却发现内核直接 oops 了。输出信息中关联比较大的信息摘取如下:

Failed to execute /init (error -2)

上述信息表明 /init 脚本执行失败。我在标准错误值中搜索 -2,发现这个错误值表示的是 No such file or directory。我一度以为是 initrd 文件不对,对了下 md5 发现是一样的,重新生成了下发现还是有相同的问题。

在网上搜索了下,发现大部分问题都是说 init 文件没有加可执行权限,而且返回值是 -9。我检查了 initrd 制作目录下的 init 文件,确认权限正常。

我也检查了 list 文件中的项目,看到了一堆 ./libxxx 文件的内容就直接翻到了最后,看到了 init 文件在列表中。在 initrd 制作目录中执行 ls -l /bin/sh 查看 shell 命令也确实是有的

我静态编译了一个不断循环打印 hello world 的 c 程序,将它命名为 init,重新生成 initrd 文件,重新启动虚拟机,发现可以正常打印。

软链接问题

搞了几个小时,内心是奔溃的,没有搞定就将这个问题跳过了。晚上吃完放之后我又重新来看这个问题,我觉得应该是哪里没有整对,可能真的是没有文件。

有这个预期,我着重观察了下 initrd 制作目录下的文件,发现 /bin 下面除了 busybox 命令之外其它命令全部是指向 busybox 的软链接,我灵机一动,是不是软链接的问题呢?

我重新检查了下 list 中的文件列表,果然没有找到 /bin/sh 与其它的命令,只有 /bin/busybox 文件。

我意识到应该是 find -type f 的问题,不指定 -type f 直接搜索然后重新生成 list,生成后重新检查 list 发现这次有了 /bin/sh 等文件。

其实这里的问题在于 busybox 安装目录下的 /bin/ 目录中的 /bin/sh 命令是指向 busybox 命令的软链接,对于 find 来说它属于链接文件类型,所以 -type f 是不会检索出 /bin/sh 文件的,这意味着 list 中其实根本就没有这个文件,只不过我一直以为 initrd 制作目录下的 bin/sh 文件存在就以为 initrd 中也应该存在,其实两个完全没有关联。

重新生成 initrd 文件后这次终于成功了。

xen 虚拟机的启动脚本

最终我创建的 initrd 文件中的 init 脚本内容如下:

#!/bin/sh

mkdir -p /dev

mount -t devtmpfs -o nosuid,mode=0755 udev /dev

modprobe xen-blkfront
modprobe xen-netfront
modprobe xen-pcifront
modprobe ext4 

mkdir -p /root

mount -t ext4 /dev/xvda1 /root

mount -t sysfs -o nodev,noexec,nosuid sysfs /root/sys
mount -t proc -o nodev,noexec,nosuid proc /root/proc

exec chroot /root

上述脚本首先创建 /dev 目录,然后挂载 devtmpfs 虚拟文件系统,这之后再加载 xen-xxfront 驱动来生成设备文件,由于我制作的根文件系统分区格式是 ext4,这里需要加载 ext4 模块,最后挂载 sysfs 与 proc 虚拟文件系统,然后执行 chroot 切根就完成了所有的过程。

我使用的虚拟机配置文件内容如下:

kernel = "/boot/vmlinuz-4.19.0-8-amd64"
ramdisk = "/home/longyu/initrd.gz"
memory = 1024
name = "debian"
disk = [ 'file:/media/xen.img,xvda1,w' ]
root = "/dev/xvda1 rw"
extra = "3"
vif = [ 'mac=00:16:3E:74:34:32', 'mac=00:16:3e:5f:48:e4,bridge=xenbr0' ]

我配置了 bridge 网络,并设置了两个 xen 虚拟机的网络接口。xenbr0 是在宿主机上创建的网桥,网桥的创建与配置的具体过程详见:我的这篇博客

创建完成并配置 ip 地址后,创建虚拟机,执行 ifconfig -a 命令可以看到有 eth0、eth1、lo 这几个网络接口设备。相关信息如下:

root@(none):/# ifconfig -a
eth0: flags=4098<BROADCAST,MULTICAST>  mtu 1500
        ether 00:16:3e:74:34:32  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth1: flags=4098<BROADCAST,MULTICAST>  mtu 1500
        ether 00:16:3e:5f:48:e4  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=8<LOOPBACK>  mtu 65536
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

我执行 ifconfig eth0 192.168.122.49 来给 eth0 配置 ip 并将接口 up 起来,然后启动 sshd 服务。启动的时候报错说 /run/sshd 目录没有创建,创建后 sshd 命令成功执行。

我在宿主机上执行如下命令连接到 xen 虚拟机内:

[longyu@debian-10:18:44:47] ~ $ ssh longyu@192.168.122.49
ssh: connect to host 192.168.122.49 port 22: No route to host
[longyu@debian-10:19:07:44] ~ $ ssh longyu@192.168.122.49
PTY allocation request failed on channel 0
Linux (none) 4.19.0-8-amd64 #1 SMP Debian 4.19.98-1 (2020-01-26) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.

发现一直卡住不进入终端,使用 netstat -an 确认连接成功建立,使用 strace -p pid 跟踪,发现程序在 select 系统调用上阻塞。注意上面的信息中有如下行:

PTY allocation request failed on channel 0

这个问题以前遇到过,是没有虚拟终端能够分配,应该是我没有挂载 devpts 。我手动执行挂载 devpts :

mkdir /dev/pts
mount -t devpts devpts /dev/pts

断开重新连接,这之后就能够正常登录了。操作记录如下:

^C[longyu@debian-10:19:12:48] ~ $ ssh longyu@192.168.122.49
Linux (none) 4.19.0-8-amd64 #1 SMP Debian 4.19.98-1 (2020-01-26) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sun Aug  2 01:38:11 2020 from 192.168.122.1
longyu@(none):~$ 

使用 virt-manager 来管理 xen

在网上搜索资料时有看到 virt-manager 能够用来管理 xen 虚拟机,就尝试了下。首先点击 virt-manager 的 File 菜单,选择 Add Connection,选择后会弹出如下对话框:

在这里插入图片描述
在对话框中填入用户名与主机名,并勾选自动连接。结果却发现连接失败了,报错信息如下:
在这里插入图片描述
报错信息表明远程主机上 netcat/nc 的版本不支持 -U option,尝试不通过 ssh 连接仍旧失败,报错信息表明不通过 ssh 连接时,xen 虚拟机中要安装某种服务,但是显然我的虚拟机中并没有安装它,这个问题就到此为止。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值