在 OpenShift 上部署 HAMi Enterprise
本文面向 SRE 和平台工程师,说明如何在使用 NVIDIA GPU 的 OpenShift 集群上部署 HAMi Enterprise。内容包括 OpenShift 所需的安全配置、SELinux、容器运行时、安装、License 激活和验证步骤。
本文不适用于离线交付场景。
前置条件
安装前,确认以下条件:
- 管理主机已安装
oc和 Helm,当前 context 指向目标集群。收集 License 申请信息还需要在该主机上安装kubectl和jq。 - 操作账号可以创建 Project、集群级 SecurityContextConstraints(SCC)和 RBAC 资源。
- 集群已安装 NVIDIA GPU Operator,
ClusterPolicy已就绪,并已禁用 GPU Operator 内置的 device plugin。HAMi Enterprise 会部署自己的 device plugin。如果尚未安装 GPU Operator,请先按照 NVIDIA 官方的 在 OpenShift 上安装 NVIDIA GPU Operator 指南完成安装。 - 所有 GPU 节点上的 NVIDIA 驱动和 Container Toolkit 已就绪。
- 本文使用传统 device plugin 路径。保持
dra.enabled=false;启用 DRA 时不会渲染 OpenShift SCC 和 SELinux 资源。
继续操作前,检查集群:
oc whoami
oc get nodes -o wide
oc get clusterpolicy
oc get nodes -L nvidia.com/gpu.present
设置 GPU Operator ClusterPolicy 的名称,并检查安装所需的关键字段:
export GPU_CLUSTER_POLICY='gpu-cluster-policy'
oc get clusterpolicy "$GPU_CLUSTER_POLICY" \
-o jsonpath='state={.status.state}{"\n"}devicePlugin.enabled={.spec.devicePlugin.enabled}{"\n"}cdi.enabled={.spec.cdi.enabled}{"\n"}'
预期输出包含 state=ready 和 devicePlugin.enabled=false。根据 cdi.enabled 的值选择后续配置路径。如果任一必需值不同或为空,请停止安装,先修正 GPU Operator 配置。如果集群使用了其他名称,请替换为实际的 ClusterPolicy 名称。
关闭 GPU Operator CDI
全新安装 NVIDIA GPU Operator 25.10 及更高版本时,默认启用 CDI;通过 OLM 升级时,可能会保留已有 ClusterPolicy 中的值。本文建议关闭 GPU Operator CDI,并保留 HAMi Enterprise 的默认配置:devicePlugin.deviceListStrategy=envvar 和 scheduler.useDownward=true。保留 Downward API 路径可以避免 HAMi 非 Downward API 路径中的额外节点级 allocation lock 协调。关闭 GPU Operator CDI 本身不会直接提高 scheduler 性能。
如果当前已经是 cdi.enabled=false,或者集群必须保留 CDI,请跳过本节命令。保留 CDI 的集群使用后文的企业版 CDI 配置。如果 GPU Operator NRI plugin 已启用,请先关闭 NRI plugin,再关闭 CDI,因为 NRI 依赖 CDI;各版本的切换步骤参见 NVIDIA 的 CDI 和 NRI 支持文档。
OpenShift 使用 CRI-O。修改已有的 ClusterPolicy 时,先暂时停止 GPU 节点上的 GPU Operator validator,再关闭 CDI,最后恢复 validator:
oc label nodes -l nvidia.com/gpu.present=true \
nvidia.com/gpu.deploy.operator-validator=false --overwrite
oc patch clusterpolicy "$GPU_CLUSTER_POLICY" --type='json' \
-p='[{"op":"replace","path":"/spec/cdi/enabled","value":false}]'
oc label nodes -l nvidia.com/gpu.present=true \
nvidia.com/gpu.deploy.operator-validator=true --overwrite
如果 patch 命令失败,仍须执行最后一条 label 命令恢复 validator,再排查失败原因。
等待 ClusterPolicy 恢复 ready 状态,然后确认结果:
oc get clusterpolicy "$GPU_CLUSTER_POLICY" \
-o jsonpath='state={.status.state}{"\n"}cdi.enabled={.spec.cdi.enabled}{"\n"}'
预期输出为 state=ready 和 cdi.enabled=false。修改 GPU Operator ClusterPolicy 时,请使用 spec.cdi.enabled;设置已弃用的 GPU Operator Helm value cdi.default=false 不能关闭 CDI。
设置 Chart 版本
设置 HAMi Enterprise Chart 地址和版本:
export HAMI_ENTERPRISE_CHART='oci://ghcr.io/dynamia-ai/charts/hami-enterprise'
export HAMI_ENTERPRISE_VERSION='REPLACE_WITH_VERSION'
准备 OpenShift Project
为 HAMi Enterprise 创建独立 Project。不要安装到 kube-system 等高权限平台 Project。
oc new-project hami-system
默认情况下,HAMi device plugin 仅在带有 gpu=on 标签的节点上启动。如果使用默认 selector,请设置 GPU_NODE,并为每个需要由 HAMi 管理的 NVIDIA 节点添加标签:
export GPU_NODE='REPLACE_WITH_GPU_NODE_NAME'
oc label node "$GPU_NODE" gpu=on --overwrite
如果准备改用现有的 nvidia.com/gpu.present 标签,请跳过添加标签的命令,并按照下一节配置替代 selector。
配置 HAMi Enterprise
保留 HAMi Enterprise 默认的 envvar 注入方式和 Downward API 配置。scheduler.useDownward 的默认值已经是 true,因此不在 values 文件中重复设置。配置 devicePlugin.runtimeClassName=nvidia,确保集群未将 NVIDIA runtime 设为默认 runtime 时,HAMi device plugin 仍使用 NVIDIA runtime。
创建 values-openshift.yaml。该文件只包含与 Chart 默认值不同的配置:
platform:
openshift: true
selinux:
enabled: true
scheduler:
service:
type: ClusterIP
devicePlugin:
runtimeClassName: nvidia
如果 NVIDIA 驱动由 GPU Operator 管理,节点上的驱动根目录是 /run/nvidia/driver,NVML 库位于 /run/nvidia/driver/usr/lib64/ 下,而不是 / 路径下。选择 nvidia RuntimeClass 后,NVIDIA Container Toolkit 会在容器启动时注入这些文件。推荐的 envvar 配置不需要设置 devicePlugin.nvidiaDriverRoot。如果 HAMi device plugin 或由 HAMi 调度的工作负载无法启动,请参阅 使用 GPU Operator 25.10+ 时 NVIDIA 容器启动失败。
devicePlugin.nvidiaDriverRoot 和 devicePlugin.nvidiaHookPath 需要根据 GPU 节点上驱动及 NVIDIA Container Toolkit 的安装方式分别配置。以下列出常见安装路径,实际值应以部署环境为准:
nvidiaDriverRoot是宿主机上的 NVIDIA 驱动安装根目录。GPU Operator 管理的驱动通常使用/run/nvidia/driver;直接安装在宿主机上的驱动通常使用/。应填写实际驱动根目录,而不是单个 NVML 库所在的目录。nvidiaHookPath是生成的 CDI specification 中 NVIDIA CDI hook 使用的宿主机可执行文件路径。只有 Toolkit 将可执行文件安装在该位置时,才使用/usr/local/nvidia/toolkit/nvidia-ctk;预装或自定义安装的 Toolkit 应填写实际可执行文件路径。
这两个 Chart value 的默认值均为空。是否覆盖各项,应根据节点安装布局和 device plugin 的实际默认配置判断,不能仅因启用了 CDI 就照搬示例中的两个路径。
如需查看 HAMi Enterprise Chart 的其他 values、默认值和参数说明,请参阅 HAMi Enterprise Chart values 参考。该参考页面由 helm-docs 根据 Chart 生成。
使用 NVIDIA GPU 节点标签
如果没有添加 gpu=on,请确认 nvidia.com/gpu.present=true 能够识别需要由 HAMi 管理的所有 NVIDIA 节点。将其中一个节点设置为 GPU_NODE,供后续验证命令使用:
oc get nodes -l nvidia.com/gpu.present=true
export GPU_NODE='REPLACE_WITH_GPU_NODE_NAME'
如果使用该标签,请将前述示例中的 devicePlugin 配置替换为:
devicePlugin:
runtimeClassName: nvidia
nvidiaNodeSelector:
gpu: null
nvidia.com/gpu.present: "true"
gpu: null 用于删除 Chart 默认的 selector。如果省略该配置,Helm 会合并两个 map 条目,device plugin 仍然要求节点带有 gpu=on。
仅在必要时使用 CDI
如果环境必须使用 CDI,请保持 GPU Operator spec.cdi.enabled=true。在现有 values-openshift.yaml 中保留已经选择的 node selector 和其他 OpenShift 配置,并应用以下 HAMi Enterprise 覆盖配置。HAMi CDI 要求设置 scheduler.useDownward=false;以下示例假设 GPU Operator NRI plugin 已关闭,并且集群中存在 nvidia RuntimeClass。
scheduler:
useDownward: false
devicePlugin:
runtimeClassName: nvidia
deviceListStrategy: cdi-annotations
# 示例路径,需分别按节点上的实际安装布局调整。
nvidiaDriverRoot: /run/nvidia/driver
nvidiaHookPath: /usr/local/nvidia/toolkit/nvidia-ctk
开源版的 HAMi CDI 配置文档提供 CDI 背景和验证步骤,但其中的 Helm values 不包含 HAMi Enterprise 所需的 scheduler.useDownward=false。在 OpenShift 上安装企业版时,请使用上述企业版覆盖配置。
配置 OpenShift 安全策略
启用 platform.openshift 后,Chart 默认创建专用的 hami-device-plugin SCC、对应的 system:openshift:scc:hami-device-plugin ClusterRole,以及只面向已启用 device-plugin ServiceAccount 的 RoleBinding。该 SCC 允许特权容器、host PID、hostPath volume 和 SYS_ADMIN capability,但仍禁用 host IPC、host network 和 host port。scheduler 和 admission ServiceAccount 不在授权范围内,继续使用 OpenShift 为其选择的 SCC。
安装前,请根据集群安全策略评估专用 SCC。如果需要使用现有 SCC,请设置 create: false,并把 name 设置为 privileged 或其他已获批准的 SCC,同时确认对应的 system:openshift:scc:<name> ClusterRole 已存在。如果准备完全在 Chart 外管理授权,请设置 create: false、将 name 留空,并仅向渲染结果中的 device-plugin ServiceAccount 授予已批准的 SCC。
SELinux relabel 使用 Chart 默认的 container_file_t 类型和 s0 level。启用后,Chart 会修改以下宿主机目录的 label 和权限:
/usr/local/vgpu
/usr/local/vgpu/containers
/tmp/vgpulock
安装 HAMi Enterprise
安装 HAMi Enterprise:
helm upgrade --install hami "$HAMI_ENTERPRISE_CHART" \
--version "$HAMI_ENTERPRISE_VERSION" \
--namespace hami-system \
--create-namespace \
-f values-openshift.yaml \
--wait
验证部署结果
检查 scheduler 和 device plugin 的 rollout 状态:
oc rollout status deployment/hami-hami-enterprise-scheduler -n hami-system
oc rollout status daemonset/hami-hami-enterprise-device-plugin -n hami-system
oc get pods -n hami-system -o wide
检查每个运行中 Pod 使用的 SCC:
oc get pods -n hami-system \
-o 'custom-columns=NAME:.metadata.name,SCC:.metadata.annotations.openshift\.io/scc'
device-plugin Pod 应使用当前授权模式对应的 SCC:Chart 默认模式使用 hami-device-plugin,其他模式使用已批准的现有 SCC。scheduler Pod 应使用 OpenShift 选择的 SCC,通常是适用于该 Project 的 restricted SCC。成功的 admission hook Job 使用 Helm hook-succeeded 删除策略,因此此时通常已经没有对应 Pod;只有失败的 hook 保留 Pod 时才需要检查。
检查 GPU Operator 状态:
oc get clusterpolicy
oc get node "$GPU_NODE" -L gpu,nvidia.com/gpu.present
oc describe node "$GPU_NODE"
检查 GPU 节点上 HAMi 目录的 SELinux label:
oc debug node/"$GPU_NODE" -- chroot /host \
ls -Zd /usr/local/vgpu /usr/local/vgpu/containers /tmp/vgpulock
三个 HAMi 目录应显示配置的 container_file_t 类型和 s0 level。
获取 License
请等待已安装的 HAMi Enterprise Pod 全部启动,再收集 License 申请信息。收集脚本使用 kubectl。请确认 kubectl 与 oc 指向同一个目标集群,并确认已安装 jq:
kubectl config current-context
jq --version
下载并运行收集脚本:
curl -fsSLO https://public.hami.run/collect-hami-license-info.sh
bash collect-hami-license-info.sh
如果交付包中已经包含该脚本,请直接运行本地副本:
bash collect-hami-license-info.sh
脚本会输出以下格式的 License 申请信息:
{
"esn": "96565d61-986a-4918-aafb-448ff6e3746b",
"deviceInstances": [
{
"uuid": "GPU-ceee905d-48ac-93de-a81b-17c00e1e5e02",
"deviceType": "NVIDIA A10"
}
]
}
请将完整 JSON 输出发送到商业合同约定的 Dynamia.ai 专属支持渠道。也可以通过 info@dynamia.ai 或 400-026-7800 联系 Dynamia.ai,获取 License。
激活 License
收到 License 文件后,将文件保存到管理主机,然后创建并标记 License Secret:
kubectl create secret generic hami-license \
--from-file=license=/path/to/license-file \
-n hami-system
kubectl label secret hami-license \
hami.io/license="true" \
-n hami-system
检查 Secret 和 License 校验事件:
kubectl get secret hami-license -n hami-system
kubectl get events --field-selector involvedObject.name=hami-license -n hami-system
kubectl get nodes \
-o custom-columns='NODE:.metadata.name,LICENSE:.metadata.annotations.hami\.io/nvidia-license'
出现 LicenseValid 事件表示 License 校验成功。对于 NVIDIA 节点,LICENSE 列还会显示 License 注册 annotation。测试 vGPU 切分和调度前,请先完成激活,再提交验收流程规定的测试工作负载。
故障排查
| 现象 | 检查与处理 |
|---|---|
渲染结果中没有 OpenShift 资源或 selinux-relabel | 确认 values-openshift.yaml 同时启用了 platform.openshift 和 selinux.enabled,然后重新渲染清单。 |
| SCC 准入拒绝 device-plugin Pod | 检查当前授权模式选用的 SCC 和 device-plugin Pod 上的 SCC annotation。由 Chart 管理授权时,检查渲染出的 RoleBinding 和 device-plugin ServiceAccount;在 Chart 外管理授权时,检查外部 binding。不要向 scheduler、admission 或业务 ServiceAccount 授予该 SCC。 |
| 缺少当前 SCC 模式所需的资源或 SELinux 资源 | 确认 dra.enabled=false,然后根据所选 SCC 授权模式检查渲染结果。设置 create: false 时,缺少专用 SCC 是预期结果;启用 DRA 时,不生成传统 SCC 和 SELinux 资源也是预期结果。 |
device-plugin Pod 一直处于 Pending | 确认节点符合 devicePlugin.nvidiaNodeSelector,检查节点污点,并确认 devicePlugin.tolerations 与污点匹配。 |
device plugin 已启动,但报告 NVIDIA hook 或 libcuda.so.1 错误 | 检查 NVIDIA 驱动、Container Toolkit 和 GPU Operator 状态。此现象表示容器运行时集成异常,不能据此判定 HAMi 调度失败。按照 使用 GPU Operator 25.10+ 时 NVIDIA 容器启动失败进行排障;兼容性背景参见 HAMi 是否兼容 NVIDIA GPU Operator 和 DCGM 指标?。 |
| 业务 Pod 无法访问 HAMi 共享目录 | 检查 selinux-relabel 日志和 HAMi 共享目录的宿主机 label。 |
卸载 Helm release 不会恢复 HAMi 修改过的宿主机 SELinux label 和目录权限。如果节点需要恢复原状态,请在安装前记录原始状态,并按组织的节点维护流程执行恢复。