上回简单介绍了下技术背景,这次真正进入实践阶段,之前提到过,sriov是需要硬件支持, 一般开启sriov需要在IBOS中进行设置,这个根据服务器型号不同而操作不同, 具体可参考官网.
k8s集群
现有的k8s集群使用的容器网络为flannel,k8s版本为v1.15.9, 这里要特别说明一下,1.15.9的版本相对来说已经较旧了,后面部署sriov-network-operator遇到好几个坑都是因为版本问题,后面会细说,其它没什么特别的.
硬件开启SRIOV功能
由于服务器的型号不一样,操作方法不一样,但是万变不离其综,在IBOS中多找找,一般都可以找到.
参考: https://docs.mellanox.com/pages/viewpage.action?pageId=19798214
安装驱动
1 | wget 'http://www.mellanox.com/page/mlnx_ofed_eula?mtag=linux_sw_drivers&mrequest=downloads&mtype=ofed&mver=MLNX_OFED-4.5-1.0.1.0&mname=MLNX_OFED_LINUX-4.5-1.0.1.0-rhel7.4-x86_64.tgz' |
在安装完驱动之后机器需要重启,
1 | # 重启完之后ib的驱动会自动启动,且一般默认开机自启 |
这时需要为 ib 端口配置一个 IP 地址,以方便网络的识别和诊 断,配置方法和以太网端口的 IP 配置方法一样,具体步骤如下:
步骤 1: 在节点的/etc/sysconfig/network-scripts/
创建 ifcfg-ib0 网络配置文件,IP 地址和子网掩码 按照 LLD 规划设计,内容如下:
1 | # cat /etc/sysconfig/network-scripts/ifcfg-ib0 |
步骤 2: 启动 ib0 端口,命令为 ifup ib0
步骤 3: 按照以上两步完成所有节点 IB 网络的 IP 配置
开启vf
1 | # mst status |
开启ib0 vf网卡的state从disable为enable, 每次机器重启后,都会变回到disable,因此这条语句需要加入到开机启动中,
1 | for ((i = 0 ; i < 8 ; i++ )); do ip link set dev ib0 vf $i state enable; done |
参考: https://codimd.mcl.math.ncu.edu.tw/s/SyG8zjJpE
使用ip看到所有VF的mac地址都是全0,但实际这个是ip命令的bug,需要通过以下的方式查看具体的mac地址
1 | [root@sh-office-10-5-40-94 bin]# cat cd/virtfn0/net/ib1/address |
Ibstat 显示除了mlx5_0的 state为active外,其它的7个(mlx5_1-mlx5_8)的state都为Down,目前这个是正常的
配置子网管理器
IB 网络使用子网管理器(SM, Subnet Manager)管理网络路由,子网管理器可以运行在 服务器节点或具有管理功能的 IB 交换机上,由于IB交换机作者没有权限,因此这里直接部署在两台服务器节点上,由于子网管理器也要考虑单点问题,而SM本身就支持主备切换,同时只 有一台处于 Active 状态,因此部署两台,一主一备,
MLNX_OFED 驱动当中集成了子网管理器 OpenSM,安装 MLNX_OFED 驱动后, OpenSM 已默认安装。启动子网管理器的方法如下: 步骤 1: 运行下述命令来创建 opensm.conf 配置文件:
1 | opensm --create-config /etc/opensm/opensm.conf |
步骤 2 基于上述初始化创建,OpenSM 使用默认的路由算法 minihop。当网络使用 Fat-Tree 或 Up-Down 等其它拓扑组网时,需要在 opensm.conf 配置文件中将 routing_engine 修改为 对应的路由算法
修改默认配置:
1 | # vim /etc/opensm/opensm.conf |
检查网络
检查 IB 端口状态 检查 IB 端口状态是否 up,端口速率是否达到标称值,通过 ibstat 命令来进行检查,下 面打印结果为 mlx5_0 端口 up,状态为 active,速率为 100Gbps
部署
准备工作[可选]
由于本人集群中有一些psp的限制 ,需要以下操作
1 | # psp.yaml |
部署multus
由于在一个k8s中要支持多个容器网络,CNCF有几款项目可以实现这个功能,而multus即为比较好的解决方案
multus的主要作用是: 在给pod分配ip时,会先经过multus,由multus根据pod是否存在指定的annotations来分配相关的网络,同时,需要指定一个默认的容器网络(这里是flannel), multus其实就是个网络代理
这里要注意的是,multus里的部署yaml文件中crd的版本因k8s的版本不同而不同,在v1.16之前的版本为v1beta1,之后为v1,请特别注意
v1.16版本之前的使用以下的yaml文件
1 | https://github.com/k8snetworkplumbingwg/multus-cni/tree/master/images/deprecated |
请根据实际情况配置cm,如下:
1 | apiVersion: v1 |
最终在`/etc/cni/net.d/00-multus.conf的文件如下
1 | { "name": "multus-cni-network", "type": "multus", "capabilities": {"portMappings": true}, "kubeconfig": "/etc/cni/net.d/multus.d/multus.kubeconfig", "delegates": [ { "cniVersion": "0.2.0", "name": "cbr0", "plugins": [ { "type": "flannel", "delegate": { "hairpinMode": true, "isDefaultGateway": true } }, { "type": "portmap", "capabilities": { "portMappings": true } } ] } ] } |
参考: https://github.com/k8snetworkplumbingwg/multus-cni
部署whereabouts
whereabounts是用于管理ip分配,这样多台node节点上的ip能够保证不出现重复
1 | # kubectl apply -f https://raw.githubusercontent.com/openshift/whereabouts-cni/master/doc/daemonset-install.yaml |
参考:https://github.com/openshift/whereabouts-cni
部署sriov-network-operator
sriov-network-operator是openshift开源的一个包含了cni及device-plugin的部署operator,方便直接.
1 | # 1. centos先安装依赖 |
安装完成
需要注意以下事项:
8ks v1.17之前的版本不支持在除kube-system之外的ns在pod中指定system-node-critical priorityClass,而官方镜像sriov-network-operator及sriov-network-config-daemon镜像中的yaml写死了system-node-critical priorityClass,要部署在其它ns中对于v1.17之前的版本需要特殊处理,需要重新打sriov-network-operator跟sriov-network-config-daemon的镜像,因为bindata/manifests目录被打进了镜像中,要么通过挂载的方式进行覆盖或者重新打镜像,操作如下:
1
2
3
4
5
6
7
8# 首先通过上述操作修改了crdversion,由v1--> v1beta1, bindata下的文件会自动生成
# bindata下涉及到 priorityClassName: "system-node-critical"的文件有,可以去掉
# bindata/manifests/daemon/daemonset.yaml
# bindata/manifests/plugins/sriov-cni.yaml
# bindata/manifests/plugins/sriov-device-plugin.yaml
# deploy/operator.yaml
# 重新Docker build
make deploy-setup-k8s
部署完之后查看sriovnetworknodestates.sriovnetwork.openshift.io
1 | kubectl -n kube-system get sriovnetworknodestates.sriovnetwork.openshift.io spring-30 -oyaml |
输出如下:
发布nodepolicy.yaml
1 | apiVersion: sriovnetwork.openshift.io/v1 |
说明:
1 | # 1. 自定义resourceName名,这个字段后续会绑定在 NetworkAttachmentDefinition 上 |
部署NetworkAttachmentDefinition
1 | apiVersion: sriovnetwork.openshift.io/v1 |
192.168.10.1默认为网关,上述的配置ip地址192.168.10.2开始分配, 从whereabouts默认是将ip信息保存在kubernetes中,部署完whereabouts会在node上的/etc/cni/net.d/whereabounts.d下生成存储信息及认证,因此可以省略使用etcd,方便.
新建的SriovIBNetwork
对象默认会创建一个同名的networkattachmentdefinition
对象
1 | kubectl get networkattachmentdefinition.k8s.cni.cncf.io -n kube-system |
验证
使用以下的yaml进行验证
1 | apiVersion: apps/v1 |
发布到镜像后可以看到容器具有两个ip
同时查看pod的yaml,可以看到annotation中存在两个ip地址
可以使用ib的测试工具来验证网络的传输速度
在其中一个pod充当服务端,执行以下命令:
1 | # kubectl exec -it sample-pod-65b94586b4-8k784 -- bash |
在另一个pod中执行充当客户端,执行以下命令;
1 | # kubectl exec -it sample-pod-65b94586b4-8xn6m -- bash |
会发现,速率接近100G/s, 符合IB网卡的理想速度.
测试使用的Dockerfile
1 | FROM nvidia/cuda:11.2.2-devel-centos7 |
部署开启webhook,非必须
Operator也可以选择开启webhook, 功能作用不大,默认也是关闭的,如果想开启的话,参考下面的方式
1 | kubectl -n kube-system create secret tls operator-webhook-service --cert=server.pem --key=serverkey.pem |
上述的server.pem、serverkey.pem、cacert.pem可通过openssl生成
1 | # 一条命令生成 ca根证书及密钥 |
整体都跑起来了,但是其中还是遇到这么多的坑,下次做过完整总结
参考文章:
- https://github.com/openshift/whereabouts-cni
- https://docs.mellanox.com/pages/viewpage.action?pageId=19798214
- https://docs.mellanox.com/pages/releaseview.action?pageId=39266293#RDG:KubernetesclusterdeploymentwithNVIDIAGPUoverInfiniBandfabric.-NodesConfiguration
- https://www.jianshu.com/p/2796f8ddf2c2
- https://docs.mellanox.com/pages/viewpage.action?pageId=19798214
- https://support.huawei.com/view/PdfRead/EDOC1000172992/SUPE_DOC/k001/document.pdf
- https://access.redhat.com/documentation/zh-cn/red_hat_enterprise_linux/8/pdf/configuring_infiniband_and_rdma_networks/Red_Hat_Enterprise_Linux-8-Configuring_InfiniBand_and_RDMA_networks-zh-CN.pdf