操作指南:在 InfiniBand 结构上部署支持 RDMA 加速的 Docker 容器

创建于 2019 年 6 月 30 日。本文档演示了如何在 NVIDIA 端到端 100 Gb/s InfiniBand (IB) 解决方案上,在 Docker 容器中部署支持 RDMA 加速的应用程序。

文档目录

创建于 2019 年 6 月 30 日

简介

本文档将演示如何在 NVIDIA 端到端 100 Gb/s InfiniBand (IB) 解决方案上,在 Docker 容器中部署支持 RDMA 加速的应用程序。

我们使用 Ubuntu 16.04.6 LTS 作为主机操作系统,并安装最新的 Docker CE安装指南)。我们将展示如何在主机和 Docker 容器上更新和安装 NVIDIA 软件及硬件组件。

对于网络通信,每个 Docker 容器拥有 2 个设备:

  1. 用于 IP 连接的 Linux 桥接设备。该桥接连接到主机的 IPoIB 接口。
  2. 手动映射的 InfiniBand uverbs 设备,用于 RDMA 流量。

注意: 本指南适用于不包含 K8s 编排的 Docker 部署。如需 K8s 部署,请访问此链接:https://docs.mellanox.com/label/SOL/k8s

参考资料

设置概述

设备

1.png

服务器逻辑设计

2.png

Docker 网络图

3.png 服务器布线

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

4.png

网络配置

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

  • 第 1 至第 4 端口 – 连接到主机服务器

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

服务器类型 服务器名称 内部网络 外部网络
Server 01 clx-mld-41 ib0: 12.12.12.41 eno1: 来自 DHCP(保留)
Server 02 clx-mld-42 ib0: 12.12.12.42 eno1: 来自 DHCP(保留)
Server 03 clx-mld-43 ib0: 12.12.12.43 eno1: 来自 DHCP(保留)
Server 04 clx-mld-44 ib0: 12.12.12.44 eno1: 来自 DHCP(保留)

部署指南

前提条件

更新 Ubuntu 软件包

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

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

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

请参阅 MLNX-OS 用户手册以熟悉交换机软件(位于 enterprise-support.nvidia.com/s/)。

在开始使用 NVIDIA 交换机之前,建议将交换机升级到最新的 MLNX-OS 版本。

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

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

我们仅解释选项 1 和 2。

选项 1:在 MLNX-OS® 所有 NVIDIA 交换机系统上配置 SM。

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

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

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

MNVIDIASwitch

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(**<span style="color: #e23d39">如果已在交换机上启用 SM,请跳过此步骤</span>)**

要在服务器上启动 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 其他可配置属性的详细信息,请参阅 NVIDIA OFED for Linux 用户手册中的“OpenSM – 子网管理器”章节。

### 在主机上为 Ubuntu 安装 NVIDIA OFED

本章介绍如何在安装了 NVIDIA ConnectX®-5 网卡的单台主机上安装和测试 NVIDIA OFED for Linux 软件包。更多信息请点击 [NVIDIA OFED for Linux 用户手册](http://www.mellanox.com/related-docs/prod_software/Mellanox_OFED_Linux_User_Manual_v4.0.pdf)。

#### 下载 NVIDIA OFED

1. 验证系统已安装 NVIDIA 网卡(HCA/NIC)。

lspci -v | grep Mellanox


以下示例显示已安装 NVIDIA HCA 的系统:

![5.png](https://networking-docs.nvidia.com/sol/__attachments/a_fe83c56334afc70c5f6da1628b9a1c9e9e08282f74f97185b86640e2cd02e77a/5.png?cb=888918417fa50682d867f98f9329d0e9)

2. 根据您的操作系统将 ISO 镜像下载到主机。

镜像名称格式为 **MLNX_OFED_LINUX-<ver>-<OS label><CPUarch>.iso**。您可以从以下位置下载:

[https://www.nvidia.com/en-us/networking/](https://www.nvidia.com/en-us/networking/) > 产品 > 软件 > InfiniBand/VPI 驱动 > NVIDIA MLNX_OFED > [下载](https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/)。

![6.png](https://networking-docs.nvidia.com/sol/__attachments/a_fcaf94ef89c7130d2e0fd4d9b449e65a1bc83a1206e5b6c5fa1caca577ba641c/6.png?cb=80d4781f5d7c2a122486e9d09d5e91f0)

3. 使用 MD5SUM 工具确认下载文件的完整性。运行以下命令并将结果与下载页面上提供的值进行比较。

md5sum MLNX_OFED_LINUX--.tgz


#### 安装 NVIDIA OFED

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

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

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

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

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

cd /tmp tar -xzvf MLNX_OFED_LINUX-4.5-1.0.1.0-ubuntu16.04-x86_64.tgz cd MLNX_OFED_LINUX-4.5-1.0.1.0-ubuntu16.04-x86_64/


3. 运行安装脚本。

./mlnxofedinstall


4. 安装成功完成后重启。

/etc/init.d/openibd restart reboot


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

5. 检查端口模式是否为 InfiniBand。

ibv_devinfo


![7.png](https://networking-docs.nvidia.com/sol/__attachments/a_7355314fd7846ad4bada84fab75d645004c1b9557d6202712ec45853aa1f08a1/7.png?cb=de9b0f577447e10bce083c325d5cd142)

6. 如果看到以下内容,则需要将接口端口类型更改为 InfiniBand:

![8.jpg](https://networking-docs.nvidia.com/sol/__attachments/a_7c58bdb9b3dfbcb9bd3cfade6a50903537fafc0036fb3ed68e080f24cd8637a2/8.jpg?cb=f013525f9a4498481559cc89154ba1eb)

将接口端口类型更改为 InfiniBand 模式。ConnectX®-5 端口可以单独配置为 InfiniBand 或以太网端口。

将模式更改为 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

Port 1 set to IB mode

reboot


c. 查询 InfiniBand 设备并打印用户空间可用的信息:

ibv_devinfo


7. 运行 `ibdev2netdev` 工具查看以太网设备与 IB 设备/端口之间的所有关联。

ibdev2netdev

ifconfig ib0 12.12.12.41 netmask 255.255.255.0


8. 将以下行插入到 `/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


9. 检查网络配置是否正确设置。

ifconfig -a


### Docker 安装与配置

#### 卸载旧版本

要卸载旧版本,请运行:

旧版本,建议运行以下命令:

```bash
sudo apt-get remove docker docker-engine docker.io

如果 apt-get 报告未安装这些软件包,则无需担心。

/var/lib/docker/ 的内容(包括镜像、容器、卷和网络)将被保留。

安装 Docker CE

对于 Ubuntu 16.04 及更高版本,Linux 内核包含对 OverlayFS 的支持,Docker CE 将默认使用 overlay2 存储驱动。

使用仓库安装

在首次在新主机上安装 Docker CE 之前,需要设置 Docker 仓库。之后,您可以从仓库安装和更新 Docker。

设置仓库

  1. 更新 apt 包索引:

    sudo apt-get update
    
  2. 安装允许 apt 通过 HTTPS 使用仓库的软件包:

    sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
    
  3. 添加 Docker 的官方 GPG 密钥:

    sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    

    验证密钥指纹是否为 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88

    sudo apt-key fingerprint 0EBFCD88
    
    pub 4096R/0EBFCD88 2017-02-22
    Key fingerprint = 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
    uid Docker Release (CE deb) <docker@docker.com>
    sub 4096R/F273FCD8 2017-02-22
    

安装 Docker CE

安装最新版本的 Docker CE,或转到下一步安装特定版本。任何现有的 Docker 安装都将被替换。

sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get install docker-ce

自定义 docker0 桥接

配置 Docker 守护进程的推荐方法是使用 daemon.json 文件,该文件位于 Linux 上的 /etc/docker/ 中。如果文件不存在,请创建它。您可以指定以下一个或多个设置来配置默认桥接网络:

{
  "bip": "172.16.41.1/24",
  "fixed-cidr": "172.16.41.0/24",
  "mtu": 1500,
  "dns": ["8.8.8.8","8.8.4.4"]
}

相同的选项也可以作为 dockerd 的标志提供,每个选项的说明如下:

  • --bip=CIDR:为 docker0 桥接提供特定的 IP 地址和子网掩码,使用标准 CIDR 表示法。例如:172.16.41.1/16
  • --fixed-cidr=CIDR:限制 docker0 子网的 IP 范围,使用标准 CIDR 表示法。例如:172.16.41.0/16
  • --mtu=BYTES:覆盖 docker0 上的最大数据包长度。例如:1500
  • --dns=[]:要使用的 DNS 服务器。例如:--dns=8.8.8.8,8.8.4.4

修改 daemon.json 文件后,重新启动 Docker。

sudo /etc/init.d/docker restart

设置与外部世界的通信

检查内核中的 IP 转发:

sysctl net.ipv4.conf.all.forwarding
net.ipv4.conf.all.forwarding = 1

如果禁用:

sysctl net.ipv4.conf.all.forwarding
net.ipv4.conf.all.forwarding = 0

请启用并再次检查:

sysctl net.ipv4.conf.all.forwarding=1

出于安全原因,Docker 在 Linux 主机上配置 iptables 规则以防止容器转发来自主机外部的流量。Docker 将 FORWARD 链的默认策略设置为 DROP。

要覆盖此默认行为,您可以手动更改默认策略:

sudo iptables -P FORWARD ACCEPT

添加特定子网的 IP 路由

为其他主机上的容器网络添加路由:

sudo ip route add 172.16.42.0/24 via 12.12.12.42
sudo ip route add 172.16.43.0/24 via 12.12.12.43
sudo ip route add 172.16.44.0/24 via 12.12.12.44

快速检查

快速测试您的环境以确保一切设置正确:

docker run hello-world

创建或拉取基础镜像并运行容器

Docker 可以通过读取 Dockerfile 中的指令自动构建镜像。

Dockerfile 是一个文本文档,包含用户可以在命令行上调用的所有命令,用于组装镜像。

Dockerfile

  1. 创建一个空目录。
  2. 切换到新目录,创建一个名为 Dockerfile 的文件,将以下内容复制粘贴到该文件中并保存。注意注释解释了新 Dockerfile 中的每个语句。
FROM ubuntu16.04

# Set MOFED version, OS version and platform
ENV MOFED_VER 4.5-1.0.1.0
ENV OS_VER ubuntu16.04
ENV PLATFORM x86_64

RUN apt-get update
RUN apt-get -y install apt-utils
RUN apt-get install -y --allow-downgrades --allow-change-held-packages --no-install-recommends \
        build-essential cmake tcsh tcl tk \
        make git curl vim wget ca-certificates \
        iputils-ping net-tools ethtool \
        perl lsb-release python-libxml2 \
        iproute2 pciutils libnl-route-3-200 \
        kmod libnuma1 lsof openssh-server \
        swig libelf1 automake libglib2.0-0 \
        autoconf graphviz chrpath flex libnl-3-200 m4 \
        debhelper autotools-dev gfortran libltdl-dev && \
        rm -rf /rm -rf /var/lib/apt/lists/*

# Download and install NVIDIA OFED 4.5-1.0.1.0 for Ubuntu 16.04

RUN wget --quiet http://content.mellanox.com/ofed/MLNX_OFED-${MOFED_VER}/MLNX_OFED_LINUX-${MOFED_VER}-${OS_VER}-${PLATFORM}.tgz && \
    tar -xvf MLNX_OFED_LINUX-${MOFED_VER}-${OS_VER}-${PLATFORM}.tgz && \
    MLNX_OFED_LINUX-${MOFED_VER}-${OS_VER}-${PLATFORM}/mlnxofedinstall --user-space-only --without-fw-update -q && \
    cd .. && \
    rm -rf ${MOFED_DIR} && \
    rm -rf *.tgz

# Allow OpenSSH to talk to containers without asking for confirmation
RUN cat /etc/ssh/ssh_config | grep -v StrictHostKeyChecking > /etc/ssh/ssh_config.new && \
    echo "    StrictHostKeyChecking no" >> /etc/ssh/ssh_config.new && \
    mv /etc/ssh/ssh_config.new /etc/ssh/ssh_config

Docker 镜像并运行容器

  1. 现在运行构建命令。这将创建一个 Docker 镜像,我们使用 -t 为其标记一个友好的名称。

    docker build -t myofed451image .
    
  2. 构建的镜像在哪里?它在您机器的本地 Docker 镜像仓库中:

    docker images
    
  3. 以特权模式运行 Docker 容器(非

操作指南:在 InfiniBand 架构上部署支持 RDMA 加速的 Docker 容器

介绍

本文档演示了在 Docker 容器中运行 RDMA 加速应用的部署流程。

步骤

  1. 从远程仓库以特权模式运行容器:

    docker run -it --privileged --name=mnlx-verbs-prvlg --name=my-verbs-nonprvlg myofed451image bash
    

    或者

    docker run -it --cap-add=IPC_LOCK --device=/dev/infiniband/uverbs1 --name=my-verbs-nonprvlg myofed451image bash
    

基准测试

检查 NVIDIA OFED 版本和 uverbs

ofed_info -s
MLNX_OFED_LINUX-4.5-1.0.1.0
ls /dev/infiniband/uverbs1

在容器中运行 IB 带宽压力测试:

角色 命令
服务端 ib_write_bw -a -d mlx5_1 &
客户端 ib_write_bw -a -F $server_IP -d mlx5_1 --report_gbits

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

完成!

相关文档