QSG:基于RDMA共享设备插件在InfiniBand网络上的Kubernetes集群部署

创建于2020年5月20日,作者:Vitaliy Razinkov。本快速入门指南(QSG)介绍了如何构建性能最高的Kubernetes集群,该集群能够承载运行在NVIDIA端到端InfiniBand EDR互连上的最苛刻分布式工作负载。RDMA共享设备插件为Pod提供RDMA设备,并允许在InfiniBand网络上运行原生RDMA应用程序,例如HPC、ML、AI等。在本指南中,我们将展示如何使用RDMA共享设备插件部署Kubernetes,并测试在不同工作节点上运行的Pod之间的网络性能。

文档目录

创建于2020年5月20日,作者:Vitaliy Razinkov

简介

快速入门指南QSG)介绍了如何构建性能最高的Kubernetes集群,该集群能够承载运行在NVIDIA端到端InfiniBand EDR互连上的最苛刻分布式工作负载。RDMA共享设备插件为Pod提供RDMA设备,并允许在InfiniBand网络上运行原生RDMA应用程序,例如HPC、ML、AI等。在本指南中,我们将展示如何使用RDMA共享设备插件部署Kubernetes,并测试在不同工作节点上运行的Pod之间的网络性能。

本文档描述了使用Kubespray构建Kubernetes集群的过程,运行以下设置:

  • 1台部署服务器(带有Ansible应用程序的单个虚拟机或物理机)
  • 1台Kubernetes主节点(单个虚拟机或物理机)
  • 4个工作节点

该部署已使用Ubuntu 18.04操作系统Kubespray v2.13.0进行验证。

缩写和缩略语列表

术语 定义 术语 定义
CNI 容器网络接口 HWE 硬件支持
EDR 增强数据速率 - 100Gb/s HPC 高性能计算
DHCP 动态主机配置协议 K8s Kubernetes
DNS 域名系统 NFD 节点特性发现
DP 设备插件 QSG 快速入门指南
HCA 主机通道适配器 RDMA 远程直接内存访问

参考文献

关键组件和技术

  • NVIDIA InfiniBand智能网卡实现了极致的性能和规模,降低了每次操作的成本,并为高性能计算、机器学习、高级存储、集群数据库、低延迟嵌入式I/O应用等提高了投资回报率。
  • NVIDIA InfiniBand交换机提供了最高的性能和端口密度,并配备完整的网络管理解决方案,使计算集群和融合数据中心能够以任何规模运行,同时降低运营成本和基础设施复杂性。NVIDIA交换机包括广泛的边缘和导向器交换机产品组合,支持40、56、100和200Gb/s端口速度。
  • NVIDIA LinkX电缆和收发器产品系列提供了业界最完整的10、25、40、50、100和200Gb互连产品线,适用于云、HPC、Web 2.0、企业、电信和存储数据中心应用。LinkX产品组合包含用于机架内主机到交换机连接的铜缆高速电缆和用于上行交换机到交换机连接的光缆。
  • RDMA共享设备插件基于通用Kubernetes框架设计,允许供应商向kubelet通告其资源,而无需更改核心代码。
  • Kubespray v2.13.0(来自Kubernetes.io)是Ansible剧本、清单、配置工具和通用OS/Kubernetes集群配置管理任务领域知识的组合,提供:
    • 高可用集群
    • 可组合属性
    • 支持最流行的Linux发行版
  • Kubernetes v1.17.5Kubernetes (K8s)是一个用于自动化部署、扩展和管理容器化应用程序的开源容器编排系统。

解决方案概述

解决方案逻辑设计

逻辑设计包括以下层:

  • 两个独立的网络层:
    1. 管理网络
    2. 高速InfiniBand网络
  • 计算层:
    1. 部署节点(本指南中基于VM的节点)
    2. Kubernetes主节点(本指南中基于VM的节点)
    3. 4个带有NVIDIA ConnectX-6 HCA的Kubernetes工作节点。NVIDIA Kubernetes RDMA共享设备插件(NVIDIA K8s共享DP)必须安装在所有工作节点上。

image2020-5-31_13-54-47.png

InfiniBand网络拓扑

单交换机简单设置

在单交换机情况下,您可以使用NVIDIA SB7700 InfiniBand EDR 100Gb/s交换机系统连接最多36台服务器

InfiniBand网络扩展设置

有关设计扩展InfiniBand拓扑的帮助,请使用NVIDIA InfiniBand拓扑生成器。它是一个在线集群配置工具,提供灵活的集群配置和规模。

对于扩展设置,我们建议使用NVIDIA统一网络管理器(UFM®)

物料清单

QSG:基于RDMA共享设备插件在InfiniBand架构上部署Kubernetes集群

创建于2020年5月20日,作者:Vitaliy Razinkov

简介

本快速入门指南(QSG)介绍了如何构建性能最高的Kubernetes集群,该集群能够利用NVIDIA网卡和交换机的InfiniBand互连,通过RDMA共享设备插件实现高性能通信。

物料清单

下表列出了单交换机拓扑的硬件组件:

image2020-9-17_16-1-28.png

架构配置

物理布线

在本设置中:

  • 部署节点和主节点仅连接到管理网络交换机
  • 每个工作节点上的NVIDIA网卡仅使用一个端口,通过EDR铜缆连接到NVIDIA交换机:

image2020-9-14_17-54-49.png

在我们的物理部署中,我们选择了网卡上的端口 P1。在默认主机操作系统配置下,端口 P1 对应网络接口 IB1

InfiniBand架构配置

以下是配置过程中的重要建议和前提条件:

  • 请参考MLNX-OS用户手册以熟悉交换机软件(位于 docs.nvidia.com/networking/
  • 将交换机软件升级到最新的MLNX-OS版本
  • 需要InfiniBand子网管理器(SM)来正确配置InfiniBand架构

在InfiniBand架构中运行InfiniBand子网管理器(SM)有三种方式:

  1. 在一个或多个受管交换机上启动SM。这是一种非常方便快捷的操作,可实现更简单的InfiniBand“即插即用”。
  2. 通过执行 /etc/init.d/opensmd 命令,在一个或多个服务器上运行OpenSM守护进程。如果节点数达到648个或更多,建议在服务器上运行SM。
  3. 使用统一架构管理(UFM®)。NVIDIA的统一架构管理器(UFM®)是一个强大的可扩展计算平台,消除了架构管理的复杂性,提供了对流量的深度可见性,并优化了架构性能。

在本指南中,我们将在InfiniBand交换机上启动InfiniBand SM(方法1)。以下是所选方法的配置步骤。

在受管交换机上启用SM:

  1. 登录交换机并输入以下配置命令(swx-mld-s01 是我们的交换机名称):
Mellanox MLNX-OS Switch Management

switch login: admin
Password:

swx-mld-s01 [standalone: master] > enable
swx-mld-s01 [standalone: master] # configure terminal
swx-mld-s01 [standalone: master] (config) # ib smnode swx-mld-s01 enable
swx-mld-s01 [standalone: master] (config) # ib smnode swx-mld-s01 sm-priority 0

swx-mld-s01 [standalone: master] (config) # ib sm virt enable
swx-mld-s01 [standalone: master] (config) # write memory
swx-mld-s01 [standalone: master] (config) # reload
  1. 交换机重启后,检查交换机配置。应如下所示:
Mellanox MLNX-OS Switch Management

switch login: admin
Password:

swx-mld-s01 [standalone: master] > enable
swx-mld-s01 [standalone: master] # configure terminal
swx-mld-s01 [standalone: master] (config) # show running-config
##
## Running database "initial"
## Generated at 2019/03/19 17:58:53 +0200
## Hostname: swx-mld-s01
##

##
## Running-config temporary prefix mode setting
##
no cli default prefix-modes enable

##
## Subnet Manager configuration
##
   ib sm virt enable

##
## Other IPv6 configuration
##
no ipv6 enable

##
## AAA remote server configuration
##
# ldap bind-password ********
# radius-server key ********
# tacacs-server key ********

##
## Network management configuration
##
# web proxy auth basic password ********
   clock timezone Asia Middle_East Jerusalem
no ntp server 192.114.62.250 disable
   ntp server 192.114.62.250 keyID 0
no ntp server 192.114.62.250 trusted-enable
   ntp server 192.114.62.250 version 4

##
## X.509 certificates configuration
##
#
# Certificate name system-self-signed, ID 0cd5b6a0da88a0e68b8f3b49408b361afc73289d
# (public-cert config omitted since private-key config is hidden)

##
## IB nodename to GUID mapping
##
   ib smnode swx-mld-s01 create
   ib smnode swx-mld-s01 enable
   ib smnode swx-mld-s01 sm-priority 0
##
## Persistent prefix mode setting
##
cli default prefix-modes enable

部署指南

主机配置

下表详细列出了服务器和交换机名称:

image2020-10-4_15-59-47.png

IB1 接口无需任何配置。 管理网络(eno0/mgmt0)的IP地址由DHCP服务分配。

主机操作系统前提条件:

  1. 确保NVIDIA网卡端口配置为InfiniBand模式。更多信息请参考 此指南
  2. 所有服务器上安装Ubuntu Server 18.04操作系统,包含OpenSSH服务器包,并创建具有sudo权限且无需密码的 非root用户账户。 通过运行以下命令更新Ubuntu软件包并安装最新的HWE内核:
# apt-get update
# apt-get -y install linux-image-generic-hwe-18.04
# reboot
  1. 操作系统安装完成后,检查Kubernetes工作节点是否具有 IB1 网络接口。

非root用户账户前提条件:

在本部署中,我们在 /etc/sudoers 文件末尾添加了以下行:

#includedir /etc/sudoers.d

#K8s cluster deployment user with sudo privileges without password
user ALL=(ALL) NOPASSWD:ALL

K8s集群部署与配置

在本部署中,Kubernetes集群将通过Kubespray从部署服务器使用 非root 用户账户安装。

SSH私钥与SSH无密码登录

部署用户(本例中为 user)身份登录 部署服务器,并运行以下命令创建SSH私钥以配置无密码认证:

$ ssh-keygen

将您的SSH私钥(例如 ~/.ssh/id_rsa)复制到部署中的所有节点,运行以下命令:

$ ssh-copy-id user@nodename

Kubespray配置

  1. 安装使用Ansible运行Kubespray所需的依赖项。

部署服务器上执行以下操作:

$ cd ~
$ sudo apt -y install python3-pip jq
$ wget https://github.com/kubernetes-sigs/kubespray/archive/v2.13.0.tar.gz
$ tar -zxf v2.13.0.tar.gz
$ cd kubespray-2.13.0
$ sudo pip3 install -r requirements.txt

默认命令目录为 ~/kubespray-2.13.0

  1. 创建新的集群配置:

    $ cp -rfp inventory/sample inventory/mycluster
    $ declare -a IPS=(192.168.222.111 192.168.222.101 192.168.222.102 192.168.222.103 192.168.222.104)
    $ CONFIG_FILE=inventory/mycluster/hosts.yaml python3 contrib/inventory_builder/inventory.py ${IPS[@]}
    

    执行后,将生成 inventory/mycluster/hosts.yaml 文件。请检查并修改文件中的主机配置。以下是本次部署的示例:

    all:
      hosts:
        node1:
          ansible_host: 192.168.222.111
          ip: 192.168.222.111
          access_ip: 192.168.222.111
        node2:
          ansible_host: 192.168.222.101
          ip: 192.168.222.101
          access_ip: 192.168.222.101
        node3:
          ansible_host: 192.168.222.102
          ip: 192.168.222.102
          access_ip: 192.168.222.102
        node4:
          ansible_host: 192.168.222.103
          ip: 192.168.222.103
          access_ip: 192.168.222.103
        node5:
          ansible_host: 192.168.222.104
          ip: 192.168.222.104
          access_ip: 192.168.222.104
      children:
        kube-master:
          hosts:
            node1:
        kube-node:
          hosts:
            node2:
            node3:
            node4:
            node5:
        etcd:
          hosts:
            node1:
        k8s-cluster:
          children:
            kube-master:
            kube-node:
        calico-rr:
          hosts:
    
  2. 检查并修改 inventory/mycluster/group_vars/all/all.ymlinventory/mycluster/group_vars/k8s-cluster/k8s-cluster.yml 文件中的集群安装参数。

    1. inventory/mycluster/group_vars/all/all.yml 中,删除以下行,以便指标能够接收集群资源使用数据:

      ## The read-only port for the Kubelet to serve on with no authentication/authorization. Uncomment to enable.
      kube_read_only_port: 10255
      
    2. 本次部署使用的 Kubespray 版本在安装 Docker 组件时存在不一致问题(详见 issue)。为避免相关问题,请在 inventory/mycluster/group_vars/k8s-cluster/k8s-cluster.yml 中添加变量 docker_version: 19.03 以指定 Docker 版本:

      ## Container runtime
      ## docker for docker, crio for cri-o and containerd for containerd.
      container_manager: docker
      docker_version: 19.03
      
    3. 可通过修改 inventory/mycluster/group_vars/k8s-cluster/k8s-cluster.yml 中的 kube_network_plugin 参数(默认:calico)来更改默认的 Kubernetes CNI。

使用 Ansible Playbook 安装 K8s 集群

使用 Kubespray Ansible Playbook 部署 K8s 集群:

$ ansible-playbook -i inventory/mycluster/hosts.yaml --become --become-user=root cluster.yml

此步骤的执行时间可能较长。

Playbook 成功完成的示例如下:

PLAY RECAP ***************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
node1                      : ok=574  changed=95   unreachable=0    failed=0    skipped=1043 rescued=0    ignored=1
node2                      : ok=350  changed=52   unreachable=0    failed=0    skipped=564  rescued=0    ignored=1
node3                      : ok=350  changed=51   unreachable=0    failed=0    skipped=563  rescued=0    ignored=1
node4                      : ok=350  changed=52   unreachable=0    failed=0    skipped=563  rescued=0    ignored=1
node5                      : ok=350  changed=52   unreachable=0    failed=0    skipped=563  rescued=0    ignored=1

Tuesday 14 July 2020  11:43:56 +0300 (0:00:00.101)       0:08:27.568 **********
===============================================================================
kubernetes/kubeadm : Join to cluster ----------------------------------------------------------------------------------------------------- 47.65s
kubernetes/master : kubeadm | Initialize first master ------------------------------------------------------------------------------------ 43.91s
download : download_file | Download item ------------------------------------------------------------------------------------------------- 28.59s
download : download_file | Download item ------------------------------------------------------------------------------------------------- 26.39s
kubernetes/master : Master | wait for kube-scheduler ------------------------------------------------------------------------------------- 22.01s
download : download_file | Download item ------------------------------------------------------------------------------------------------- 19.47s
kubernetes/preinstall : Update package management cache (APT) ----------------------------------------------------------------------------- 9.48s
kubernetes/master : Master | reload kubelet ----------------------------------------------------------------------------------------------- 9.02s
download : download_file | Download item -------------------------------------------------------------------------------------------------- 8.41s
kubernetes/preinstall : Install packages requirements ------------------------------------------------------------------------------------- 7.62s
etcd : wait for etcd up ------------------------------------------------------------------------------------------------------------------- 6.44s
etcd : Configure | Wait for etcd cluster to be healthy ------------------------------------------------------------------------------------ 6.32s
kubernetes-apps/ansible : Kubernetes Apps | Start Resources ------------------------------------------------------------------------------- 5.49s
download : download_file | Download item -------------------------------------------------------------------------------------------------- 4.86s
Gather necessary facts -------------------------------------------------------------------------------------------------------------------- 4.77s
download : download_file | Download item -------------------------------------------------------------------------------------------------- 4.40s
download : download | Download files / images --------------------------------------------------------------------------------------------- 4.36s
kubernetes-apps/ansible : Kubernetes Apps | Lay Down CoreDNS Template --------------------------------------------------------------------- 3.09s
container-engine/docker : ensure docker packages are installed ---------------------------------------------------------------------------- 2.84s
container-engine/docker : Docker | reload docker ------------------------------------------------------------------------------------------ 2.82s

部署验证

可通过 K8s 主节点上的 ROOT 用户账户验证 Kubernetes 集群部署。

以下是使用默认 Kubespray 配置(Calico Kubernetes CNI 插件)的 K8s 集群部署信息示例输出。

为确保 Kubernetes 集群安装正确,请运行以下命令:

root@node1:~# kubectl get nodes -o wide
NAME    STATUS   ROLES    AGE   VERSION   INTERNAL-IP       EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION     CONTAINER-RUNTIME
node1   Ready    master   28m   v1.17.5   192.168.222.111   <none>        Ubuntu 18.04.4 LTS   5.3.0-62-generic   docker://19.3.7
node2   Ready    <none>   26m   v1.17.5   192.168.222.101   <none>        Ubuntu 18.04.4 LTS   5.3.0-62-generic   docker://19.3.7
node3   Ready    <none>   26m   v1.17.5   192.168.222.102   <none>        Ubuntu 18.04.4 LTS   5.3.0-62-generic   docker://19.3.7
node4   Ready    <none>   26m   v1.17.5   192.168.222.103   <none>        Ubuntu 18.04.4 LTS   5.3.0-62-generic   docker://19.3.7
node5   Ready    <none>   26m   v1.17.5   192.168.222.104   <none>        Ubuntu 18.04.4 LTS   5.3.0-62-generic   docker://19.3.7

root@node1:~# kubectl get pod -n kube-system -o wide
NAME                                          READY   STATUS    RESTARTS   AGE    IP                NODE    NOMINATED NODE   READINESS GATES
calico-kube-controllers-78974cdb4d-ltb2n      1/1     Running   0          26m    192.168.222.102   node3   <none>           <none>
calico-node-7mwxg                             1/1     Running   1          26m    192.168.222.101   node2   <none>           <none>
calico-node-gzsjq                             1/1     Running   1          26m    192.168.222.104   node5   <none>           <none>
calico-node-p5ssx                             1/1     Running   1

26m    192.168.222.102   node3   <none>           <none>
calico-node-rxnn6                             1/1     Running   1          26m    192.168.222.103   node4   <none>           <none>
calico-node-zr9lw                             1/1     Running   1          26m    192.168.222.111   node1   <none>           <none>
coredns-76798d84dd-f64sq                      1/1     Running   0          26m    10.233.92.3       node3   <none>           <none>
coredns-76798d84dd-tgfgp                      1/1     Running   0          26m    10.233.90.1       node1   <none>           <none>
dns-autoscaler-85f898cd5c-zcd7w               1/1     Running   0          26m    10.233.90.2       node1   <none>           <none>
kube-apiserver-node1                          1/1     Running   0          27m    192.168.222.111   node1   <none>           <none>
kube-controller-manager-node1                 1/1     Running   0          27m    192.168.222.111   node1   <none>           <none>
kube-proxy-5f4vl                              1/1     Running   0          26m    192.168.222.101   node2   <none>           <none>
kube-proxy-cszc6                              1/1     Running   0          26m    192.168.222.102   node3   <none>           <none>
kube-proxy-hn62h                              1/1     Running   0          26m    192.168.222.111   node1   <none>           <none>
kube-proxy-kwh25                              1/1     Running   0          26m    192.168.222.103   node4   <none>           <none>
kube-proxy-vzp9w                              1/1     Running   0          26m    192.168.222.104   node5   <none>           <none>
kube-scheduler-node1                          1/1     Running   0          27m    192.168.222.111   node1   <none>           <none>
kubernetes-dashboard-77475cf576-4q42g         1/1     Running   0          26m    10.233.92.2       node3   <none>           <none>
kubernetes-metrics-scraper-747b4fd5cd-qs9r2   1/1     Running   0          26m    10.233.92.1       node3   <none>           <none>
nginx-proxy-node2                             1/1     Running   0          26m    192.168.222.101   node2   <none>           <none>
nginx-proxy-node3                             1/1     Running   0          26m    192.168.222.102   node3   <none>           <none>
nginx-proxy-node4                             1/1     Running   0          26m    192.168.222.103   node4   <none>           <none>
nginx-proxy-node5                             1/1     Running   0          26m    192.168.222.104   node5   <none>           <none>
nodelocaldns-bvkp5                            1/1     Running   0          26m    192.168.222.101   node2   <none>           <none>
nodelocaldns-fskdn                            1/1     Running   0          26m    192.168.222.102   node3   <none>           <none>
nodelocaldns-nqxdn                            1/1     Running   0          26m    192.168.222.111   node1   <none>           <none>
nodelocaldns-svfw6                            1/1     Running   0          26m    192.168.222.104   node5   <none>           <none>
nodelocaldns-v24fk                            1/1     Running   0          26m    192.168.222.103   node4   <none>           <none>

在K8s集群上以InfiniBand模式安装RDMA共享设备插件

以下部署场景中的RDMA共享设备插件支持原生InfiniBand应用。

在安装过程中,角色将使用Kubespray的inventory/mycluster/hosts.yaml文件来部署和配置Kubernetes组件。

RDMA共享设备插件组件由安装过程中的一个独立Ansible角色(Role)进行配置。 该角色将安装以下组件:

  1. 节点特性发现(NFD)
  2. RDMA共享设备插件的特定配置(configmap)
  3. RDMA共享设备插件(daemonset模式)

前提条件

  1. 已通过Kubespray部署K8s集群。
  2. 每个Kubernetes工作节点上必须安装InfiniBand驱动。 有关InfiniBand inbox驱动的安装,请参阅Ubuntu 18.04 Inbox Driver User Manual
  3. 复制角色组件。

角色部署

将角色部署到Kubespray部署文件夹:

$ cd ~
$ git clone https://github.com/Mellanox/Kubespray-role-for-RDMA-shared-DP.git
$ cd ~/kubespray-2.13.0
$ cp -r ~/Kubespray-role-for-RDMA-shared-DP/* .

自定义角色变量

在yml文件roles/mlnx-hca-shared/vars/main.yml中设置角色变量。 第7-10行:将共享资源ib1定义为hca_shared_device_a。

---
# vars file for mlnx-shared-hca role
# Physical adapter names must be connected to separate InfiniBand fabric
# max_hca variable in shared_resouces supports value: 1-1000
# Example resources configuration of the multi resource pools with single device in pool and multiple devices in pool
shared_resources:
- res_name: hca_shared_devices_a
  max_hca: 50
  devices:
  - ib1
    #- res_name: hca_shared_devices_b
    #  max_hca: 500
    #  devices:
    #  - ib2
    #  - ib3

# If you need only single resources pool please remove the unused resource name with its components

# Using for Host OS the Ubuntu LTS enablement (also called HWE or Hardware Enablement) kernel(required node reboot)
HWE_kernel: true

# MOFED installation
# If install_mofed is FALSE, will be used kernel InfiniBand inbox driver

install_mofed: false
mlnx_ofed_package: "mlnx-ofed-kernel-only"
mlnx_ofed_version: "latest"
upstream_libs: true

# Install Kubeflow MPI-Operator - https://github.com/kubeflow/mpi-operator

kubeflow_mpi_operator: false
mpi_operator_dep: "https://raw.githubusercontent.com/kubeflow/mpi-operator/master/deploy/v1/mpi-operator.yaml"

# DP and CNI's URL's
shared_dp_ds: "https://raw.githubusercontent.com/Mellanox/k8s-rdma-shared-dev-plugin/master/images/k8s-rdma-shared-dev-plugin-ds.yaml"
nfd_release: "https://github.com/kubernetes-sigs/node-feature-discovery/archive/v0.6.0.tar.gz"

角色执行

从Kubespray部署文件夹运行playbook,使用以下命令:

$ ansible-playbook -i inventory/mycluster/hosts.yaml  --become --become-user=root mlnx-hca-shared.yaml

此步骤的执行时间可能较长。

playbook成功完成的示例如下:

PLAY RECAP ***************************************************************************************************************************************
node1                      : ok=17   changed=9    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0
node2                      : ok=6    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
node3                      : ok=6    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
node4                      : ok=6    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
node5                      : ok=6    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

Tuesday 14 July 2020  16:22:55 +0300 (0:00:00.014)       0:00:31.228 **********
===============================================================================
mlnx-hca-shared : Install aptitude -------------------------------------------------------------------------------------------------------- 7.76s
mlnx-hca-shared : Update additional packages ---------------------------------------------------------------------------------------------- 7.75s
mlnx-hca-shared : OS update. It takes a while. -------------------------------------------------------------------------------------------- 2.89s
mlnx-hca-shared : Extract NFD daemonset's ------------------------------------------------------------------------------------------------- 2.31s
mlnx-hca-shared : Install Openshift pip module -------------------------------------------------------------------------------------------- 2.25s
Gathering Facts --------------------------------------------------------------------------------------------------------------------------- 1.39s
mlnx-hca-shared : Download DP-ds.yaml ----------------------------------------------------------------------------------------------------- 1.16s
mlnx-hca-shared : create configmap for Shared DP ------------------------------------------------------------------------------------------ 1.08s
mlnx-hca-shared : Create a NFD worker Deployment by reading the definition from a local file ---------------------------------------------- 1.05s
mlnx-hca-shared : Create a NFD Master Deployment by reading the definition from a local file ---------------------------------------------- 0.56s
mlnx-hca-shared : Install Mellanox shared device plugin ----------------------------------------------------------------------------------- 0.52s
mlnx-hca-shared : check if a reboot is required ------------------------------------------------------------------------------------------- 0.40s
mlnx-hca-shared : check for module openshift ---------------------------------------------------------------------------------------------- 0.35s
mlnx-hca-shared : Remove NFD directory ---------------------------------------------------------------------------------------------------- 0.32s
mlnx-hca-shared : check if a reboot is required ------------------------------------------------------------------------------------------- 0.32s
mlnx-hca-shared : Insert NFD path to DP-ds.yaml ------------------------------------------------------------------------------------------- 0.28s
Install prerequisites for ALL Nodes

------------------------------------------------------------------------------------------------------- 0.27s mlnx-hca-shared : MOFED installation ------------------------------------------------------------------------------------------------------ 0.22s include_role : mlnx-hca-shared ------------------------------------------------------------------------------------------------------------ 0.15s mlnx-hca-shared : Remove DP-ds.yaml ------------------------------------------------------------------------------------------------------- 0.14s

角色安装摘要

在K8s集群中使用默认变量参数安装角色后,还将完成以下操作:

  1. 安装用于Kubernetes的节点特性发现。
  2. 为"RDMA SHARED DEVICE PLUGIN"配置configmap以创建资源。
  3. 安装带有"RDMA SHARED DEVICE PLUGIN"的DaemonSet。

角色部署验证

角色部署验证必须在K8s主节点上完成。执行以下命令启动验证过程:

root@node1:~# kubectl get pod -n node-feature-discovery -o wide
NAME                          READY   STATUS    RESTARTS   AGE   IP             NODE    NOMINATED NODE   READINESS GATES
nfd-master-786cfcc58f-wjsq8   1/1     Running   0          72s   10.233.90.3    node1   <none>           <none>
nfd-worker-5t84f              1/1     Running   0          71s   10.233.105.1   node4   <none>           <none>
nfd-worker-jb9rd              1/1     Running   0          71s   10.233.70.1    node5   <none>           <none>
nfd-worker-kjm27              1/1     Running   0          71s   10.233.92.4    node3   <none>           <none>
nfd-worker-ljkkl              1/1     Running   0          71s   10.233.96.1    node2   <none>           <none>

root@node1:~# kubectl get pod -n kube-system -o wide | grep "rdma"
NAME                                          READY   STATUS    RESTARTS   AGE   IP                NODE    NOMINATED NODE   READINESS GATES
rdma-shared-dp-ds-4hkdv                       1/1     Running   0          45s   192.168.222.101   node2   <none>           <none>
rdma-shared-dp-ds-qprbd                       1/1     Running   0          45s   192.168.222.104   node5   <none>           <none>
rdma-shared-dp-ds-qzj2h                       1/1     Running   0          42s   192.168.222.102   node3   <none>           <none>
rdma-shared-dp-ds-tmv7f                       1/1     Running   0          42s   192.168.222.103   node4   <none>           <none>

部署验证

  1. 创建一个测试容器以验证部署。 以下是使用RDMA共享设备的工作负载部署的yml配置文件:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: test-deployment
      labels:
        app: test
    spec:
      replicas: 4
      selector:
        matchLabels:
          app: test
      template:
        metadata:
          labels:
            app: test
        spec:
          containers:
          - image: IMAGE_NAME
            name: test-pod
            securityContext:
              capabilities:
                add: [ "IPC_LOCK" ]
            resources:
              limits:
                rdma/hca_shared_devices_a: 1
            command:
            - sh
            - -c
            - sleep inf
    

    注意: 需要一个安装了InfiniBand用户空间驱动程序的Docker镜像(IMAGE_NAME)。

  2. 启动部署并确保所有Pod都在运行:

    root@node1:~# kubectl apply -f test-dep.yaml
    
    root@node1:~# kubectl get pod -o wide
    NAME                              READY   STATUS    RESTARTS   AGE   IP             NODE    NOMINATED NODE   READINESS GATES
    test-deployment-d5d789464-8gmml   1/1     Running   0          88s   10.233.70.2    node5   <none>           <none>
    test-deployment-d5d789464-fz787   1/1     Running   0          88s   10.233.105.2   node4   <none>           <none>
    test-deployment-d5d789464-hftjs   1/1     Running   0          88s   10.233.92.6    node3   <none>           <none>
    test-deployment-d5d789464-q7djk   1/1     Running   0          88s   10.233.96.2    node2   <none>           <none>
    
  3. 检查Pod的InfiniBand组件:

    root@node1:~# kubectl exec -it test-deployment-d5d789464-hftjs -- bash
    root@test-deployment-d5d789464-hftjs:/tmp# ls -la /dev/infiniband /sys/class/net
    /dev/infiniband:
    total 0
    drwxr-xr-x 2 root root      140 Jul 15 04:42 .
    drwxr-xr-x 6 root root      380 Jul 15 04:42 ..
    crw------- 1 root root 231,  67 Jul 15 04:42 issm3
    crw-rw-rw- 1 root root  10,  54 Jul 15 04:42 rdma_cm
    crw-rw-rw- 1 root root 231, 227 Jul 15 04:42 ucm3
    crw------- 1 root root 231,   3 Jul 15 04:42 umad3
    crw-rw-rw- 1 root root 231, 195 Jul 15 04:42 uverbs3
    
    /sys/class/net:
    total 0
    drwxr-xr-x  2 root root 0 Jul 15 04:43 .
    drwxr-xr-x 78 root root 0 Jul 15 04:43 ..
    lrwxrwxrwx  1 root root 0 Jul 15 04:43 eth0 -> ../../devices/virtual/net/eth0
    lrwxrwxrwx  1 root root 0 Jul 15 04:43 lo -> ../../devices/virtual/net/lo
    lrwxrwxrwx  1 root root 0 Jul 15 04:43 tunl0 -> ../../devices/virtual/net/tunl0
    
    root@test-deployment-d5d789464-hftjs:/tmp# ibv_devinfo
    hca_id:	mlx5_3
    	transport:			InfiniBand (0)
    	fw_ver:				20.24.0246
    	node_guid:			9803:9b03:0085:56a7
    	sys_image_guid:		9803:9b03:0085:56a6
    	vendor_id:			0x02c9
    	vendor_part_id:		4123
    	hw_ver:				0x0
    	board_id:			MT_0000000224
    	phys_port_cnt:		1
    		port:	1
    			state:			PORT_ACTIVE (4)
    			max_mtu:		4096 (5)
    			active_mtu:		4096 (5)
    			sm_lid:			1
    			port_lid:		4
    			port_lmc:		0x00
    			link_layer:		InfiniBand
    

    从上述示例中,我们可以看到部署的容器只有一个InfiniBand设备(uverb3),任何支持原生InfiniBand的应用程序都可以使用它。

  4. 以下是在不同K8s工作节点上的两个Pod之间使用IB_WRITE_BW命令进行的部署后完整性检查:

    root@node1:~# kubectl exec -it test-deployment-d5d789464-hftjs -- bash
    root@test-deployment-d5d789464-hftjs:/tmp# ib_write_bw -d mlx5_3 -a -F
    
    ************************************
    * Waiting for client to connect... *
    ************************************
    ---------------------------------------------------------------------------------------
                        RDMA_Write BW Test
     Dual-port       : OFF		Device         : mlx5_3
     Number of qps   : 1		Transport type : IB
     Connection type : RC		Using SRQ      : OFF
     CQ Moderation   : 100
     Mtu             : 4096[B]
     Link type       : IB
     Max inline data : 0[B]
     rdma_cm QPs	 : OFF
     Data ex. method : Ethernet
    ---------------------------------------------------------------------------------------
     local address: LID 0x04 QPN 0x088d PSN 0xa1ff0c RKey 0x08a785 VAddr 0x007fae2d365000
     remote address: LID 0x03 QPN 0x088c PSN 0x57b931 RKey 0x08a282 VAddr 0x007f74e44b0000
    ---------------------------------------------------------------------------------------
     #bytes     #iterations    BW peak[MB/sec]    BW average[MB/sec]   MsgRate[Mpps]
     65536      1097100          0.00               95.87  		        0.182849
    ---------------------------------------------------------------------------------------
    
    root@node1:~# kubectl exec -it test-deployment-d5d789464-8gmml -- bash
    root@test-deployment-d5d789464-8gmml:/tmp# ib_write_bw  -F -d mlx5_3 10.233.92.6 -D 10 --cpu_util --report_gbits
    ---------------------------------------------------------------------------------------
                        RDMA_Write BW Test
     Dual-port       : OFF		Device         : mlx5_3
     Number of qps   : 1		Transport type : IB
     Connection type : RC		Using SRQ      : OFF
     TX depth        : 128
     CQ Moderation   : 100
     Mtu             : 4096[B]
     Link type       : IB
     Max inline data : 0[B]
     rdma_cm QPs	 : OFF
     Data ex. method : Ethernet
    ---------------------------------------------------------------------------------------
     local address: LID 0x03 QPN 0x088c PSN 0x57b931 RKey 0x08a282 VAddr 0x007f74e44b0000
     remote address: LID 0x04 QPN 0x088d PSN 0xa1ff0c RKey 0x08a785 VAddr 0x007fae2d365000
    ---------------------------------------------------------------------------------------
     #bytes     #iterations    BW peak[Gb/sec]    BW average[Gb/sec]   MsgRate[Mpps]    CPU_Util[%]
     65536      1097100          0.00               95.87  		        0.182849	    4.57
    ---------------------------------------------------------------------------------------
    

    上述示例表明,我们可以达到约96Gb/sec的最大传输速率。

完成!

关于作者

VR.jpg

Vitaliy Razinkov

Vitaliy Razinkov 是 NVIDIA 网络团队的一名解决方案架构师,专注于复杂的 Kubernetes、OpenShift 和 Microsoft 解决方案。凭借超过 25 年的高级技术职位经验,他在设计和实施高级基础设施方面拥有深厚的专业知识。Vitaliy 撰写了多份关于 Microsoft 技术、RoCE/RDMA 加速的 Kubernetes/OpenShift 机器学习以及容器化解决方案的参考设计指南——所有这些均可在 NVIDIA 网络文档网站上获取。

相关文档