在容器(Docker)中启用eRDMA

eRDMA(Elastic Remote Direct Memory Access)是一种高性能网络通信技术,将eRDMA功能引入容器(Docker)环境可以实现容器应用程序绕过操作系统内核直接访问主机的物理eRDMA设备,从而提供更快的数据传输和通信效率,适用于在容器中需要大规模数据传输和高性能网络通信的应用场景。本文主要介绍如何在容器(Docker)中配置eRDMA,以及在自建k8s集群上如何使用eRDMA Controller组件在k8s pod上快速配置eRDMA。

使用限制

目前仅支持在以下Docker镜像中使用eRDMA功能。

  • Alibaba Cloud Linux 3/Ubuntu 22.04/24.04的镜像源(ARMx86实例均支持)

  • Alibaba Cloud Linux 2/CentOS 7/CentOS 8/Ubuntu 18.04/Ubuntu 20.04/24.04的镜像源(仅x86实例支持)

说明

暂不支持Anolis OS的镜像源。

实现原理

在容器环境中使用eRDMA功能时,使用Docker--device选项将/dev/infiniband/rdma_cm/dev/infiniband/uverbsX两个字符设备映射到容器中,这样容器内的用户态程序就可以绕过操作系统内核直接访问eRDMA设备进行数据的收发。

  • /dev/infiniband/rdma_cm:用于eRDMA连接管理的字符设备。用户态程序可以通过对这个字符设备的操作,与eRDMA设备进行连接的建立、销毁和管理,包括创建和销毁连接、发送和接收连接事件等操作。

  • /dev/infiniband/uverbsX:用于用户空间eRDMA操作的字符设备。用户态程序可以通过对这个字符设备的操作,与eRDMA设备进行通信,包括打开设备、创建和销毁eRDMA通信端点、注册和注销内存缓冲区等操作。

    说明

    /dev/infiniband/uverbsX中的X是设备的索引号,可能会因系统和配置而异,您可以运行ls /dev/infiniband | grep uverbs命令查看字符设备名称。

Docker容器中配置eRDMA

步骤一:为实例配置eRDMA

确认Docker所在实例的实例规格支持eRDMA、已绑定弹性RDMA网卡、已部署eRDMA驱动程序,同时eRDMA设备工作正常。

步骤二:(可选)为实例部署Docker

如果您的实例尚未部署Docker相关环境,无法使用Docker,您需要先在实例中安装Docker。

具体操作如下所示:

  1. 远程连接实例。

    具体操作,请参见使用Workbench登录Linux实例

  2. 执行以下命令,确认实例是否已部署Docker环境。

    sudo docker -v

    如果Docker已正确部署,则输出具体版本号,如下所示:

    image

    如果Docker尚未部署或出现异常,则可能出现如下执行结果,请您参考为实例部署Docker

    image

  3. 为实例部署Docker。

步骤三:(可选)Docker部署镜像

如果您的Docker环境尚未部署任何镜像,您可以根据实际应用需求,部署对应的镜像。

本文以Alibaba Cloud Linux基础镜像为例,在Docker中下载Alibaba Cloud Linux镜像(需要开通公网)。

具体操作如下所示:

  1. 安装Docker

  2. 执行以下命令,下载Alibaba Cloud LinuxDocker镜像。

    sudo docker pull alibaba-cloud-linux-<image_version>-registry.<region_ID>.cr.aliyuncs.com/alinux<image_version>/alinux<image_version>:<TAG>
    • <image_version>:Alibaba Cloud Linux的版本,例如23。

    • <region_ID>:Docker镜像所在的地域,例如cn-hangzhou

    • (可选)<TAG>:Docker镜像的版本。如果填写,表示下载指定版本的镜像。如果不填,默认下载最新版本的镜像。

    如何查看镜像所在的地域以及镜像版本信息?

    1. 访问容器镜像服务-制品中心

    2. 单击alinux2/alinux2alinux3/alinux3,查看Alibaba Cloud Linux 2Alibaba Cloud Linux 3Docker镜像版本信息。

      例如Alibaba Cloud Linux 3Docker镜像信息如下,①表示Docker镜像所在的地域,②表示Docker镜像的版本信息。

      image.png

    示例命令如下:

    • 在杭州地域下载220901.1版本的Alibaba Cloud Linux 3 Docker镜像

      sudo docker pull alibaba-cloud-linux-3-registry.cn-hangzhou.cr.aliyuncs.com/alinux3/alinux3:220901.1
    • 在杭州地域下载最新版本的Alibaba Cloud Linux 2 Docker镜像

      sudo docker pull alibaba-cloud-linux-2-registry.cn-hangzhou.cr.aliyuncs.com/alinux2/alinux2
  3. 执行以下命令,查看镜像是否下载成功。

    sudo docker images

    示例结果如下,表示已成功下载220901.1版本的Alibaba Cloud Linux 3 Docker镜像和最新版本的Alibaba Cloud Linux 2 Docker镜像。

    image.png

步骤四:启动容器并挂载eRDMA设备

使用Docker--device选项将/dev/infiniband/rdma_cm/dev/infiniband/uverbsX两个字符设备映射到容器中,这样容器内的用户态程序就可以绕过操作系统内核直接访问eRDMA设备进行数据的收发。详细信息,请参见实现原理

具体操作如下所示:

  1. 远程连接ECS实例。

    具体操作,请参见使用Workbench登录Linux实例

  2. 执行以下命令,启动一个Docker容器实例并将eRDMA对应的字符设备映射到容器中。

    sudo docker run --net=host --device=/dev/infiniband/uverbsX --device=/dev/infiniband/rdma_cm --ulimit memlock=-1 -t -i <IMAGE ID> /bin/bash

    参数说明如下:

    • --net=host:配置容器的通信模式为host。容器内的应用程序可以直接使用主机的网络接口和网络配置,从而实现与主机相同的网络通信能力。

    • --device=/dev/infiniband/uverbsX--device=/dev/infiniband/rdma_cm:将eRDMA对应的用户态字符设备暴露到容器中。

      执行以下命令,查看字符设备名称uverbsX中的X)

      ls /dev/infiniband | grep uverbs

      image

    • --ulimit memlock=-1:将maxlockedmemory设置为unlimited表示不限制非root用户锁定内存的数量。这可以确保eRDMA应用程序在非root用户下能够锁定所需的内存量,从而有效地使用eRDMA功能。

    • <IMAGE ID>:请根据实际环境填写Docker镜像的镜像ID,可以通过sudo docker images命令查看。

      执行以下命令,查看目标镜像ID

      sudo docker images

      本示例中,以步骤三中部署的Alibaba Cloud Linux镜像为例,执行结果如下:

      image

    本示例中执行命令

    sudo docker run --net=host --device=/dev/infiniband/uverbs0 --device=/dev/infiniband/rdma_cm --ulimit memlock=-1 -t -i e8d9a60b6967 /bin/bash

步骤五:为Docker容器部署eRDMA驱动程序包

在容器内使用eRDMA还需要部署eRDMA的用户态驱动程序包,否则在容器内部无法识别eRDMA设备信息。阿里云提供了yum、apt源,用于便捷部署相应的程序包。

具体操作如下所示:

  1. 远程连接实例。

    具体操作,请参见使用Workbench登录Linux实例

  2. 进入目标容器内部。

    如果您按照本文示例执行了步骤四的命令,那么已经直接进入Docker容器内部,直接在容器内安装用户态驱动包

    1. 执行以下命令,查看目标容器ID。

      sudo docker ps

      本示例中以步骤四中启动的容器为例,执行结果如下所示:

      image

    2. 执行以下命令,进入容器内部。

      sudo docker exec -it <CONTAINER ID> /bin/bash

      CONTAINER ID替换为上一步您实际查询的目标容器ID。

  3. 进入容器内部后,在容器内安装用户态驱动程序包。

    重要

    以下操作示例中,http://mirrors.cloud.aliyuncs.com表示内网源地址,如果您需要公网访问,需要将http://mirrors.cloud.aliyuncs.com替换为https://mirrors.aliyun.com使用公网会产生公网流量,进而可能产生额外费用。有关公网的计费规则,请参见公网带宽计费

    CentOS 7/CentOS 8

    1. 在容器中运行以下命令,在/etc/yum.repos.d目录中创建一个erdma.repo源文件。

      sudo vim /etc/yum.repos.d/erdma.repo
    2. erdma.repo文件中添加如下内容,然后保存退出。

      [erdma]
      name = ERDMA Repository
      baseurl = http://mirrors.cloud.aliyuncs.com/erdma/yum/redhat/$releasever/erdma/$basearch/
      gpgcheck = 1
      enabled = 1
      gpgkey = http://mirrors.cloud.aliyuncs.com/erdma/GPGKEY
    3. 运行以下命令,更新yum源缓存。

      sudo yum makecache
    4. 运行以下命令,安装用户态驱动包。

      sudo yum install  libibverbs rdma-core librdmacm libibverbs-utils -y 

    Alibaba Cloud Linux

    1. 在容器中运行以下命令,添加repo仓库。

      sudo yum-config-manager \
       --add-repo \
       http://mirrors.cloud.aliyuncs.com/erdma/yum/alinux/erdma.repo
      说明

      如果您的容器中没有安装yum-config-manager命令,请先运行sudo yum install -y yum-utils命令安装yum-utils包。yum-config-manageryum-utils包的一部分,用于管理yum配置。

    2. 运行以下命令,更新yum源缓存。

      sudo yum makecache
    3. 运行以下命令,安装用户态驱动包。

      sudo yum install  libibverbs rdma-core librdmacm libibverbs-utils -y

    Ubuntu 18.04/20.04/22.04/24.04

    1. 在容器中运行以下命令,添加PGP签名。

      • Ubuntu 18.04/Ubuntu 20.04

        wget -qO - http://mirrors.cloud.aliyuncs.com/erdma/GPGKEY | sudo apt-key add -
      • Ubuntu 22.04/24.04

        wget -qO - http://mirrors.cloud.aliyuncs.com/erdma/GPGKEY | sudo gpg --dearmour -o /etc/apt/trusted.gpg.d/erdma.gpg
    2. 运行以下命令,添加apt源。

      • Ubuntu 18.04

        echo "deb [ arch=amd64 ] http://mirrors.cloud.aliyuncs.com/erdma/apt/ubuntu bionic/erdma main" | sudo tee /etc/apt/sources.list.d/erdma.list
      • Ubuntu 20.04

        echo "deb [ arch=amd64 ] http://mirrors.cloud.aliyuncs.com/erdma/apt/ubuntu focal/erdma main" | sudo tee /etc/apt/sources.list.d/erdma.list
      • Ubuntu 22.04

        echo "deb [ ] http://mirrors.cloud.aliyuncs.com/erdma/apt/ubuntu jammy/erdma main" | sudo tee /etc/apt/sources.list.d/erdma.list
      • Ubuntu 24.04

        echo "deb [ ] http://mirrors.cloud.aliyuncs.com/erdma/apt/ubuntu noble/erdma main" | sudo tee /etc/apt/sources.list.d/erdma.list
    3. 运行以下命令,更新apt源。

      sudo apt update
    4. 运行以下命令,安装用户态驱动。

      sudo apt install libibverbs1 ibverbs-providers ibverbs-utils librdmacm1 -y 
  4. 执行以下命令,在容器内部查看eRDMA设备信息。

    ibv_devinfo

    image

    可以看到在容器内部,已经可以正常识别eRDMA设备。

Docker容器内配置eRDMA完成后,您可以通过SMC-R或者NetACCeRDMA集成到容器内部的TCP应用中,实现应用加速。详细信息,请参见应用适配概述

在自建k8s集群上使用eRDMA Controller部署eRDMA pod

步骤一:安装eRDMA Controller

  1. master节点执行以下命令,安装helm工具。

    该工具用于管理eRDMA Controller相关组件的安装和卸载。安装后通过helm version验证是否成功安装
    curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
    chmod 700 get_helm.sh
    ./get_helm.s
  2. 执行以下命令,在master节点上下载eRDMA Controller源码。

    git clone https://github.com/AliyunContainerService/alibabacloud-erdma-controller.git
  3. eRDMA Controller的安装配置文件是deployment/helm/values.yaml。通过修改此文件可以选择工作模式并配置相关参数。支持两种工作模式:

    • 常规模式 (Regular Mode):适用于需要eRDMA Controller自动管理ERI (Elastic RDMA Interface),并实现eRDMA资源动态分配的场景。

    • 本地模式 (Local Mode):适用于在k8s节点上已经完成eRDMA环境准备,并将eRDMA设备暴露给Pod的场景。不涉及eRDMA资源的动态管理。

    配置项说明:

    • localERIDiscovery:设置Controller的工作模式。

      • true:本地模式。

      • false:常规模式(默认)。

    • credentials: 在常规模式下,Controller需要访问阿里云API来查询和配置ECS实例及弹性网卡。因此,需先创建 RAM 角色并授予所需权限。

      目前支持AccessKey认证。将 type 设为 access_key,并填入AccessKey ID 和Secret。

      credentials:
        type: "access_key"
        accessKeyID: "{access key}"
        accessKeySecret: "{access key secret}"

      本地模式无需配置此项。

    • preferDriver: 设置节点使用的eRDMA驱动类型。

      • default:默认驱动模式。

      • compat:兼容RoCE驱动模式。

      • ofed:基于OFED的驱动模式,适用于GPU机型。

    • allocateAllDevices: 设置常规模式下的设备分配策略。

      • true:为Pod分配节点上的所有eRDMA设备。

      • false:根据NUMA拓扑为Pod分配一个eRDMA设备。

    • exposedLocalERIs: 设置本地模式下节点需暴露给PodeRDMA设备。配置格式见示例。

      exposedLocalERIs:
        - i-XXX erdma_0/erdma_1 # specify instance ID and erdma devices(erdma_0/erdma_1) to expose
        - i-* erdma_0           # specify erdma devices(erdma_0) to expose for all unspecified nodes
        - i-* erdma_*           # expose all existing erdma devices for all unspecified nodes
    • 镜像配置:默认的erdma-agent镜像(registry.aliyuncs.com/erdma/agent)不支持本地模式。若要使用本地模式,需自行构建agent镜像,并将其推送至自定义镜像仓库。

      执行以下命令构建并推送镜像。示例使用阿里云容器镜像服务 (ACR),需提前创建命名空间和镜像仓库。

      docker build --tag <REGISTRY_NAME>-registry.<REGION_ID>.cr.aliyuncs.com/<NAMESPACE>/agent:<TAG> --target agent .
      
      docker push <REGISTRY_NAME>-registry.<REGION_ID>.cr.aliyuncs.com/<NAMESPACE>/agent:<TAG>
  4. 使用helm安装erdma-controller组件。

    helm install -f deploy/helm/values.yaml --namespace kube-system alibaba-erdma-controller deploy/helm/
  5. 验证安装。

    • 常规模式安装完成后,验证 erdma-agent 和 erdma-controller Pod 是否已成功创建:

      kubectl get pods -n kube-system | grep erdma

      查询节点上的 eRDMA 设备资源:

      kubectl get erdmadevices
    • 在本地模式下,系统仅创建erdma-agentPod,不会创建erdma-controllerPod,因此erdmadevices资源不可用。

步骤二:创建支持eRDMA网络加速的pod

  1. 要创建支持eRDMA网络加速的pod,需在容器的resources.limits中声明 aliyun/erdma: 1。可依照如下示例,需要将 <ERDMA_POD_IMAGE> 替换为实际使用的容器镜像地址:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: erdma
      name: erdma
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: erdma
      template:
        metadata:
          labels:
            app: erdma
          annotations:
        spec:
          containers:
          - command:
            - sleep
            - "360000"
            image: <ERDMA_POD_IMAGE>
            name: erdma
            resources:
              limits:
                aliyun/erdma: 1
    如果要开启SMC-R透明加速,在annotations中配置 network.alibabacloud.com/erdma-smcr: "true"。此功能要求操作系统为Alibaba Cloud Linux 3,其内核版本不低于 5.10.134-17。
  2. 基于上述配置文件,执行以下命令,部署该Deployment,通过Deployment启动指定数量的Pod副本。

    kubectl apply -f example.yaml

相关文档

如果您希望在ACK集群中配置和使用eRDMA,请参见ACK集群中使用eRDMA加速容器网络