跳到主要内容
EnterpriseAI Platform

Zarf 迁移手册

本文用于指导已部署 HAMi Enterprise/AI Platform 的集群迁移到 Zarf 离线包部署。适用对象是负责集群交付、升级和运维的客户侧 SRE、平台工程师或 Kubernetes 管理员。

文中的包名、组件名和 values 文件名请按实际交付包替换。示例中使用:

<PACKAGE_FILE> # HAMi Enterprise Zarf 主部署包,例如 hami-enterprise-*.tar.zst
<VALUES_FILE> # 迁移时使用的 values 文件,例如 my-overrides.yaml

推荐迁移路线

先判断当前 HAMi Enterprise 是怎么安装的:

--adopt-existing-resources--force-conflicts 是 2 个重要的 zarf package deploy 参数。

当前状态推荐做法默认使用 --adopt-existing-resources默认使用 --force-conflicts
集群里还没有 HAMi Enterprise直接使用 Zarf 部署
已有同名 Helm release用 Zarf 包接管后续部署和升级入口
已有不同名 Helm release建议维护窗口内迁移,不建议两个 release 管同一批资源视情况
资源由 Kustomize 或 kubectl apply 创建使用 --adopt-existing-resources 接管资源仅字段冲突时
只是部分字段被 HPA 或人工 kubectl 改过正常部署,遇到 SSA 字段冲突时再处理必要时

不建议让旧 Helm release 和 Zarf 管理的 release 长期同时管理同一批对象。后续任何一边执行 upgrade、rollback 或 uninstall,都可能影响另一边已经接管的资源。

使用 Zarf 安装组件带来的限制

镜像改写范围应通过标签明确控制

建议在初始化时使用 zarf init --agent-mutation-policy=labeled。此策略只改写带 zarf.dev/agent: mutate 标签的资源,或位于带该标签 Namespace 中的资源;需要保留原镜像地址的单个工作负载可标记 zarf.dev/agent: ignore,且资源标签优先于 Namespace 标签。因此,同一集群甚至同一 Namespace 中可以按资源划分是否由 Zarf 改写,不再需要让 Agent 默认接管全部业务 Namespace。需要注意:只有已经打入 Zarf package 的镜像才能在离线环境中被改写并拉取;修改标签后还需重新创建 Pod,已创建 Pod 不会自动变化。

同一批资源应由单一交付链管理

Zarf 通过 Helm 管理 package 中的 Chart release。对同一批 Kubernetes 资源再并行使用另一套原生 Helm 流程,仍可能产生 release ownership、字段所有权和升级顺序冲突。日常升级应继续使用新的 Zarf package;若确需把已有资源交给 Zarf 管理,应先核对 release 和资源范围,再使用 --take-ownership--force-conflicts 仅用于确认可以覆盖的 Server-Side Apply 字段冲突,不应作为常规安装参数。

迁移前准备

1. 确认工具可用

kubectl version
kubectl get nodes
zarf version

如果目标环境没有单独安装 Helm,可以使用 Zarf 自带的 Helm:

zarf tools helm version
zarf tools helm list -A

2. 确认当前安装方式

查看当前 Helm release:

zarf tools helm list -A

如果看到 HAMi Enterprise 对应 release,记录它的 namespace 和 release name。常见情况是:

namespace: hami-system
release: hami

查看 HAMi 相关资源:

kubectl get ns hami-system
kubectl -n hami-system get pods,deploy,ds,svc,cm,secret

查看资源上的 Helm 归属信息:

kubectl -n hami-system get deploy,ds,svc,cm,secret,sa,role,rolebinding \
-o custom-columns='KIND:.kind,NAME:.metadata.name,MANAGED_BY:.metadata.labels.app\.kubernetes\.io/managed-by,RELEASE:.metadata.annotations.meta\.helm\.sh/release-name,RELEASE_NS:.metadata.annotations.meta\.helm\.sh/release-namespace'

查看 HAMi 相关集群级资源:

kubectl get clusterrole,clusterrolebinding,mutatingwebhookconfiguration,validatingwebhookconfiguration \
-o name | grep -i hami

3. 备份现有配置和状态

如果当前是 Helm release:

zarf tools helm -n hami-system get values <OLD_RELEASE> -o yaml > hami-current-values.yaml
zarf tools helm -n hami-system get manifest <OLD_RELEASE> > hami-current-manifest.yaml
zarf tools helm -n hami-system status <OLD_RELEASE> > hami-current-status.txt

如果当前不是 Helm 管理,也建议导出现有 YAML:

kubectl -n hami-system get deploy,ds,svc,cm,secret,sa,role,rolebinding -o yaml > hami-current-resources.yaml

保存当前运行状态:

kubectl -n hami-system get pods -o wide
kubectl get nodes --show-labels
kubectl get events -A --sort-by=.lastTimestamp | tail -100

如果集群里已有 HAMi license Secret 或客户侧自定义配置,请一并备份。

4. 准备迁移用 values

通常可以从现有 Helm values 开始整理:

cp hami-current-values.yaml <VALUES_FILE>

请重点核对:

  • 是否启用 DRA。

  • hami-scheduler 副本数是否适合集群规模。

  • 是否启用 scheduler leader election。

  • kube-scheduler 镜像版本是否与目标 Kubernetes 版本匹配。

  • GPU 节点是否使用 gpu=on 标签。

  • 是否需要保留已有 webhook、RBAC、Service、ConfigMap 的名称。

部署前离线检查

部署前建议先查看 values 合并结果:

zarf package inspect values-files <PACKAGE_FILE> \
--components=hami-deploy-scripts,hami \
--values=<VALUES_FILE> \
--features="values=true"

再查看 Zarf 包将要部署的 manifests:

zarf package inspect manifests <PACKAGE_FILE> \
--components=hami-deploy-scripts,hami \
--values=<VALUES_FILE> \
--features="values=true" \
> hami-zarf-rendered.yaml

检查重点:

  • 目标 namespace 是否正确。

  • 目标 release name 是否与迁移方案一致。

  • 资源名称是否与现有资源对应。

  • 镜像是否都来自离线包或目标环境可访问的 registry。

  • values 是否正确覆盖了当前集群需要的配置。

场景一:已有同名 Helm release

适用条件:

  • 当前 HAMi Enterprise 已由 Helm 安装。

  • 旧 release name 与 Zarf 包中的 HAMi release name 一致。

  • namespace 一致。

  • 后续希望统一通过 Zarf 包部署和升级。

这种情况下,通常按 Helm upgrade 思路迁移。不要默认添加 --adopt-existing-resources--force-conflicts

执行迁移:

zarf package deploy <PACKAGE_FILE> \
--components=hami-deploy-scripts,hami \
--values=<VALUES_FILE> \
--features="values=true" \
--confirm

迁移后检查:

zarf package list
zarf tools helm -n hami-system status hami
kubectl -n hami-system get pods
kubectl -n hami-system rollout status deploy/hami-scheduler

迁移完成后,请把日常升级入口切换到 Zarf 包。除非是在执行明确的回退方案,否则不要再用旧 Helm 流程直接升级同一个 release。

场景二:已有不同名 Helm release

如果旧 release name 与 Zarf 包中的 release name 不一致,这是高风险迁移。不要直接部署一个新的 Zarf release 去覆盖同一批资源。

推荐在维护窗口内选择一种方案:

方案适用情况说明
使用与旧 release name 一致的 Zarf 包希望尽量原地迁移需要确认交付包中的 release name 已匹配旧环境
卸载旧 release 后部署 Zarf可以接受短暂停机或重建生命周期最清晰
使用 --adopt-existing-resources 接管资源必须保留,且不能重建需要逐项核对资源归属,风险较高

如果选择卸载旧 release 后部署 Zarf,先确认已经备份 values、manifest、license Secret 和必要配置。然后在维护窗口内执行:

zarf tools helm -n hami-system uninstall <OLD_RELEASE>

zarf package deploy <PACKAGE_FILE> \
--components=hami-deploy-scripts,hami \
--values=<VALUES_FILE> \
--features="values=true" \
--confirm

如果选择接管已有资源,至少先确认:

  • 旧 Helm release 后续不会再执行 upgrade、rollback 或 uninstall。

  • Zarf 渲染出的资源名称与现有资源能够对应。

  • 资源所在 namespace 没有混入其他系统的同名或同类资源。

  • 已有完整备份,并且有维护窗口。

接管命令示例:

zarf package deploy <PACKAGE_FILE> \
--components=hami-deploy-scripts,hami \
--values=<VALUES_FILE> \
--features="values=true" \
--adopt-existing-resources \
--confirm

只有部署日志明确显示 Server-Side Apply 字段冲突,并且确认这些字段应由 Zarf/Helm 接管时,才考虑叠加 --force-conflicts

zarf package deploy <PACKAGE_FILE> \
--components=hami-deploy-scripts,hami \
--values=<VALUES_FILE> \
--features="values=true" \
--adopt-existing-resources \
--force-conflicts \
--confirm

这不是默认迁移命令,只用于已经确认接管范围和字段冲突来源的情况。

场景三:现有资源由 Kustomize 或 kubectl apply 管理

如果现有 HAMi Enterprise 资源不是 Helm release,而是通过 Kustomize 或 kubectl apply 创建,迁移重点是把这些资源纳入 Zarf 管理的 Helm chart。

推荐流程:

  1. 导出现有 YAML。

  2. 使用 Zarf 渲染目标 manifests。

  3. 对比资源名称、namespace、labels、annotations 和关键 spec。

  4. 使用 --adopt-existing-resources 接管。

  5. 只有遇到 Server-Side Apply 字段冲突时,再使用 --force-conflicts

接管命令:

zarf package deploy <PACKAGE_FILE> \
--components=hami-deploy-scripts,hami \
--values=<VALUES_FILE> \
--features="values=true" \
--adopt-existing-resources \
--confirm

如果失败信息明确是字段 ownership 冲突,再执行:

zarf package deploy <PACKAGE_FILE> \
--components=hami-deploy-scripts,hami \
--values=<VALUES_FILE> \
--features="values=true" \
--adopt-existing-resources \
--force-conflicts \
--confirm

Prometheus 和 GPU Operator

迁移 HAMi Enterprise 不等于必须同时接管 Prometheus 或 NVIDIA GPU Operator。

如果集群已经有 Prometheus 或 GPU Operator,建议先只迁移 HAMi:

zarf package deploy <PACKAGE_FILE> \
--components=hami-deploy-scripts,hami \
--values=<VALUES_FILE> \
--features="values=true" \
--confirm

需要迁移 Prometheus 或 GPU Operator 时,请分别按它们自己的 release、namespace、values 和资源归属做评估。

特别注意:

  • 如果集群已有 GPU Operator,通常不要重复部署 Zarf 包里的 gpu-operator component。

  • 如果 GPU Operator 默认 NVIDIA device-plugin 与 HAMi device-plugin 冲突,应通过 GPU Operator values 禁用默认 device-plugin。

  • --force-conflicts 不能解决两个 device-plugin 同时运行导致的运行时冲突。

迁移后验收

检查 Zarf 包状态:

zarf package list

检查 Helm release:

zarf tools helm -n hami-system status hami
zarf tools helm -n hami-system get values hami

检查核心组件:

kubectl -n hami-system get pods -o wide
kubectl -n hami-system rollout status deploy/hami-scheduler
kubectl get nodes --show-labels | grep gpu=on

检查证书和 GPU 调度链路:

bash collect-hami-license-info.sh
kubectl describe node <GPU_NODE_NAME>

如交付包包含示例 workload,可继续使用 GPU burn 或 vLLM 示例验证调度链路。

回滚建议

回滚方案取决于迁移方式:

迁移方式回滚思路
同名 Helm release 迁移使用迁移前保存的 values 和 manifest,按既定 Helm/Zarf 回退流程恢复
卸载旧 release 后重新部署 Zarf使用旧 release values 和原 Helm chart 重新安装
--adopt-existing-resources 接管回滚前先确认资源 ownership,避免旧 release uninstall 删除正在使用的资源
Kustomize / kubectl apply 接管使用迁移前导出的 YAML 和变更记录恢复

任何回滚都建议在维护窗口内执行。不要在没有确认资源归属的情况下直接删除 release 或 namespace。

常见问题处理

现象可能原因处理
invalid ownership metadata资源已存在,但 Helm release ownership 不匹配或缺失判断是否需要 --adopt-existing-resources,或在维护窗口内清理冲突资源
field manager conflict / SSA conflict某些字段由其他 manager 管理确认字段应由 Zarf/Helm 接管后,再使用 --force-conflicts
旧 Helm release uninstall 后资源被删除旧 release 仍然认为自己拥有这些资源不要让两个 release 同时管理同一批资源;回滚前先确认 ownership
hami-device-pluginCrashLoopBackOff可能与 NVIDIA 默认 device-plugin 冲突禁用 GPU Operator 内置 device-plugin,检查 GPU 驱动
workload 一直 Pending证书未激活、GPU 节点未打标签、GPU 不足检查 license、gpu=on 标签和 kubectl describe pod 事件
scheduler 启动异常values、镜像版本或 leader election 配置不匹配核对 <VALUES_FILE> 和目标 Kubernetes 版本

参考