执行摘要
- 一句话:镜像与 CI 预装 kubectl/helm/k8s 客户端,为 kubernetes 功能铺路
- 推荐动作:建议重点阅读
docker/install-kube-tools.sh 的下载校验与清理模式,以及 pr-test.yml/docker-build.yml 中针对共享 runner 的锁等待与 --ignore-installed 处理;这两处是后续 CI/镜像维护中容易复用的工程经验。整体不值得精读,但作为 kubernetes 功能的前置基座值得留意后续消费它的 PR。
功能与动机
PR body 明确说明这是前置准备:Nothing on main uses these yet; they land ahead of the kubernetes work so the image is ready when it does。同时指出当前缺失会静默失败的三条路径:缺少 kubernetes_asyncio 导致相关模块在收集阶段失败;缺少 helm 时 chart 测试自我跳过并报告成功;缺少 kubectl 时 launcher 无法驱动 pod 内命令。
实现拆解
- 新增集中安装脚本
docker/install-kube-tools.sh:固定 kubectl v1.36.3 与 helm v4.2.3,从 dl.k8s.io 与 get.helm.sh 下载二进制/压缩包,与官方 sha256 校验和比对后再通过 install 落到 /usr/local/bin,并在同一 RUN 内清理临时文件。
- 接入两个 Dockerfile:
docker/Dockerfile 与 docker/Dockerfile.rocm 均新增 COPY docker/install-kube-tools.sh /tmp/install-kube-tools.sh,再执行安装脚本并通过 ${TARGETARCH} 传入架构,随后 rm -f 删除脚本本体;ROCm 镜像额外补充 ARG TARGETARCH 声明。
- 依赖清单
requirements.txt:新增 kubernetes_asyncio(36.1.0)。作者在 PR body 中核对镜像内已安装的包集合,确认 aiohttp、certifi、python-dateutil、pyyaml、six、urllib3 均已存在,不会引入新的传递依赖。
- 镜像重建触发链:
docker-build.yml 与 pr-test.yml 的路径过滤加入 docker/install-kube-tools.sh,保证将来升级工具版本时能触发镜像重建,避免改脚本但镜像不重建的脱节。
- CI runner 配套:
_run-cpu-ci.yml 与 pre-commit.yml 通过 azure/setup-helm@v4 安装 helm v4.2.3;pr-test.yml 与 docker-build.yml 将 python3/pip3 安装改为缺失才执行,并加上 DPkg::Lock::Timeout=600 等待 apt 锁、pip3 install --ignore-installed typer 规避 typer 0.27 与 rich 版本冲突。
配套验证:作者对 radixark/miles:pr-2404 镜像做 smoke test,确认三个工具版本正确、训练栈(torch 2.11.0+cu130、sglang、ray、megatron-core)未变、fast 测试 3322 passed、sglang 成功启动 Qwen2.5-0.5B-Instruct 完成推理。
关键文件:
docker/install-kube-tools.sh(模块 部署脚本;类别 infra;类型 infrastructure): 新的安装脚本集中管理 kubectl 与 helm 的下载、sha256 校验、安装和清理,两个 Dockerfile 都调用它,是本 PR 的核心资产。
.github/workflows/pr-test.yml(模块 CI 工作流;类别 infra;类型 infrastructure): 路径过滤加入 install-kube-tools.sh,并把 python3/pip3 安装改为按需 + 等待 apt 锁 + --ignore-installed,修复共享 runner 上的静默失败。
.github/workflows/docker-build.yml(模块 CI 工作流;类别 infra;类型 infrastructure): 镜像构建工作流同样加入路径过滤与 python/typer 修复,是本 PR 触发链的关键一环。
.github/workflows/_run-cpu-ci.yml(模块 CI 工作流;类别 infra;类型 infrastructure): CPU CI 中添加 helm 安装,保证 chart 测试在 CI 中真实执行而不自我跳过。
.github/workflows/pre-commit.yml(模块 CI 工作流;类别 infra;类型 infrastructure): pre-commit 环境也安装 helm,保证本地校验与 CI 行为一致。
docker/Dockerfile.rocm(模块 镜像构建;类别 infra;类型 infrastructure): ROCm 镜像补上 ARG TARGETARCH 并调用安装脚本,保持与主镜像工具链一致。
docker/Dockerfile(模块 镜像构建;类别 infra;类型 infrastructure): 主镜像调用安装脚本,把 kubectl/helm 打进镜像层。
requirements.txt(模块 依赖清单;类别 config;类型 dependency): 新增 kubernetes_asyncio 依赖,供 k8s worker provider 使用;作者验证无新增传递依赖。
关键符号:未识别
关键源码片段
docker/install-kube-tools.sh
新的安装脚本集中管理 kubectl 与 helm 的下载、sha256 校验、安装和清理,两个 Dockerfile 都调用它,是本 PR 的核心资产。
#!/usr/bin/env bash
# 安装 kubectl 与 helm 到 /usr/local/bin 目录,固定版本并做 sha256 校验。
# PR#2404 为后续 kubernetes 工作提前准备镜像内工具链。
set -euxo pipefail
# 版本集中定义,升级时只改这里
KUBECTL_VERSION="v1.36.3"
HELM_VERSION="v4.2.3"
# 支持显式传入架构;Dockerfile 里通过 ARG TARGETARCH 传入
arch="${1:-}"
[ -n "$arch" ] || arch="$(dpkg --print-architecture)"
# kubectl 组件:下载二进制与校验和,校验通过后安装,失败立即中断
curl -fsSL -o /tmp/kubectl "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/${arch}/kubectl"
curl -fsSL -o /tmp/kubectl.sha256 "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/${arch}/kubectl.sha256"
echo "$(cat /tmp/kubectl.sha256) /tmp/kubectl" | sha256sum -c -
install -m 0755 /tmp/kubectl /usr/local/bin/kubectl
# helm 组件:下载 tar 包与校验和;awk 只取哈希字段,避免换行干扰校验
curl -fsSL -o /tmp/helm.tar.gz "https://get.helm.sh/helm-${HELM_VERSION}-linux-${arch}.tar.gz"
curl -fsSL -o /tmp/helm.tar.gz.sha256 "https://get.helm.sh/helm-${HELM_VERSION}-linux-${arch}.tar.gz.sha256sum"
echo "$(awk '{print $1}' /tmp/helm.tar.gz.sha256) /tmp/helm.tar.gz" | sha256sum -c -
tar -xzf /tmp/helm.tar.gz -C /tmp
install -m 0755 "/tmp/linux-${arch}/helm" /usr/local/bin/helm
# 清理临时文件,避免把校验和与压缩包带进镜像层
rm -rf /tmp/kubectl /tmp/kubectl.sha256 /tmp/helm.tar.gz /tmp/helm.tar.gz.sha256 "/tmp/linux-${arch}"
# 安装后立即验证,构建期就能发现装错
kubectl version --client
helm version --short
评论区精华
review 环节无实质讨论,guapisolo 直接 APPROVED,无评论内容。唯一有价值的补充来自作者在 issue 评论中的镜像 smoke test:验证 kubectl v1.36.3、helm v4.2.3、kubernetes_asyncio 36.1.0 均安装正确,且训练栈(torch、sglang、ray、megatron-core)未受影响,fast 测试通过、sglang 可正常服务模型。这直接回应了“镜像体积变大是否影响训练/推理路径”的潜在疑虑。
风险与影响
-
风险:
- 新增两个构建期外部下载源(
dl.k8s.io、get.helm.sh),虽有 pin 与 sha256 校验兜底,但上游发布策略变化可能拉长镜像构建时间或导致构建失败。
requirements.txt 新增 kubernetes_asyncio 后,所有按该清单安装的环境都会引入它;作者确认无新增传递依赖,但安装期生成约 21 MiB __pycache__,会反映在镜像层尺寸上。
- 镜像体积增加约 38.7 MiB 拉取量(磁盘约 145-165 MiB),对 19.12 GB 整体镜像占比很小,但仍是长期膨胀的一部分。
pr-test.yml 与 docker-build.yml 的 apt 锁处理只覆盖当前两个 job,其他 workflow 若复用同一共享 runner,仍可能遇到同类锁竞争。
- kubectl/helm 版本固定后需要团队持续跟进安全更新;版本升级成本虽集中在一个脚本,但仍需维护。
- 影响:对用户:镜像体积略增但功能无感知,后续 kubernetes 相关功能可直接使用镜像内工具链。
对系统:CI 构建链路新增两个下载与校验步骤,chart 测试不再自我跳过,CI 结果更可信,共享 runner 的锁竞争问题得到缓解。
对团队:新增三个需要跟进版本的依赖与两个外部下载源;kubernetes 工作落地时无需再改镜像构建逻辑,路径过滤已保证版本变更会触发镜像重建。
-
风险标记:外部下载源新增, 镜像体积增加, 共享 runner 锁竞争, 依赖版本维护, 当前无运行时使用
关联脉络
- PR #2363 ci(docker): run image builds on docker-build runners: 本 PR 的第三个 commit 修复了 #2363 引入的 docker-build runner 上 python3/typer 安装与 apt 锁竞争问题,属于同一 CI 镜像构建基础设施演进线。
参与讨论