升级 HAMi
本文仅适用于从 HAMi v2.10 升级到新版 Chart,不建议从其他版本直接按本文操作。如果当前使用的是更早版本,请先参考 v2.10 升级文档,将 HAMi 升级至 v2.10,再按本文继续升级。
升级影响
HAMi 升级会替换 hami-scheduler 和 hami-device-plugin,并重新生成设备配置,但不会影响正在运行的 GPU 工作负载,无需因此停止或迁移现有任务。不过,正在使用 HAMi-core 的工作负载不会自动切换到新版本。HAMi-core 在 Pod 创建时注入,运行中的进程不会重新加载该库。需要使用新版 HAMi-core 的工作负载,应在升级完成后执行滚动重启或重新创建 Pod。
升级期间建议暂停提交新的 HAMi GPU 工作负载,待 hami-scheduler、hami-device-plugin 和 admission webhook 完成更新后再恢复。组件滚动切换时可能出现短暂不可用或配置版本不一致,新任务可能因此调度失败或注入异常。
其他厂商的 device plugin 不在本文档讨论范围内,请参阅 HAMi 支持的设备。
升级前准备
配置变量
配置所需的变量来方便部署。接下来给出示例,请按照实际环境修改。
export namespace=kube-system
export release=hami
export hami_chart_dir="${HOME}/hami-upgrade/HAMi"
确认 HAMi 版本
升级前确认当前安装的是 HAMi 2.10:
helm list -n "${namespace}" --filter "^${release}$"
备份当前配置
升级前保存当前 release 的用户配置:
helm get values "${release}" -n "${namespace}" -o yaml > previous-values.yaml
直接修改过的设备 ConfigMap 不会记录在 Helm values 中。升级前还应保存其中的 data.device-config.yaml,用于迁移手工修改和回滚后核对配置。
以下命令以 hami-scheduler-device 为例;如果修改过 release 名称或名称覆盖配置,请替换为实际的 ConfigMap 名称:
kubectl get configmap hami-scheduler-device -n "${namespace}" \
--allow-missing-template-keys=false \
-o jsonpath='{.data.device-config\.yaml}' > previous-device-config.yaml
确认 previous-device-config.yaml 包含当前设备配置,并保留这份备份。迁移时只提取仍需保留的设置,不要将整份备份作为新版配置恢复。
获取 Chart
包含迁移变更的 Chart 尚未发布到 Helm 仓库。请使用 HAMi 提交 bf61e91 或包含该变更的后续提交,以确保包含旧字段校验的补充。以下命令以 bf61e91 为例,后续校验和升级均使用 ${hami_chart_dir} 中的 Chart:
git clone https://github.com/Project-HAMi/HAMi.git "${hami_chart_dir}"
git -C "${hami_chart_dir}" checkout bf61e91763b51105f821c573002baca4e0025329
该提交中的 Chart 是开发版本,不是已发布版本,其 version 和 appVersion 可能仍沿用上一版本。固定 Chart 提交不会固定后文使用的 latest 镜像标签。
迁移并创建 values
从 v2.10 升级到最新版 Chart 时,设备相关字段统一迁移到 devices.<vendor>。请先基于备份的 values 创建 my-values.yaml,完成字段迁移和渲染校验,再执行升级。
创建 values.yaml
从 previous-values.yaml 创建 my-values.yaml,作为整理升级配置的起点:
cp previous-values.yaml my-values.yaml
本文使用 latest 标签的 HAMi 镜像。Chart 默认使用 IfNotPresent 拉取策略,仅修改标签会继续使用节点上缓存的旧镜像。请在 my-values.yaml 中设置标签,并将 scheduler extender、HAMi device plugin 和 monitor 的拉取策略改为 Always:
global:
imageTag: latest
scheduler:
extender:
image:
pullPolicy: Always
devicePlugin:
image:
pullPolicy: Always
monitor:
image:
pullPolicy: Always
Always 会在容器启动时向镜像仓库解析标签对应的镜像。latest 仍是可变标签,不能保证不同时间启动的容器使用同一构建;远端标签更新也不会自动重启已有 Pod。
如果旧 values 中单独设置过 scheduler.extender.image.tag、devicePlugin.image.tag 或 devicePlugin.monitor.image.tag,请删除这些覆盖。
复制后,请按下节说明整理设备字段,不要直接将旧配置全部用于升级。其他仍需保留的自定义设置也应写入 my-values.yaml。升级后不要直接恢复整个旧 ConfigMap,以免覆盖新版默认配置。
迁移设备字段
Enflame、Kunlun、Vastai 和 Biren 的标准资源名现在由对应的设备字段自动加入 scheduler extender。这四类设备的 customresources 只保留额外资源,默认为空列表。旧 values 中复制过去的标准资源项应删除。
迁移前,先核对 previous-values.yaml,以及 previous-device-config.yaml 中曾手工修改过的设备配置。以升级前所用 Chart 版本的默认配置为基准,只将与默认值不同、升级后仍需保留的设置写入新 values。
- 对于旧 values 中的设备字段,按下方各厂商的字段映射迁移到新路径,并删除旧路径。
- 对于直接修改过的 ConfigMap 配置,找到对应的 Helm values 字段后再迁移,不要将 ConfigMap 的内容整体复制到 values 中。下方表格中的旧字段指旧 Helm values 路径,不是 ConfigMap 字段路径。
- 与旧版本默认值相同的设备字段应从
my-values.yaml中删除,不必写入对应的新路径,让新 Chart 使用其默认配置。
不要仅凭值是否为 0、false 或空字符串判断是否需要迁移;应与旧版本默认值比较。迁移后应删除下表列出的旧字段。Chart 会拒绝校验列表中的旧字段,但未被校验覆盖的旧字段可能被静默忽略,因此不能仅凭渲染成功判断迁移是否完成。
NVIDIA
包含 NVIDIA 资源字段和 NVIDIA Device Plugin 配置字段:
| v2.10 字段 | 最新版字段 |
|---|---|
resourceName | devices.nvidia.resourceCountName |
resourceMem | devices.nvidia.resourceMemoryName |
resourceMemPercentage | devices.nvidia.resourceMemoryPercentageName |
resourceCores | devices.nvidia.resourceCoreName |
resourcePriority | devices.nvidia.resourcePriorityName |
devicePlugin.deviceSplitCount | devices.nvidia.deviceSplitCount |
devicePlugin.deviceMemoryScaling | devices.nvidia.deviceMemoryScaling |
devicePlugin.deviceCoreScaling | devices.nvidia.deviceCoreScaling |
devicePlugin.preConfiguredDeviceMemory | devices.nvidia.preConfiguredDeviceMemory |
devicePlugin.enableNumaTopology | devices.nvidia.enableNumaTopology |
devicePlugin.runtimeClassName | devices.nvidia.runtimeClassName |
devicePlugin.createRuntimeClass | devices.nvidia.createRuntimeClass |
Cambricon
| v2.10 字段 | 最新版字段 |
|---|---|
mluResourceName | devices.cambricon.resourceCountName |
mluResourceMem | devices.cambricon.resourceMemoryName |
mluResourceCores | devices.cambricon.resourceCoreName |
Hygon
HAMi#2969 将 Hygon 设备的 DCU 命名统一改为 HCU,涉及资源名称、配置和注解。建议将 HCU(原 DCU)device plugin 升级到 Hygon 官方提供的最新版本 k8s-hcu-device-plugin。更新信息和配置说明见启用 Hygon HCU 共享。
| v2.10 字段 | v2.10 默认值 | 最新版字段 | 最新版默认值 |
|---|---|---|---|
dcuResourceName | hygon.com/dcunum | devices.hygon.resourceCountName | hygon.com/hcunum |
dcuResourceMem | hygon.com/dcumem | devices.hygon.resourceMemoryName | hygon.com/hcumem |
dcuResourceCores | hygon.com/dcucores | devices.hygon.resourceCoreName | hygon.com/hcucores |
删除与 v2.10 默认值相同的旧字段后,Chart 会使用新的 hygon.com/hcu* 资源名。升级时应核对 HCU device plugin 实际暴露的资源名,并同步调整后续提交的工作负载中的资源请求,使其与 Chart 配置一致。仅通过 Helm 渲染校验不能确认 Hygon 设备迁移完成。
MetaX
| v2.10 字段 | 最新版字段 |
|---|---|
metaxResourceName | devices.metax.resourceVCountName |
metaxResourceCore | devices.metax.resourceVCoreName |
metaxResourceMem | devices.metax.resourceVMemoryName |
metaxsGPUTopologyAware | devices.metax.sgpuTopologyAware |
metaxsGPUTopologyAware 在 v2.10 中使用字符串,默认值为 "false";新字段 devices.metax.sgpuTopologyAware 使用布尔值,默认值为 false。Chart 仍兼容字符串形式的 "true" 和 "false",迁移时建议使用不带引号的布尔值。旧值为默认的 "false" 时,删除旧字段即可;旧值为 "true" 时,将新字段设为 true。
Enflame
| v2.10 字段 | 最新版字段 |
|---|---|
enflameResourceNameDRSGCU | devices.enflame.resourceNameDRSGCU |
enflameResourceNameGCUMemory | devices.enflame.resourceNameGCUMemory |
enflameResourceNameGCUCore | devices.enflame.resourceNameGCUCore |
Kunlunxin
| v2.10 字段 | 最新版字段 |
|---|---|
kunlunResourceName | devices.kunlun.resourceCountName |
kunlunResourceVCountName | devices.kunlun.resourceVCountName |
kunlunResourceVMemoryName | devices.kunlun.resourceVMemoryName |
Vastai
| v2.10 字段 | 最新版字段 |
|---|---|
vastaiResourceName | devices.vastai.resourceCountName |
Biren
| v2.10 字段 | 最新版字段 |
|---|---|
birenResourceName | devices.biren.resourceCountName |
迁移示例
假设之前安装时使用了 override-values.yaml,内容如下:
resourceName: nvidia.com/gpu
devicePlugin:
deviceSplitCount: 20
disablecorelimit: "true"
其中,resourceName 与 v2.10 默认值相同,不需要保留;deviceSplitCount 从默认的 10 改为了 20,需要迁移;disablecorelimit 是自定义设置,但路径不变,需要原样保留。
此外,曾在 hami-scheduler-device ConfigMap 的 data.device-config.yaml 中,将以下字段从默认的 0 改为 4096(这里只展示相关片段):
nvidia:
defaultMemory: 4096
v2.10 的 Chart 模板将 defaultMemory 固定为 0,当时无法通过单独的 values 字段修改它。HAMi#3152 将这类配置开放为 values 字段,现在可以将这项手工修改迁移到 devices.nvidia.defaultMemory。
整理后的 my-values.yaml 如下:
devices:
nvidia:
deviceSplitCount: 20
defaultMemory: 4096
devicePlugin:
disablecorelimit: "true"
这份文件只保留需要覆盖的设置:迁移后的设备字段、从 ConfigMap 中提取的自定义配置,以及路径不变的自定义设置。resourceName 的旧路径和对应的新路径都不需要写入,交由新 Chart 提供默认值。
scheduler.overwriteEnv 和其他 devicePlugin 设置仍使用原路径,包括 enabled、镜像、deviceListStrategy、migStrategy、disablecorelimit 和 nodeConfiguration;如有自定义值,同样保留在原路径下。
如果之前使用了 device-config.content 或 Chart 内的 files/device-config.yaml,它们会整体替代自动生成的设备配置,不会与 devices.* 合并。若要改用 devices.* 管理配置,需要先整理并迁移其中仍需保留的设置,再移除原有的整份配置覆盖。
校验迁移后的配置
使用升级前准备中获取的本地 Chart,渲染迁移后的配置:
helm template "${release}" "${hami_chart_dir}/charts/hami" \
--namespace "${namespace}" \
--values my-values.yaml
执行升级
使用迁移后的 values 和 Chart 默认值重新渲染 release:
helm upgrade "${release}" "${hami_chart_dir}/charts/hami" \
--namespace "${namespace}" \
--reset-values \
--values my-values.yaml
--reset-values 会丢弃 release 中保存的旧 values。所有需要保留的覆盖都必须写入 my-values.yaml,或通过其他 --values 文件传入。
这次迁移不要使用 --reuse-values 或 --reset-then-reuse-values。这些选项会将旧 values 中的已删除字段带入新 Chart,可能导致渲染失败;未被校验覆盖的旧字段也不会因此恢复生效。
升级后验证
检查工作负载
kubectl get pods -n "${namespace}" \
-l "app.kubernetes.io/instance=${release}"
kubectl rollout status deployment -n "${namespace}" \
-l "app.kubernetes.io/instance=${release},app.kubernetes.io/component=hami-scheduler" \
--timeout=5m
kubectl rollout status daemonset -n "${namespace}" \
-l "app.kubernetes.io/instance=${release},app.kubernetes.io/component=hami-device-plugin" \
--timeout=5m
Pod 应处于 Running 状态,Deployment 和 DaemonSet 应完成滚动更新。
测试设备分配
用一个小型 Pod 验证 GPU 分配:
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: gpu-test-pod
namespace: default
spec:
containers:
- name: test
image: nvidia/cuda:12.2.0-runtime-ubuntu22.04
command: ["nvidia-smi"]
resources:
limits:
nvidia.com/gpu: 1
restartPolicy: Never
EOF
kubectl logs gpu-test-pod
kubectl delete pod gpu-test-pod
随后检查节点资源和 HAMi 注解:
kubectl describe nodes | grep -A 5 "Allocated resources"
kubectl get nodes -o yaml | grep -A 10 "hami.io"
回滚
先查看 release 历史:
helm history "${release}" -n "${namespace}"
回滚到上一个版本:
helm rollback "${release}" -n "${namespace}"
也可以指定 revision:
helm rollback "${release}" <revision-number> -n "${namespace}"
Helm 回滚使用历史 release 中保存的清单,不包含直接修改集群 ConfigMap 的记录。如果升级前手工修改过设备配置,回滚后应对照 previous-device-config.yaml 核对并恢复必要字段,不要直接覆盖整个 ConfigMap。保留迁移后的 my-values.yaml,再次升级时继续使用其中已整理的配置。
如果回滚后仍有工作负载异常,先恢复维护窗口前的 GPU 工作负载,再检查 scheduler、device plugin 和节点日志。
获取帮助
如果升级过程中遇到问题:
- 查看故障排查指南
- 检查 scheduler 和 device plugin 日志
- 查看 GitHub Issues
- 在社区讨论区提问