【转】采用 Linux* Containers 的单根输入/输出虚拟化 (SR-IOV)

https://software.intel.com/zh-cn/articles/single-root-inputoutput-virtualization-sr-iov-with-linux-containers

目录

要点综述
摘要

目录

  1. 简介 
  2. 硬件和软件设置
  3. SR-IOV 在操作系统中的配置
  4. 测试
  5. 结论
  6. 参考书目

附录 A: 控制容器中的资源使用

附录 B: 其它资源

要点综述

虚拟化是一项在软件和硬件之间提供抽象层的技术。 它可以模拟硬件平台,提供各种资源的操作系统抽象。 它还可以帮助轻松管理硬件资源,以及在云端运行服务。 但是,传统基于管理程序的虚拟化的主要优势之一是,无论内存和 CPU1 的使用如何,它都会产生大量的开支。 Linux* Containers (缩写为 LXC)是传统方法的轻量级替代方案,可帮助划分命名空间和文件系统,同时在一个内核上运行所有线程。 结合使用单根输入/输出虚拟化(缩写为 SR-IOV),它提供的解决方案支持容器在网络中显示为单独的计算节点,并且带有独有的 MAC2 地址,同时能够共享一个链接和物理网络适配器。

本文是 CERN openlab 和英特尔共同研究的成果,旨在调查 Linux Containers 是否能够结合 SR-IOV 使用,并对 CERN 数据中心内的现有的虚拟化基础设施提供补充。 该解决方案可以运用到存储节点中,从而主要用于输入/输出操作,并让 CPU 在大部分时间内处于闲置状态。 通过在一个存储节点的容器中同时运行 CPU 密集型和存储作业,并确保两种应用完全分离以及对消耗的资源进行完全控制,CERN 能够从 LXC/SR-IOV 获得诸多优势。

我们介绍了一次 Linux Containers 的成功设置,设置基于英特尔® 万兆以太网适配器,并包含 SR-IOV 支持和网络与存储综合基准测试的结果。

作者: Pawel Szostek (CERN openlab ) 和 Marco Righini (英特尔)

1 中央处理单元

2 媒体访问控制

摘要

本文调查了在 CERN 环境中结合配置 SR-IOV 和 LXC 的可能性,其中采用了 CERN 中最新操作系统成果 (CERN CentOS* 7)。 我们展示了运营配置所需的所有步骤。 我们还展示了此配置下运行的基本网络和存储基准测试所得出的结果。 我们的结果证明,技术堆栈能够使用。 但是,当运行密集 I/O 运营时,系统性能会出现小幅下降。 未来的工作包括在目标技术堆栈上运行性能和可靠性测试。

1. 简介

Linux Containers 是什么?

Linux* Containers 缩写为 LXC,是 Linux 内核中的一款特性,支持在进程的命名空间和文件系统内对其进行划分,同时确保其在相同的内核上运行。 如多种研究(Xavier 等,2013 年;Kjallman 等,2015 年)所示,其性能开销低于基于管理程序的系统,但是灵活性和可管理性会降低。 LXC 可与 cgroups 绑定在一起使用,支持控制硬件资源在容器内的使用,从而更好地划分不同容器内运行的应用。

LXC 不同于 Docker:前者可提供轻量级的命名空间划分功能,同时不需要传统的虚拟机开销,而后者是一个独立的应用虚拟化引擎,可在容器上运行。 它与 LXC 有明显的区别,需要在一个单独的应用上运行,并将其依赖性闭合在一个映像中。 默认情况下,Docker 会禁用存储持久性,使映像在执行时处于无状态。

SR-IOV 是什么?

单根 I/O3 虚拟化 (SR-IOV) 是 PCI 特别兴趣小组 (PCI-SIG) 针对 I/O 虚拟化的规范。 它提供了一种标准机制,支持设备曝露其能力,以便在多个虚拟机间同时共享。 它还支持将 PCI 功能划分为多个虚拟接口,以便在虚拟环境中共享 PCI Express*(PCIe)设备的资源。

根据物理设备和内核端支持的不同,一个系统内可启用不同数量的虚拟功能。 对于本文,我们使用了英特尔 X520 插卡,可为每个端口提供多达 64 种虚拟功能。 每种功能可指派到一个容器,该容器将在其整个生命周期过程中对其享有所属权。 因此,设备将在网络中显示为独立的节点,其流量为完全隔离。

整体概况

CERN 数据中心位于全球 LHC 计算网格的中心。 该机构负责收集、存储和处理 LHC 实验的数据。 它托管了近 110,000 个处理器内核和 11,000 台服务器,全天候运行,确保服务不间断。 CERN 数据中心的所有节点都可以根据其使用案例划分为几种类型。 在本文中,我们主要介绍存储前端节点,这些节点主要用于收集实验数据,并根据需求将该数据提供给计算节点。 它们的 CPU 利用率较低,使用永久性存储资源较密集。 本篇 Openlab 中介绍的调查旨在探寻使用 Linux Containers 在不降低存储可靠性的前提下提供除存储服务器之外更多计算资源的可能性。 图 1 展示了目标设置的图表。

Example Of a Storage Node Configuration

图 1:存储节点配置示例。

EOS 是 CERN 中针对大型物理数据使用的磁盘存储系统,需要密集的 I/O,对计算资源有中等程度的需求。 Boinc 是一款用于数据处理的分布式应用 — 属于 CPU 密集型操作,I/O 较低。 在目标配置中,EOS 和 Boinc 将在一个存储节点上运行。 这样的设置支持更好地利用 CPU (目前利用率较低),同时能够将不同的应用隔离开,并为其提供必要的硬件资源。 为此,SR-IOV 支持我们创建多个虚拟网络接口,以便在容器内独立使用,同时 cgroups 可提供资源划分的功能。

在本文中,我们介绍了使用一些易于运行的综合基准测试对采用 SR-IOV 的 LXC 设置进行的测试。 我们无法调查图 1 中介绍的目标配置,因为这种设置非常复杂、耗时且易于出错。 我们主要运行了一些综合性基准测试,旨在强调与 I/O 有关的硬件资源。

3 输出/输出(操作)

2. 硬件和软件设置

节点测试的配置是一个包含 24 块日立 HUA72302 A800 硬盘的 JBOD 阵列和一个采用 SR-IOV 支持的英特尔® 82599ES 万兆以太网适配器。 此外,系统主板上还集成了一个数据和一个管理千兆以太网端口。

该机器的启动系统是采用 3.10.0-123.13.2.el7.x86_64 内核和 CERN 特定插件的预生产 CentOS* 7。 安装标准包,除非明确提及。

BIOS 配置

SR-IOV 要求以下 BIOS 设置正确执行: 启用 VT,启用 SR-IOV,禁用 VT-D。

3. SR-IOV 在操作系统中的配置

在本部分内容中,我们将具体介绍在测试系统上获取可使用的 SR-IOV 设置所需的全部步骤。 在本文的其他内容中,主机将称为 p01001534852033,容器将称为 centos1 和 centos2。

首先,我们确保以太网适配器能够在系统中看到。 因为它们是 PCIe 设备,所以我们使用了 lspci 命令:

[root@p01001534852033 tmp]# lspci | grep 10-Gig 04:00.0 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01) 04:00.1 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01)

采用的插卡的内核驱动程序已在英特尔网站上公开发布。 下载驱动程序后,我们将其解包,构建并安装 ixgbe 和 ixgbevf 内核模块:

1 tar xvzf ixgbe-*.tar.gz
2 cd ixgbe-*/src
3 make install
4 cd ../..
5 tar xvzf ixgbevf-*.tar.gz
6 cd ixgbevf-*/src
7 make install

然后,我们对系统进行配置,使其在启动时自动加载内核模块:

echo "ixgbevf\nixgbe" >> /etc/modules-load.d/modules.conf

此外,ixgbe 驱动程序要求安装大尺寸的虚拟内存页面(又称大内存页):

mkdir -p /mnt/huge chmod 777 /mnt/huge echo "huge /mnt/huge" hugetlbfs defaults 0 0 echo "vm.nr_hugepagesz=2M" >> /etc/sysctl.conf

驱动程序要求在启动时将以下参数传递到内核:

intel_iommu=off default_hugepagesz=2M hugepagesz=2M ixgbe.max_vfs=8,8.

最后一个参数指定了每个物理接口可用的虚拟接口数量。 在本案例中,我们针对每个物理接口使用了 8 个虚拟接口。

为此,我们向 grub.cfg 添加了定制条目。 由于 CentOS7 使用 grub2,这一实施需要通过向 /etc/grub.d/40_custom 添加条目来间接完成。 以下条目克隆了其他额外添加了参数的条目。 如欲进一步了解详情,请参考 /boot/grub2/grub.cfg:

01 cat << EOF > /etc/grub.d/40_custom
02 menuentry 'CentOS Linux (3.10.0-123.9.3.el7.x86_64) 7 Intel setup' --classcentos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-123.el7.x86_64-advanced-3d81a16b-9af7-4ba0-ae53-ef16fb54f864' {
03         load_video
04         set gfxpayload=keep
05         insmod gzio
06         insmod part_msdos
07         insmod ext2
08         set root='hd0,msdos1'
09         if [ x$feature_platform_search_hint = xy ]; then
10           search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1'  0b7ebc67-f22d-4760-abd9-7503761e827f
11         else
12           search --no-floppy --fs-uuid --set=root 0b7ebc67-f22d-4760-abd9-7503761e827f
13         fi
14         linux16 /vmlinuz-3.10.0-123.8.1.el7.x86_64 root=/dev/mapper/cc_p01001534852033-root ro rd.lvm.lv=cc_p01001534852033/swap crashkernel=auto  vconsole.font=latarcyrheb-sun16 rd.lvm.lv=cc_p01001534852033/root vconsole.keymap=us rhgb quiet LANG=en_US.UTF-8 intel_iommu=off default_hugepagesz=2M hugepagesz=2M ixgbe.max_vfs=8,8
15         initrd16 /initramfs-3.10.0-123.8.3.el7.x86_64.img
16 }
17 EOF

接下来,我们重新创建了 GRUB2 配置文件,并将其添加到最后的变更中:

grub2-mkconfig --output=/boot/grub2/grub.cfg

最后,我们重启了系统,以检查与 SR-IOV 相关的配置是否正确,以及在每次重启时是否可复制。

当系统使用新参数重启后,我们测试虚拟功能是否在系统中可见。 如果它们未被 lspci 列出,则说明驱动程序未加载或加载错误(在这种情况下,请参考 lsmod 和 dmesg)。

01 [root@p01001534852033 tmp]# lspci | grep -i virt
02 00:11.0 PCI bridge: Intel Corporation C600/X79 series chipset PCI Express Virtual Root Port (rev 06)
03 04:10.0 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
04 04:10.1 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
05 04:10.2 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
06 04:10.3 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
07 04:10.4 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
08 04:10.5 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
09 04:10.6 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
10 04:10.7 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
11 04:11.0 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
12 04:11.1 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
13 04:11.2 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
14 04:11.3 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
15 04:11.4 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
16 04:11.5 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
17 04:11.6 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
18 04:11.7 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)

我们再次检查了大内存页是否已加载:

1 [root@p01001534852033 tmp]# mount | grep huge
2 cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
3 hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime)
4 huge on /mnt/huge type hugetlbfs (rw,relatime)

此外, ifconfig 应报告所有虚拟接口:

01 [root@p01001534852033 ~]# ifconfig | grep enp4s | cut -c 1-53
02 enp4s16: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>
03 enp4s17: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>
04 enp4s0f0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>
05 enp4s0f1: flags=4099<UP,BROADCAST,MULTICAST>  mtu 150
06 enp4s16f2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>
07 enp4s16f4: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>
08 enp4s16f6: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>
09 enp4s17f2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>
10 enp4s17f4: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>
11 enp4s17f6: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>

如果不是这种情况,请尝试重新加载 ixgbe 和 ixgbevf。 但是,如果您使用 SSH 连接机器,连接将断开。 这可通过运行以下命令来避免。

nohup 'rmmod ixgbe && rmmod ixgbevf && insmod ixgbe && insmod ixgbevf'.

请注意,ixgbevf 应在 ixgbe 后加载,否则系统将不会报告虚拟功能。

当制定解决方案时,我们在 CentOS7 LXC 模板中偶然发现了一个漏洞,导致容器启动非常慢4。 该漏洞可通过在模板文件上添加补丁来修复5。

上述提到的配置就位后,我们将重新创建一个新的 CentOS 容器:

lxc-create -t centos -n centos1

在启动容器之前,我们需要更改其设置,以便其不使用桥接网络适配器,而使用虚拟功能。 示例配置如下:

01 [root@p01001534852033 tmp]# cat /var/lib/lxc/centos1/config
02 lxc.autodev = 1
03 lxc.network.type = phys # was veth
04 lxc.network.flags = up
05 lxc.network.link = enp4s16f1  # was virbr0
06 lxc.rootfs = /var/lib/lxc/centos1/rootfs
07 lxc.include = /usr/share/lxc/config/centos.common.conf
08 lxc.arch = x86_64
09 lxc.utsname = centos1.cern.ch
10 lxc.autodev = 1

ixgbevf 内核模块每次加载时,虚拟功能便会指派新的 MAC 地址。 为了防止其出现不当后果(如通过 CERN 网络以错误路线发送数据包),我们使用了下面的 Python 脚本重置地址。 我们意识到,这并不是最佳解决方案,但是可以作为临时的解决办法。

01 #!/usr/bin/env python
02 import subprocess
03 intf_mac_list0 = [("enp4s16","d6:d6:d6:54:f9:f8"),
04 ("enp4s16f2""ee:2b:1d:e6:f7:aa"),
05 ("enp4s16f4""1e:99:1e:f0:bb:64"),
06 ("enp4s16f6""6e:82:0c:ff:f8:47"),
07 ("enp4s17",   "da:61:59:96:ab:1d"),
08 ("enp4s17f2""fe:66:3f:87:74:12"),
09 ("enp4s17f4""72:7b:1a:0c:bf:fc"),
10 ("enp4s17f6""46:02:c9:b1:3a:a7")]
11  
12 intf_mac_list1 = [("enp4s16f1""7a:e7:81:9c:43:38"),
13 ("enp4s16f3",  "ca:fa:89:58:95:92"),
14 ("enp4s16f5",  "ba:7d:2e:d3:1b:96"),
15 ("enp4s16f7",  "3e:72:0d:07:2b:e9"),
16 ("enp4s17f1",  "52:7b:24:90:11:01"),
17 ("enp4s17f3",  "fe:14:4f:45:6d:49"),
18 ("enp4s17f5",  "86:1e:f4:cc:fa:bb"),
19 ("enp4s17f7",  "0a:93:df:2e:62:2b")]
20  
21 for idx, tup in enumerate(intf_mac_list0):
22     intf, mac = tup
23     cmd = "ip link set %s vf %d mac %s" % ("enp4s0f0", idx, mac)
24     print(cmd)
25     subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
26  
27 for idx, tup in enumerate(intf_mac_list1):
28     intf, mac = tup
29     cmd = "ip link set %s vf %d mac %s" % ("enp4s0f1", idx, mac)
30     print(cmd)
31     subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,
32 stdout=subprocess.PIPE)

最后,我们可以运行容器,并连接至其终端:

1 [root@p01001534852033 ~]# lxc-start –d -n centos1
2 [root@p01001534852033 ~]# lxc-attach -n centos1
3 [root@centos1 ~]#

https://lists.linuxcontainers.org/pipermail/lxc-users/2014-July/007443.html
https://github.com/tukiyo/lxc/commit/dbf45a526bf5a2f0503737b0b68d244e9389a2a7

4. 测试

网络带宽测试

我们执行了非常简单的测试,以证明容器内外获取的网络带宽处于同一水平。 为此,我们设置了两台机器,并使 10GbE 网卡连接至相同的 10GbE 以太网交换机。 我们使用了 iperf3,对客户端至服务器的数据传输进行测试。 我们的客户端是放置容器的机器,服务器是直接与同一台交换机相连的另一台机器 (cd1001534-0004132575)。 首先,我们在容器内外同时运行基准测试并测量带宽。 然后,我们以反向模式重复测试,如让流量从服务器流向客户端。 结果显示,链接是对称的,而且使用 LXC 不会影响此配置中的网络流量。

01 [root@centos2 ~]# iperf3 -c cd1001534-0004132575 -O 3 -t 20
02 Connecting to host cd1001534-0004132575, port 5201
03
04 - - - - - - - - - - - - - - - - - - - - - - - - -
05 [ ID] Interval           Transfer     Bandwidth       Retr
06 [  4]   0.00-20.00  sec  21.9 GBytes  9.41 Gbits/sec    0             sender
07 [  4]   0.00-20.00  sec  22.0 GBytes  9.43 Gbits/sec                  receiver
08  
09 [root@p010001534074188 ~]# iperf3 -c cd1001534-0004132575 -O 3 -t 20
10
11 - - - - - - - - - - - - - - - - - - - - - - - - -
12 [ ID] Interval           Transfer     Bandwidth       Retr
13 [  4]   0.00-20.00  sec  21.9 GBytes  9.41 Gbits/sec  0             sender
14 [  4]   0.00-20.00  sec  21.9 GBytes  9.40 Gbits/sec                receiver

磁盘测试

在我们的测试中,我们想要了解在访问驱动器时软件堆栈中是否有任何限制。 我们运行了两个磁盘基准测试 — iozone 和 ssdbench。 前者旨在测试磁盘吞吐量,在位于通过 SAS HBA 连接的 JBOD 阵列中的外部 HGST HUA72302 硬盘上运行。 第二个基准测试主要针对固态盘的吞吐量和 IOPS,在插入 PCIe 插槽的英特尔固态盘 DC P3700 400GB 上运行。

硬盘

对于此基准测试,我们通过 LSI 9207-8e SAS 主机总线适配器将测试系统连接到采用 HGST HUA72302 2TB 硬盘的外部 JBOD 阵列。 iozone 测试旨在模仿 CASTOR (CERN 高级 STORage 管理器)执行的访问。 在所测试的每台设备上,我们创建了一个 XFS 文件系统,该系统使用以下选项进行安装:

logbufs=8,logbsize=256k,noatime,swalloc,inode64.

在第一个测试中,我们分别测量了每台设备读写操作的最大吞吐量。 我们运行了四次测试,然后计算了顺序读取、随机读取、顺序写入、随机写入和混合工作负载的平均值。 使用的命令如下所示:

for i in `seq 1 4`; do /opt/iozone/bin/iozone -R -I -l 1 -u 1 -r 1m -s 4g -F /srv/castor/{drive}/iozone.dat | tee -a iozone-1m-4g-first-disk-loop-"$i".txt; done

第二个测试对 9 块硬盘上的同步读写进行了测试。 我们使用了以下命令:

for i in `seq 1 4`; do /opt/iozone/bin/iozone -R -I -l 9 -u 9 -r 1m -s 4g –F /srv/castor/{1,2,3,4,5,6,7,8,9}/iozone.dat | tee -a iozone-1m-4g-24fs-loop-"$i".txt; done

操作系统上和容器内获取的结果差别不到 1%。 主机操作系统上获取的值如图 2 所示。

Spinning Drive I/O Performance

图 2:硬盘 I/O 性能

固态盘

为了测试采用高带宽和低延迟硬盘的设置,我们为系统配备了英特尔 DC P3700 400GB 固态盘,通过 PCIe gen. 3 总线连接。为了访问硬盘,我们使用了 fio 命令,可为硬盘上的各种操作提供便捷的接口。 通过此测试,我们希望检查容器内 I/O 操作的软件堆栈上是否有任何限制会对 IOPS、吞吐量或延迟产生影响。

在我们的试验中,我们执行了以下测试:

  • 单线程 512B 顺序写入,采用多种队列深度
  • 单线程顺序写入,采用多种块尺寸
  • 持续 4kB 随机读取,采用多种线程数量
  • 持续多线程随机读取,采用多种块尺寸
  • 持续 4kB 随机混合访问,采用多种线程数量
  • 持续 4kB 随机写入,采用多种线程数量
  • 持续随机写入,采用多种线程数量

在大多数情况下,容器内外的结构差异不超过 1%。 但是,当在更大的块 (32kB 和 64kB) 上运行测试时,IOPS、带宽和延迟明显不如容器内。 这些结果可参见表 1 和表 2。

块 (B)

IOPS (主机)

IOPS (LXC)

IOPS 惩罚

带宽6
(MB/秒,主机)

带宽
(MB/秒, LXC)

带宽
惩罚

读取延迟
(主机)

读取延迟
(LXC)

惩罚

512

477094

477091

-0.00%

244

244

-0.00%

1070.81

1070.55

-0.02%

1024

497015

499390

-0.48%

508

511

-0.59%

1027.77

1022.66

-0.50%

2048

469362

472190

-0.60%

961

967

-0.62%

1088.18

1081.56

-0.61%

4096

389633

392483

-0.73%

1595

1607

-0.75%

1311.51

1301.63

-0.75%

8192

206444

205842

0.29%

1691

1686

0.30%

2477.98

2484.89

0.28%

16384

103754

103441

0.30%

1699

1694

0.29%

4932.13

4946.21

0.29%

32768

44451

23158

47.90%

1456

758

47.94%

11514.24

22100.29

91.94%

65536

14289

11889

16.80%

936

779

16.77%

35821.39

43051.09

20.18%

131072

2837

2865

-0.99%

371

375

-1.08%

180377.07

178622.08

-0.97%

表 1:持续多线程随机读取测试,按块尺寸划分,512 个线程,IO 队列深度= 1

块 (B)

IOPS (主机)

IOPS (LXC)

IOPS 惩罚

带宽
(MB/秒,主机)

带宽
(MB/秒, LXC)

带宽
惩罚

读取延迟
(主机)

读取延迟
(LXC)

读取
延迟
惩罚

4096

46040

46966

-2.01%

188

192

2.13%

19.83

19.54

-1.46%

8192

39340

38146

3.04%

322

312

-3.11%

23.48

24.28

3.41%

16384

27561

27243

1.15%

451

446

-1.11%

33.64

33.88

0.71%

32768

20531

16495

19.66%

672

540

-19.64%

46.59

57.78

24.02%

65536

13563

11395

15.98%

888

746

-15.99%

71.62

84.16

17.51%

表 2: 顺序单线程读取测试(按块尺寸划分),IO 队列深度 = 1

如上表所示,在使用较大尺寸的块时,性能会显著下降。 例如,在连续多线程读取基准测试运行中,我们在 32kB 块尺寸上获取的 IOPS 低 47.90%,带宽少 47.94%,延迟高 91.94%。 同样,在顺序单线程基准测试运行中,我们获取的 IOPS 低 19.66%,带宽低 19.64%,写入延迟高 24.02%。 在根据所测试的技术(SR-IOV、LXC、NVMe)设计计算系统时,应考虑到这些异常。

5. 结论

在我们的调查中,我们设法在 SR-IOV 上创建了一个能够正常运行的 Linux Containers 设置。 我们运行了网络和磁盘基准测试,结果显示设置能够正常运行,但是在访问固态盘时可能会出现微小的异常。 我们认为该技术堆栈可能会对 CERN 基础设施有用,如图 1.4 中所示,适用于 CERN 中的其他研究。

6. 参考书目

CERN 高级存储管理器 (CASTOR) http://castor.web.cern.ch/。

Kjallman J 和 Komu M 管理程序与轻量级虚拟化: 性能比较 [会议]// IEEE 云工程国际会议。 - 坦佩: IEEE,2015 年。 - pp. 386-393.

Xavier Miguel [等。] 高性能计算环境中基于容器的虚拟化的性能评估 [会议] // 并行、分布式和基于网络的处理。 - 贝尔法斯特: IEEE,2013 年。 - pp. 233-240.

附录 A: 控制容器中的资源使用

限制网络使用

Linux 流量控制器 (tc) 可用来轻松限制网络接口的流量。 比如下列的示例,将 eth0 上的带宽限制为 1kbps:

1 tc qdisc add dev eth0 handle 1: root htb default 11
2 tc class add dev eth0 parent 1: classid 1:1 htb rate 1kbps
3 tc class add dev eth0 parent 1:1 classid 1:11 htb rate 1kbps

如要删除 eth0 上的限制,只需要运行以下命令即可:

tc qdisc del dev eth0 root

限制其他资源的使用

Linux containers 支持限制每容器的资源使用。 限制可通过编辑 /var/lib/lxc/<container_name>/config 中的容器的配置文件以静态方式进行设置,也可使用 lxc-cgroups 命令以动态方式进行设置。 lxc-cgroups 命令的手动页面可对可用特性进行进一步解释。

支持块和字符设备在容器中的使用

默认情况下,系统中的块和字符设备在容器中不可见。 为了能够使用它们,需要在容器命名空间中重新创建设备文件。 到目前为止,我们发现的最好的方式是结合使用 autodev hook script 和相应的 cgroup 设置:

01 [root@p01001534852033 centos2]# cat config
02 --
03  
04 lxc.autodev = 1
05 lxc.hook.autodev = ./sd.sh
06 lxc.cgroup.devices.allow = b 8:* rwm
07 lxc.cgroup.devices.allow = b 259:* rwm
08  
09 [root@p01001534852033 centos2]# cat sd.sh
10 #!/bin/bash
11 cd ${LXC_ROOTFS_MOUNT}/dev
12 mknod sdc b 8 32
13 mknod sdd b 8 48
14 mknod sde b 8 64
15 mknod sdf b 8 80
16 mknod sdl b 8 176
17 mknod sdk b 8 160
18 mknod sdj b 8 144
19 mknod sdi b 8 128
20 mknod sdh b 8 112
21 mknod nvme0 c 10 58
22 mknod nvme0n1 b 259 0

附录 B: 其它资源

关于 Linux* Containers 的一般性文档

CentOS 7 LXC 模板问题

Cgroups

猜你喜欢

转载自blog.csdn.net/msdnchina/article/details/89643536