操作指南:在 InfiniBand 架构上部署 RDMA 加速的 Linux 容器 (LXD)

创建于 2019 年 6 月 30 日。本文档演示了在 Linux 容器 (LXC) 和 Mellanox 端到端 100 Gb/s InfiniBand (IB) 解决方案上部署 RDMA 加速应用程序的过程。

文档目录

创建于 2019 年 6 月 30 日

简介

本文档将演示在 Linux 容器 (LXC) 和 Mellanox 端到端 100 Gb/s InfiniBand (IB) 解决方案上部署 RDMA 加速应用程序的过程。

本文档描述了从源代码构建 LXD 容器 的过程,适用于 Ubuntu 16.04.2 LTS 和物理服务器上的 LXD 2.16。 我们将展示如何在主机和 LXD 容器上更新和安装 Mellanox 软件和硬件组件。

参考资料

设置概述

设备

1.png

服务器逻辑设计

2.png

服务器布线

在我们的参考中,我们将第一个端口连接到 InfiniBand 交换机,而不使用第二个端口。

3.png

网络配置

在我们的安装设置中,将使用两台服务器。 每台服务器将通过 100Gb IB 铜缆连接到 SB7700 交换机。在我们的案例中,交换机端口连接如下:

  • 第 1-2 端口 – 连接到主机服务器

服务器名称及网络配置如下:

服务器类型 服务器名称 内部网络 外部网络
Server 01 clx-mld-41 ib0: 12.12.12.41 eno1: From DHCP (reserved)
Server 02 clx-mld-42 ib0: 12.12.12.42 eno1: From DHCP (reserved)

部署指南

前提条件

更新 Ubuntu 软件包

要更新/升级 Ubuntu 软件包,请运行以下命令。

sudo apt-get update          # 获取可用更新列表
sudo apt-get upgrade -y      # 严格升级当前包

在 IB 交换机上启用子网管理器 (SM)

请参考 MLNX-OS 用户手册以熟悉交换机软件(位于 docs.nvidia.com/networking/)。 在开始使用 Mellanox 交换机之前,建议将交换机升级到最新的 MLNX-OS 版本。

有三种选择来确定 SM 的最佳位置:

  1. 在其中一个受管交换机上启用 SM。这是一个非常方便且快速的操作,使 InfiniBand 易于“即插即用”。
  2. 在一台或多台服务器上运行 /etc/init.d/opensmd。如果节点数达到 648 或更多,建议在服务器上运行 SM。
  3. 使用统一结构管理 (UFM®) 设备专用服务器。UFM 提供的功能远不止 SM。UFM 需要比现有交换机更强的计算能力,但不需要昂贵的服务器。不过,这增加了专用服务器的额外成本。

我们将仅解释选项 1 和 2。

选项 1:在交换机上配置 SM(所有 Mellanox 交换机系统均支持 MLNX-OS®)

要在其中一个受管交换机上启用 SM,请执行以下步骤。

  1. 登录交换机并进入配置模式:
Mellanox MLNX-OS Switch Management

switch login: admin
Password:
Last login: Wed Aug 12 23:39:01 on ttyS0

Mellanox Switch

switch [standalone: master] > enable
switch [standalone: master] # conf t
switch [standalone: master] (config)#
  1. 运行命令:
switch [standalone: master] (config)#ib sm
switch [standalone: master] (config)#
  1. 检查 SM 是否正在运行。运行:
switch [standalone: master] (config)#show ib sm
enable
switch [standalone: master] (config)#

要永久保存配置,请运行:

switch (config) # configuration write

选项 2:在服务器上配置 SM(如果已在交换机上启用 SM,请跳过此过程)

要在服务器上启动 OpenSM,只需在管理节点的命令行中运行 opensm

opensm

或者:

通过编辑 /etc/opensm/opensm.conf 文件,在头节点上自动启动 OpenSM。

通过运行以下命令创建配置文件:

opensm –config /etc/opensm/opensm.conf

编辑 /etc/opensm/opensm.conf 文件,添加以下行:

onboot=yes

初始安装后,OpenSM 已配置并运行默认路由算法。当运行多层胖树集群时,建议更改以下选项以创建最高效的路由算法,从而提供最佳性能:

–routing_engine=updn

有关 OpenSM 其他可配置属性的详细信息,请参阅 Mellanox OFED for Linux 用户手册中的“OpenSM – 子网管理器”章节。

在主机上安装适用于 Ubuntu 的 Mellanox OFED

本章介绍如何在安装了 Mellanox ConnectX®-5 网卡的单台主机上安装和测试 Mellanox OFED for Linux 软件包。更多信息请点击

操作指南:在 InfiniBand 架构上部署 RDMA 加速的 Linux 容器 (LXD)

简介

本文档演示了在 Linux 容器 (LXD) 上运行 RDMA 加速应用的部署流程。

前提条件

  • 一台安装了 Mellanox 网卡(HCA/NIC)的 Linux 主机。
  • 支持 RDMA 的 Linux 内核。
  • 已安装 LXD 容器管理工具。

步骤

1. 安装 Mellanox OFED

Mellanox OFED 是运行 RDMA 应用所需的驱动和库。请参考 Mellanox OFED for Linux 用户指南 进行安装。

下载 Mellanox OFED

  1. 确认系统已安装 Mellanox 网卡:

    lspci -v | grep Mellanox
    

    示例输出:

    4.png

  2. 根据操作系统下载 ISO 镜像。镜像名称格式为 MLNX_OFED_LINUX-<ver>-<OS label><CPUarch>.iso。可从 Mellanox 官网 > 产品 > Software > Infiniband/VPI Drivers > Mellanox OFED Linux (MLNX_OFED) > Download 下载。

    5.png

  3. 使用 MD5SUM 校验文件完整性:

    md5sum MLNX_OFED_LINUX-<ver>-<OS label>.tgz
    

安装 Mellanox OFED

MLNX_OFED 通过运行 mlnxofedinstall 脚本安装。该脚本会:

  • 检测当前内核
  • 卸载标准操作系统发行版或其他厂商的软件栈
  • 安装 MLNX_OFED_LINUX 二进制 RPM(如果适用于当前内核)
  • 识别已安装的 InfiniBand 和以太网网卡并自动升级固件

安装脚本会删除所有先前安装的 Mellanox OFED 包并重新安装。系统会提示确认删除旧包。

  1. 以 root 身份登录安装机器。

  2. 将下载的 tgz 文件复制到 /tmp

    cd /tmp
    tar -xzvf MLNX_OFED_LINUX-4.1-1.0.2.0-ubuntu16.04-x86_64.tgz
    cd MLNX_OFED_LINUX-4.1-1.0.2.0-ubuntu16.04-x86_64/
    
  3. 运行安装脚本:

    ./mlnxofedinstall
    
  4. 安装成功后重启:

    /etc/init.d/openibd restart
    reboot
    

    默认情况下,ConnectX®-5 VPI 的两个端口均初始化为 InfiniBand 端口。

  5. (可选)禁用设备上的第二个端口:

    识别网卡端口的 PCI ID:

    lspci | grep Mellanox
    

    示例输出:

    05:00.0 Infiniband controller: Mellanox Technologies Device 1019
    05:00.1 Infiniband controller: Mellanox Technologies Device 1019
    

    禁用第二个端口:

    echo 0000:05:00.1 > /sys/bus/pci/drivers/mlx5_core/unbind
    
  6. 检查端口模式是否为 InfiniBand:

    ibv_devinfo
    

    6.png

  7. 如果看到以下信息,则需要将端口类型更改为 InfiniBand:

    7.jpg

    ConnectX®-5 端口可单独配置为 InfiniBand 或以太网模式。使用 mlxconfig 脚本更改模式。

    注意:LINK_TYPE_P1=1 表示 InfiniBand 模式

    a. 启动 mst 并查看端口名称:

    mst start
    mst status
    

    b. 将两个端口模式更改为 InfiniBand:

    mlxconfig -d /dev/mst/mt4121_pciconf0 s LINK_TYPE_P1=1
    

    端口 1 设置为 IB 模式后重启:

    reboot
    

    每次重启后需要禁用第二个端口。

    c. 查询 InfiniBand 设备信息:

    ibv_devinfo
    
  8. 运行 ibdev2netdev 查看以太网设备与 IB 设备/端口的关联:

    ibdev2netdev
    ifconfig ib0 12.12.12.41 netmask 255.255.255.0
    
  9. 编辑 /etc/network/interfaces 文件,添加以下行:

    vim /etc/network/interfaces
    

    示例:

    auto eno1
    iface eno1 inet dhcp
    
    # 新行
    auto ib0
    iface ib0 inet static
    address 12.12.12.41
    netmask 255.255.255.0
    
  10. 检查网络配置是否正确:

    ifconfig -a
    

2. 安装和配置 LXD

安装 LXD

建议使用官方 Ubuntu PPA 安装 LXD(当前版本 2.16):

sudo apt-add-repository ppa:ubuntu-lxc/stable
sudo apt update
sudo apt dist-upgrade
sudo apt install lxd

配置 LXD

通过 lxd init 逐步配置存储和网络:

sudo lxd init

以下是 init 命令的执行示例。示例中配置了默认的 dir 存储后端和 lxdbr0 桥接网络。

该桥接默认未配置,仅通过 HTTP 代理提供 IPv6 链路本地连接。

强烈建议使用 ZFS,因为它支持 LXD 所需的所有功能,以提供最快、最可靠的容器体验。

Do you want to configure a new storage pool (yes/no) [default=yes]? Enter
Name of the new storage pool [default=default]: Enter
Name of the storage backend to use (dir, btrfs, lvm) [default=dir]: Enter
Would you like LXD to be available over the network (yes/no) [default=no]? Enter
Would you like stale cached images to be updated automatically (yes/no) [default=yes]? Enter
Would

(注:由于输入截断,后续配置步骤未完整显示,请根据实际提示完成配置。)

您想创建一个新的网络桥接 (yes/no) [default=yes]? Enter

新桥接应如何命名 [default=lxdbr0]? Enter

应使用哪个 IPv4 地址 (CIDR 子网表示法、"auto" 或 "none") [default=auto]? Enter

应使用哪个 IPv6 地址 (CIDR 子网表示法、"auto" 或 "none") [default=auto]? none

LXD 已成功配置。

然后您可以使用以下命令查看 "lxdbr0" 桥接配置:

lxc network show lxdbr0

其输出如下所示。

config:
  ipv4.address: 10.141.11.1/24
  ipv4.nat: "true"
  ipv6.address: none
description: ""
name: lxdbr0
type: bridge

准备容器的网络

创建一个 /etc/dnsmasq.conf.lab 文件:

vim /etc/dnsmasq.conf.lab

并添加以下行:

domain=lab-ml.cloudx.mlnx
# verbose
log-queries
log-dhcp
dhcp-option=6,8.8.8.8

运行以下命令以更改 IPv4 网络并添加 dnsmasq.conf.lab 配置:

lxc network set lxdbr0 ipv4.address 10.10.41.1/24
lxc network set lxdbr0 raw.dnsmasq "conf-file=/etc/dnsmasq.conf.lab"

并使用以下命令查看 "lxdbr0" 桥接配置:

lxc network show lxdbr0

其输出如下所示。

config:
  ipv4.address: 10.10.41.1/24
  ipv4.nat: "true"
  ipv6.address: none
  raw.dnsmasq: conf-file=/etc/dnsmasq.conf.lab
description: ""
name: lxdbr0
type: bridge

更改 LXD 服务配置以设置容器的静态 MAC 和 IP 地址(可选)

在每个主机上运行此过程。

编辑 lxd 服务文件:

vim /lib/systemd/system/lxd.service

添加以下行 ExecStartPost=/bin/bash -c 'rm -f /var/lib/lxd/networks/lxdbr0/dnsmasq.hosts && for i in {2..254}; do echo "00:16:3e:41:01:$(printf '%02x' $i),10.10.41.$i,c41$i" >> /var/lib/lxd/networks/lxdbr0/dnsmasq.hosts ; done'

(在其他主机上更改 c41):

[Service]
EnvironmentFile=-/etc/environment
ExecStartPre=/usr/lib/x86_64-linux-gnu/lxc/lxc-apparmor-load
ExecStart=/usr/bin/lxd --group lxd --logfile=/var/log/lxd/lxd.log
ExecStartPost=/usr/bin/lxd waitready --timeout=600
ExecStartPost=/bin/bash -c 'rm -f /var/lib/lxd/networks/lxdbr0/dnsmasq.hosts && for i in {2..254}; do echo "00:16:3e:41:01:$(printf '%02x' $i),10.10.41.$i,c41$i" >> /var/lib/lxd/networks/lxdbr0/dnsmasq.hosts ; done'

重启 lxd 服务:

systemctl daemon-reload
killall -SIGHUP dnsmasq
service lxd restart
service lxd status

检查 /var/lib/lxd/networks/lxdbr0/dnsmasq.hosts 文件:

cat /var/lib/lxd/networks/lxdbr0/dnsmasq.hosts
00:16:3e:41:01:02,10.10.41.2,c412
00:16:3e:41:01:03,10.10.41.3,c413
00:16:3e:41:01:04,10.10.41.4,c414
00:16:3e:41:01:05,10.10.41.5,c415
00:16:3e:41:01:06,10.10.41.6,c416
...

如果看不到,请重新运行 lxd 服务并再次检查:

service lxd restart

检查 LXD 服务状态:

service lxd status
lxd.service - LXD - main daemon
  Loaded: loaded (/lib/systemd/system/lxd.service; indirect; vendor preset: enabled)
  Drop-In: /etc/systemd/system/lxd.service.d
          override.conf
  Active: active (running) since Thu 2017-08-10 14:57:33 IDT; 3min 38s ago
    Docs: man:lxd(1)
  Process: 6406 ExecStartPost=/bin/bash -c rm -f /var/lib/lxd/networks/lxdbr0/dnsmasq.hosts && for i in {2..254};
  Process: 6326 ExecStartPost=/usr/bin/lxd waitready --timeout=600 (code=exited, status=0/SUCCESS)
  Process: 6314 ExecStartPre=/usr/lib/x86_64-linux-gnu/lxc/lxc-apparmor-load (code=exited, status=0/SUCCESS)
Main PID: 6325 (lxd)
  Memory: 10.1M
    CPU: 324ms
  CGroup: /system.slice/lxd.service
          6325 /usr/bin/lxd --group lxd --logfile=/var/log/lxd/lxd.log
          6391 dnsmasq --strict-order --bind-interfaces --pid-file=/var/lib/lxd/networks/lxdbr0/dnsmasq.pid --e
Aug 10 14:57:33 clx-mld-41 dnsmasq[6391]: using local addresses only for domain lxd
Aug 10 14:57:33 clx-mld-41 dnsmasq[6391]: reading /etc/resolv.conf
Aug 10 14:57:33 clx-mld-41 dnsmasq[6391]: using local addresses only for domain lxd
Aug 10 14:57:33 clx-mld-41 dnsmasq[6391]: using nameserver 10.141.119.41#53
Aug 10 14:57:33 clx-mld-41 dnsmasq[6391]: using nameserver 8.8.8.8#53
Aug 10 14:57:33 clx-mld-41 dnsmasq[6391]: read /etc/hosts - 5 addresses
Aug 10 14:57:33 clx-mld-41 dnsmasq-dhcp[6391]: read /var/lib/lxd/networks/lxdbr0/dnsmasq.hosts
Aug 10 14:57:33 clx-mld-41 dnsmasq[6391]: read /etc/hosts - 5 addresses
Aug 10 14:57:33 clx-mld-41 dnsmasq-dhcp[6391]: read /var/lib/lxd/networks/lxdbr0/dnsmasq.hosts
Aug 10 14:57:33 clx-mld-41 systemd[1]: Started LXD - main daemon.

并在每个主机上添加静态路由(示例在 host 43 上):

sudo route add -net 10.10.42.0/24 gw 12.12.12.42
sudo route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.10.42.0      12.12.12.42     255.255.255.0   UG    0      0        0 ib1
10.10.41.0      *               255.255.255.0   U     0      0        0 lxdbr0
10.141.119.0    *               255.255.255.0   U     0      0        0 enp129s0f0
12.12.12.0      *               255.255.255.0   U     0      0        0 ib1

准备 LXC 容器

默认情况下,LXD 创建非特权容器。这意味着容器中的 root 在主机上是非 root UID。它相对于容器拥有的资源具有特权,但相对于主机是非特权的,使得容器中的 root 大致相当于主机上的非特权用户。(主要例外是通过系统调用接口暴露的攻击面增加)

简而言之,在非特权容器中,65536 个 UID 被“移位”到容器中。例如,容器中的 UID 0 在主机上可能是 100000,容器中的 UID 1 是 100001,依此类推,直到 165535。UID 和 GID 的起始值分别由 /etc/subuid/etc/subgid 文件中的 'root' 条目决定。

我们需要请求容器在没有 UID 映射的情况下运行,通过将 security.privileged 标志设置为 true(在默认配置文件中更改):

lxc profile set default security.privileged true

注意:在这种情况下,容器中的 root 用户就是主机上的 root 用户。

在容器中运行 verbs 和基于 RDMA 的应用需要访问主机操作系统的 InfiniBand 设备(uverbs 接口)。可以通过运行以下命令(修改默认配置文件)将访问权限授予容器:

lxc profile device add default uverbs1 unix-char source=/dev/infiniband/uverbs1

可以通过检查 /dev/infiniband/ 文件夹的内容来查看主机的一些 InfiniBand 设备。

sudo ls /dev/infiniband
issm0 issm1 rdma_cm ucm0 ucm1 umad0 umad1 uverbs0 uverbs1
sudo ibdev2netdev
mlx5_0 port 1 ==> enp5s0f0 (Down)
mlx5_1 port 1 ==> ib0 (Up)

在我们的示例中,主机上有两个 mlx5_ 设备,因此在 /dev/infiniband 中对应两个 ucm、umad 和 uverbs 接口。 运行时,您可以选择将哪些设备暴露给哪些正在运行的容器。 在我们的示例中,当运行单个容器时,您可以选择将第二个 InfiniBand 设备暴露给正在运行的容器。

要显示默认配置文件,请运行:

lxc profile show default

您应该会看到类似以下的输出:

config:
  environment.http_proxy: ""
  security.privileged: "true"
  user.network_mode: ""
description: Default LXD profile
devices:
  eth0:
    nictype: bridged
    parent: lxdbr0
    type: nic
  root:
    path: /
    pool: default
    type: disk
  uverbs1:
    source: /dev/infiniband/uverbs1
    type: unix-char
name: default

创建新容器

创建容器的语法如下:

lxc init images:{distro}/{version}/{arch} {container-name-here}

要创建一个使用所有 8 个 GPU 的 Ubuntu 16.04 容器,请使用以下命令:

lxc init ubuntu:16.04 c432

为容器设置静态 MAC 地址:

lxc config set c412 volatile.eth0.hwaddr "00:16:3e:41:01:02"

这将创建一个新的 ubuntu 16.04 容器,可以通过以下命令确认:

lxc list

要将安装文件推送到容器中,请使用:

lxc file push MLNX_OFED_LINUX-4.1-1.0.2.0-ubuntu16.04-x86_64.tgz c412/tmp/

另一个可选操作是进行文件共享,将共享目录挂载到容器中,以便访问安装程序和示例文件。

lxc config device add c412 installs disk source=/root/installs path=/root/installs

启动容器:

lxc start c412

要登录并在容器 c412 中获得 shell 访问权限,请输入:

lxc exec c412 -- bash

安装容器

更新 Ubuntu 软件包

要更新/升级 Ubuntu 软件包,请运行以下命令。

sudo apt-get update          # 获取可用更新列表
sudo apt-get upgrade -y      # 严格升级当前包

在容器上安装 Mellanox OFED

验证系统是否安装了 Mellanox 网络适配器(HCA/NIC)。

apt-get install pciutils
lspci -v | grep Mellanox

安装 Mellanox OFED

MLNX_OFED 通过运行 mlnxofedinstall 脚本进行安装。安装脚本执行以下操作:

  • 发现当前安装的内核
  • 卸载标准操作系统发行版或其他供应商商业堆栈中的任何软件堆栈
  • 安装 MLNX_OFED_LINUX 二进制 RPM(如果它们适用于当前内核)
  • 识别当前安装的 InfiniBand 和以太网网络适配器,并自动升级固件

安装脚本会删除所有先前安装的 Mellanox OFED 包,并从头开始重新安装。系统会提示您确认删除旧包。

  1. 安装所需包:

    apt-get install -y net-tools ethtool perl lsb-release iproute2
    
  2. 以 root 身份登录安装机器。

    cd /tmp
    tar -xzvf MLNX_OFED_LINUX-4.1-1.0.2.0-ubuntu16.04-x86_64.tgz
    cd MLNX_OFED_LINUX-4.1-1.0.2.0-ubuntu16.04-x86_64/
    
  3. 运行安装脚本。

    ./mlnxofedinstall --user-space-only --without-fw-update -q
    
  4. 检查 mofed 版本和 uverbs:

    ofed_info -s
    

    MLNX_OFED_LINUX-4.1-1.0.2.0:

    ls /dev/infiniband/
    
    uverbs1
    
  5. 在容器中运行 IB 带宽压力测试:

    服务器 ib_write_bw -a -d mlx5_1 &
    客户端 ib_write_bw -a -F $Server_IP -d mlx5_1 --report_gbits

    通过这种方式,您可以在容器之间运行 IB 带宽压力测试。

完成!

相关文档

操作指南:在 InfiniBand 架构上部署 RDMA 加速的 Linux 容器 (LXD)

创建于 2019 年 6 月 30 日

简介

本文档将演示在 Linux 容器 (LXD) 上部署 RDMA 加速应用的流程。

标签