把 Kubeflow 故障现场带回 Kubernetes:用 Headlamp 插件直查 CRD 与 Pod

2026-07-14 29 预计阅读时间: 1 分钟
来源: kubernetes.io AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:9 分钟

Kubernetes 已经承载了越来越多的 AI/ML 工作负载:Notebook、分布式训练、超参数搜索、流水线和 Spark 作业最终都会落到 Pod、存储卷、调度器与自定义资源上。Kubeflow 用 CRD 描述这些能力,但面向数据科学家的专用控制台往往隐藏了底层 Kubernetes 状态。Headlamp Kubeflow 插件补上了这层视角,让运维人员在通用 Kubernetes UI 中直接检查 Kubeflow 资源及其关联的 Pod。

为什么 ML 控制台不能替代集群视角

数据科学家通常关心实验参数、模型指标和流水线结果,平台工程师处理的却是另一组问题:Notebook 为什么一直无法启动,训练容器是否被 OOMKilled,镜像是否拉取失败,PVC 是否尚未绑定,或者 GPU 请求是否超过了节点容量。

这些故障最终由 Kubernetes API 暴露。Headlamp Kubeflow 插件直接读取 API Server,不依赖额外的 ML 中间服务或数据库,因此能展示 Kubernetes 报告的 Pod condition、失败原因和跨命名空间资源状态。对于 Kubeflow Pipelines,这种设计还有一个实际价值:即使 Pipelines API 服务或后端数据库暂时不可用,已经保存在 Kubernetes API 中的资源状态仍可检查。

插件面向不同组件提供相应视图:

  • Notebooks:NotebookProfilePodDefault
  • Pipelines:PipelinePipelineVersionRunRecurringRunExperiment
  • Katib:ExperimentTrialSuggestion
  • Training:TrainJobTrainingRuntimeClusterTrainingRuntime
  • Spark:SparkApplicationScheduledSparkApplication

Kubeflow 本身是模块化的,插件会发现集群中已经安装的 API Group,只显示实际存在的组件。这一点很重要:只部署训练和 Katib 的集群,不需要承受一整套空白菜单。

一个详情页应该回答哪些问题

Notebook 详情页不仅列出对象 YAML,还汇总 Pod condition 及其 reasonmessage,并展示 CPU、内存和 GPU 的 requests/limits。卷挂载可以追溯到 PVC、ConfigMap、Secret 或 emptyDir,环境变量引用的 Secret 和 ConfigMap、sidecar 容器以及节点 toleration 也能集中查看。过去需要多次执行 kubectl describe 才能拼出的故障现场,被压缩到同一个页面里。

Katib 视图关注搜索过程:调优算法、参数空间、各个 Trial 的实时状态、当前最佳 Trial 的指标与参数,以及 early stopping 配置和提前停止的 Trial 数量。运维人员因此既能看到业务层面的搜索进度,也能继续下钻到底层资源。

Pipelines 视图则展示 Run 状态和持续时间,把 RecurringRun 的计划转换为更容易阅读的时间表达,并从近期 Run 中聚合 pipelineRoot。Pipeline 详情还可以并排比较最新与上一版 PipelineVersion 的 YAML,帮助定位版本变更带来的行为差异。

插件也把 Notebook、Profile、PodDefault、Experiment、Pipeline、SparkApplication 和 TrainJob 注册为 Headlamp 资源图节点,并依据 .metadata.ownerReferences 绘制关系边。这个图适合回答“这个失败 Pod 是谁创建的”和“一个领域资源下面派生了哪些对象”。不过,只有写入 owner reference 的关系才能自动呈现;通过标签、名称或外部数据库建立的逻辑关系不会凭空出现。

可以这样实践:先用 kubectl 验证插件将看到什么

下面的命令适用于已经安装部分 Kubeflow 组件的集群。它不会修改资源,可以直接复制执行;运行前只需确认当前 kubectl context 指向目标集群。

# 查看集群中与 Kubeflow、Katib、Training、Spark 相关的 API 资源
kubectl api-resources --verbs=list --namespaced -o wide \
  | grep -Ei 'kubeflow|katib|training|spark|notebook|pipeline'

# 搜索常见的 Kubeflow CRD;模块化安装中只会返回已安装部分
kubectl get crd -o name \
  | grep -Ei 'kubeflow|katib|training|spark|notebook|pipeline'

# 跨命名空间检查异常 Pod
kubectl get pods -A \
  --field-selector=status.phase!=Running,status.phase!=Succeeded \
  -o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,PHASE:.status.phase,REASON:.status.reason,NODE:.spec.nodeName'

如果 Notebook 已经创建了 Pod,可以用标签或 owner reference 找到它,然后检查容器等待、终止原因和资源请求。下面示例中的命名空间需要替换为实际值:

NAMESPACE=kubeflow-user-example-com

kubectl get pods -n "$NAMESPACE" -o json \
  | jq -r '.items[] | {
      pod: .metadata.name,
      owners: [.metadata.ownerReferences[]?.kind + "/" + .metadata.ownerReferences[]?.name],
      waiting: [.status.containerStatuses[]? | select(.state.waiting) | {
        container: .name,
        reason: .state.waiting.reason,
        message: .state.waiting.message
      }],
      terminated: [.status.containerStatuses[]? | select(.state.terminated) | {
        container: .name,
        reason: .state.terminated.reason,
        exitCode: .state.terminated.exitCode
      }]
    }'

这段查询需要本机安装 jq。它相当于一个最小化的故障视图:如果结果出现 ImagePullBackOffCreateContainerConfigErrorOOMKilled,应继续检查镜像凭据、Secret/ConfigMap 引用和内存限制;如果 Pod 长时间处于 Pending,则应查看事件、PVC、污点容忍和 GPU 等扩展资源。

POD_NAME=replace-with-pod-name

kubectl describe pod -n "$NAMESPACE" "$POD_NAME"
kubectl get events -n "$NAMESPACE" \
  --field-selector="involvedObject.name=$POD_NAME" \
  --sort-by='.lastTimestamp'

这些命令不是插件安装步骤,而是一组对照检查:部署 Headlamp 插件后,应该能够在 UI 中更快获得同类信息,并从 Kubeflow CRD 导航到相关 Kubernetes 对象。

推广到其他 CRD 平台时的边界

Headlamp Kubeflow 插件展示了一种可复用模式:领域控制台继续服务工作流提交者,通用 Kubernetes UI 则通过插件为运维人员呈现 CRD、Pod、事件和资源关系。这个模式同样适用于数据库 Operator、消息系统、推理平台和内部发布平台。

落地前可以检查四件事:

  • RBAC 是否只授予插件读取所需 CRD、Pod、事件和配置对象的权限。
  • Secret 引用可以显示,但 Secret 内容不应在普通详情页中泄露。
  • API Group 和版本是否与集群实际安装的 Kubeflow 组件一致。
  • owner reference 是否完整;否则资源图可能遗漏真实依赖关系。
  • 集群规模是否需要分页、缓存或限制跨命名空间查询,避免 UI 给 API Server 增加不必要的压力。

Headlamp 可作为桌面应用运行,也可以部署到集群内。试点时,适合先接入一个非生产集群,选择 Notebook 卡住、Katib Trial 失败和 Pipeline Run 异常三类真实案例,对比插件页面与 kubectl describe 的结论。只有当 UI 能稳定暴露 Kubernetes 报告的原始原因,它才真正减少了排障切换,而不只是增加了另一块仪表盘。


相关推荐