Mctrain's Blog

What I learned in IT, as well as thought about life

Running Driver Domain on Xen

| Comments

又是一篇和Xen相关的教程,主要介绍如何在Xen里面启动一个网卡的driver domain(也被称为stub domain),也就是说,该虚拟机专门用来为其它虚拟机提供网络服务(而不是把所有这些服务都交给Domain 0来做)。

说句题外话,为什么最近这么多教程类型的博客,原因在于我发现每次我把这些东西记在博客里面的话,自己都会记得很深,但是记在Evernote里面经常就会忘记掉,况且记在博客里面还有可能为别人提供帮助,所以何乐而不为呢?

好了,废话说到这,开始进入正题。

为什么要使用driver domain

可以参看Xen的wiki

主要有四点原因:

  • 安全性:把权限从domain 0里面剥离出来,也就是说就算客户虚拟机控制了driver domain,也不能拿domain 0如何;
  • 可扩展性:driver domain的资源不受domain 0的限制,所有和设备相关的资源都和该driver domain相关;
  • 隔离性:其实和安全性有点重复,主要是说driver domain里面的进程不会和domain 0里面的进程产生竞争关系,不管从安全性还是性能方面都能提供比较好的隔离性;
  • 高性能:如果在domain 0里面运行driver的进程,那么会产生double scheduling的问题,即driver要工作,必须首先等domain 0被调度,然后等domain 0中和driver相关的进程被调度;但是如果用了driver domain的话就没有这个问题了,只要等driver domain被调度就可以了(因为在driver domain里面只有一个进程)。

使用driver domain可以提供多大的性能提升呢?可以参看这个slide

配置和启动driver domain

好,下面开始进入教程。

首先我们来一张使用网卡driver domain的架构图吧:

driver domain

其实主要就是如何进行网卡的passthrough,以及如何让客户虚拟机和driver domain进行匹配。

至于相关的参考资料嘛,可以参考这里

安装Xen和客户虚拟机

这个就不说了,参照上篇博客

Xen PCI Passthrough

参考资料来自这里

首先提一下IOMMU和PCI passthrough的关系:

在正常情况下,一个设备可被配置成DMA到任意的宿主机的物理内存,但是这样会有两个问题:

  • 第一,客户虚拟机可以利用它来任意写Xen的内存,这样会有安全问题;
  • 第二,对于HVM模式的客户虚拟机来说,它看到的内存是被虚拟化的,但是对于设备来说却不是这样的,也就是说正常情况下HVM的虚拟机是看不到被设备访问的那块内存的,也就无法使用那块内存。

那么如何让客户虚拟机的driver来操作真实硬件呢?这就引入了IOMMU,这套机制运行Xen来配置一个设备可以访问哪些内存,以及将这些内存也让客户虚拟机看到。

所以说,在有IOMMU支持的硬件上,设备可以被passthrough给HVM和PV虚拟机,而在没有IOMMU支持的设备上,如果设备被passthrough给PV虚拟机,虽然可以正常运行,但是会有安全问题,另外,设备不能被passthrough给HVM虚拟机,因为HVM虚拟机看不到设备访问的那块内存。

接下来我们就来看如何passthrough。

简单来说,我们需要先把网卡和domain 0的连接先给取消掉,然后再把它分配给driver domain

首先我们得先知道我们的网卡设备是哪一个,以及它所对应的BDF_Notation),这个可以通过:

$ lspci

查看,得到它的BDF是00:19.0:

nic bdf

之后,就可以利用xl这套xen-tool里面提供的命令来将其从domain 0里面移除,并且加进Xen的assignable的设备集合里面:

$ sudo xl pci-assignable-add 00:19.0

这个时候运行sudo xl pci-assignable-list就可以看到:

xl pci-assignale-list

这之后,就可以启动我们的driver domain了。配置启动文件:

driver-domain.cfg
1
2
3
4
5
6
7
builder="hvm"
name = "driver-domain"
memory = 1024
vcpus = 2
pci=[ '00:19.0' ]
disk = [ 'file:/path/to/vm.img,xvda,rw' ]
boot="cd"

注意,这里主要就是增加了一行:

dd.cfg
1
pci=[ '00:19.0' ]

然后启动虚拟机:

$ sudo xl create driver-domain.cfg

这个时候如果进到虚拟机里面看,会发现它多了一个PCI设备,且可以联网:

network in driver domain

而此时,宿主机已经连不上网了!

这里需要注意的是我们需要在这个driver domain里面安装xen-tools,以及配置桥接网络,取名为xenbr0,供之后的客户虚拟机使用。

network in driver domain 2

这些配置和domain 0里面的差不多,具体的可以参照我的上一篇博客

配置客户虚拟机

然后我们就可以配置客户虚拟机了,这一步非常简单,只需要在vif这个配置选项上的backend填上driver-domain(也就是driver domain的name),将bridge填上xenbr0(也就是driver domain的桥的名字)就可以了:

guest-vm.cfg
1
2
3
4
5
6
7
builder="hvm"
name = "guest vm"
memory = 1024
vcpus = 2
vif = [ 'bridge=xenbr0, model=e1000, backend=driver-domain']
disk = [ 'file:/path/to/vm2.img,xvda,rw' ]
boot="cd"

然后启动虚拟机:

$ sudo xl create guest-vm.cfg

进入虚拟机之后试一下,发现它果然可以上网啦!

guest vm


到这里,这一篇博客的内容就结束啦。

Comments