GitHub - Mellanox/network-operator: Mellanox Network Operator
找不到包用这个
1 |
|
结构
README.md
:通常包含项目的概述、安装和使用说明。
docs/
:可能包含详细的文档和设计说明。
pkg/
:包含Go语言的源代码。
cmd/
:包含项目的主程序入口。
deploy/
:包含部署相关的YAML文件。
概念和一些信息
海光不需要加载
寒武纪使用sudo modprobe cambricon-peermem
加载peermem
目标:通过修改英伟达network-operator实现自动加载peermem
OFED driver container
只会部署到支持Mellanox的node上
只要在主机上安装该镜像,容器将完成下面的功能
- 重新加载 Mellanox OFED 提供的内核模块
- 将容器的根目录挂载到
/run/mellanox/drivers/
。如果该目录被映射到主机,该容器的内容就可以与主机或其他容器共享。它的一个用例是编译 Nvidia Peer Memory 客户端模块。
RDMA shared device plugin
支持 IB and RoCE HCA
的plugin,作为daemonset
运行
InfiniBand Kubernetes
InfiniBand Kubernetes
提供了一个守护进程 ib-kubernetes
,它与 InfiniBand SR-IOV CNI
和 Multus CNI
一起工作,Pod
发生变化(创建/更新/删除)时,它会读取 Pod 的网络annotation
并获取其对应的网络 CRD 并读取 PKey,对于带有注释 mellanox.infiniband.app
的 Pod
,将新生成的 Guid 或 CRD cni-args 的 guid 字段中的预定义 Guid 添加到该 PKey。
secondaryNetwork
辅助网络,目前支持下面几种
Multus-CNI:支持 Kubernetes 中二级网络的委托 CNI 插件
CNI 插件: 目前仅支持 containernetworking-plugins
IP Over Infiniband(IPoIB)CNI 插件: 允许用户创建 IPoIB 子链接并将其移动到 pod。
IPAM CNI:IPAM CNI 和相关配置的去向
nicclusterpolicy_controller
NicClusterPolicyReconciler 结构体
NicClusterPolicyReconciler
是一个结构体,包含了用于管理 NicClusterPolicy
自定义资源状态的客户端、方案和各种提供者。
client.Client
: 与 Kubernetes API 进行交互。Scheme
: 定义资源的运行时方案。ClusterTypeProvider
、StaticConfigProvider
、DocaDriverImagesProvider
: 提供必要的配置和驱动镜像。MigrationCh
: 用于处理迁移流程的通道。stateManager
: 管理自定义资源的状态同步。
Reconcile 方法
Reconcile
方法是控制器的核心,负责:
- 处理迁移流程: 确保迁移通道被处理。
- 获取自定义资源: 根据请求检索
NicClusterPolicy
实例。 - 处理 NotFound 错误: 如果资源被删除,则进行清理。
- 检查资源名称: 确保只处理特定名称的资源。
- 创建状态服务目录: 初始化状态服务目录,并添加必要的信息。
- 节点信息提供者: 如果指定了 OFED 驱动程序,则收集节点信息并更新状态目录。
- 同步状态并更新状态: 同步状态并更新自定义资源状态。
- 处理 OFED 等待标签: 更新与 OFED 驱动程序就绪状态相关的节点标签。
辅助方法
requeue()
: 触发带有延迟的重新排队。handleMOFEDWaitLabels()
: 更新节点标签,以指示 OFED 驱动程序是否应等待。handleMOFEDWaitLabelsNoConfig()
: 处理未配置 OFED 的场景,并相应地更新标签。setOFEDWaitLabel()
: 设置或删除节点上的 OFED 等待标签。updateCrStatus()
: 根据状态同步结果更新自定义资源的状态。handleUnsupportedInstance()
: 通过将其状态更新为忽略来处理不受支持的实例。
SetupWithManager 方法
SetupWithManager
使用提供的管理器设置控制器。
- 它创建一个状态管理器,并设置对
NicClusterPolicy
和相关资源的监视。 - 它定义了事件的谓词和处理程序,以确保高效的协调。
此控制器确保 NicClusterPolicy
资源得到正确管理,同步 Kubernetes 集群中的期望状态与实际状态,并处理 OFED 驱动程序的节点特定配置。
peermem模块
Starting from v465 NVIDIA GPU driver includes a built-in nvidia_peermem module which is a replacement for nv_peer_mem module. NVIDIA GPU operator manages nvidia_peermem module loading.
由于现在peermem已经由NVIDIA GPU operator manages负责,所以用之前的代码。最低版本为0.1.0
,最高版本为v23.5.0
还是从nicclusterpolicy_controller.go
入手
nicclusterpolicy_controller.go
在Reconcile中,判断是否写了ofed,nvpeermem,rdma share等,如果写了将信息存入infoProvider,然后将infoProvider添加到sc中,最后调用r.stateManager.SyncState(instance, sc)进行同步。
1 |
|
接下来具体来看SyncState的实现
1 |
|
这里又调用了下面的函数进行处理
1 |
|
最后发现关于peermem的代码在pkg/state/state_nv_peer.go
1 |
|
pkg/state/state_skel.go
1 |
|
manifests/stage-nv-peer-mem-driver
这些文件定义了一个DaemonSet,用于在每个符合条件的节点上部署nv_peer_mem驱动。
主要的实现在0050_nv-peer-mem-driver-ds.yaml文件中:
a) DaemonSet确保在每个满足nodeSelector条件的节点上运行一个Pod:
1
2
3
4nodeSelector:
feature.node.kubernetes.io/pci-15b3.present: "true"
nvidia.com/gpu.present: "true"
network.nvidia.com/operator.mofed.wait: "false"b) 使用initContainer确保NVIDIA驱动已加载:
1
2
3
4initContainers:
- name: gpu-driver-validation
...
args: ["... until nvidia-smi; do echo waiting for nvidia drivers to be loaded; sleep 5; done"]c) 主容器负责加载nv_peer_mem模块:
1
2
3containers:
- image: {{ .CrSpec.Repository }}/{{ .CrSpec.Image }}-{{ .CrSpec.Version }}:{{ .RuntimeSpec.CPUArch }}-{{ .RuntimeSpec.OSName }}{{ .RuntimeSpec.OSVer }}
name: nv-peer-mem-driver-containerd) 使用livenessProbe和readinessProbe检查nv_peer_mem模块是否已加载:
1
2
3
4livenessProbe:
exec:
command:
[sh, -c, 'lsmod | grep nv_peer_mem']该DaemonSet会自动在符合条件的节点上部署和运行,从而实现nv_peer_mem的自动加载。
其他YAML文件(0010到0040)定义了必要的RBAC权限和安全上下文约束,确保Pod有足够的权限来加载内核模块。
注意到有一个版本检查,防止在CUDA驱动版本>=465的节点上调度此Pod,因为较新版本的CUDA驱动应该包含内置的nvidia_peermem模块:
1
2
3
4- key: nvidia.com/cuda.driver.major
operator: Lt
values:
- "{{ .RuntimeSpec.MaxCudaVersion }}"
总之,这个实现通过Kubernetes的DaemonSet机制,在每个符合条件的节点上自动部署和运行一个负责加载nv_peer_mem模块的Pod,从而实现了nv_peer_mem的自动加载。
修改manifests/stage-nv-peer-mem-driver/0050_nv-peer-mem-driver-ds.yaml
通过阅读源码打算修改manifests/stage-nv-peer-mem-driver/0050_nv-peer-mem-driver-ds.yaml
来实现寒武纪的peermem模块的加载。
在v23.5.0的代码基础上进行修改
非常抱歉我之前的误解。根据您的需求,我们需要执行 sudo modprobe cambricon-peermem
命令。让我为您重新说明需要修改的部分:
- 修改 initContainer 部分:
1 |
|
- 在 volumes 部分添加:
1 |
|
- 修改主容器的探针:
将原来检查 nv_peer_mem
的探针改为检查 cambricon-peermem
:
1 |
|
- 更新 DaemonSet 的名称和标签(可选,但建议为了清晰):
1 |
|
- 更新节点选择器(如果需要):
如果 cambricon-peermem 模块需要特定的硬件支持,您可能需要更新节点选择器。例如:
1 |
|
请注意,您可能需要根据实际情况调整节点选择器。
这些修改将使 DaemonSet 在每个符合条件的节点上执行 modprobe cambricon-peermem
命令,从而加载 cambricon-peermem 模块。同时,它还会检查模块是否成功加载。
记住,这种方法假设 cambricon-peermem 模块已经在主机上可用。如果模块不存在,modprobe 命令会失败。另外,使用 privileged: true
会给予容器很高的权限,这可能会带来安全风险。请确保在生产环境中谨慎使用,并相应地调整您的安全策略。
编译部署
要通过编译源码部署NVIDIA Network Operator,可以按照以下步骤进行:
克隆仓库:
1
2git clone https://github.com/Mellanox/network-operator.git
cd network-operator安装依赖:
确保你的系统安装了Go编译器和Docker。编译操作符:
在项目根目录下运行:1
make build
构建Docker镜像:
1
make docker-build
推送Docker镜像:
将镜像推送到你的Docker仓库(例如Docker Hub):1
2docker tag network-operator:latest <your-repo>/network-operator:latest
docker push <your-repo>/network-operator:latest部署操作符:
编辑部署文件,将镜像路径更新为你的仓库路径,然后应用这些文件:1
kubectl apply -f deploy/
通过这些步骤,你可以从源码编译并部署NVIDIA Network Operator。如果需要详细信息,可以参考项目中的 README.md
文件或其他文档。