LMCache K8s 测试流水线(k3_tests)完整指南:Buildkite Web UI 配置、路径过滤与新增测试
LMCache K8s 测试流水线k3_tests完整指南Buildkite Web UI 配置、路径过滤与新增测试【免费下载链接】LMCacheLMCache: Supercharge Your LLM with the Fastest KV Cache Layer项目地址: https://gitcode.com/GitHub_Trending/lm/LMCache本文档是 LMCache 仓库中.buildkite/k3_tests/目录的实战指南。它讲解了如何借助 Buildkite 与 agent-stack-k8s在单节点 K3s 集群上按需拉起 GPU Pod 执行 LMCache 的各类 CI 测试——包括 Web UI 的逐流水线配置、基于路径过滤的文档改动自动跳过auto-pass、触发器策略以及如何为新的测试目录编写run.sh、pipeline.yml与buildkite-pipeline.yml。读完本文你将掌握一套可复制、可运行的 K8s 原生 CI 测试框架搭建方法并能对照仓库源码理解其底层实现。概览k3_tests 目录结构在 .buildkite/k3_tests/ 下每个子目录都是一个自包含self-contained的测试统一包含以下四类文件文件用途run.sh测试脚本sourcek3_harness/setup-env.sh等环境脚本后执行测试pipeline.ymlK8s Pod 规格——GPU 数量、卷挂载、超时时间等buildkite-pipeline.yml粘贴到 Buildkite UI Steps 编辑器中的内容先跑路径过滤再上传pipeline.ymlBK_WEB_SETUP.md完整的 Buildkite UI 配置说明环境变量、触发器过滤条件、配置建议以 unit 为例该测试不需要 vLLM仅运行 pytest 覆盖率测试multiprocess 则包含 20 余个脚本scripts 下的run-p2p.sh、run-lm-eval.sh、run-deadlock.sh等覆盖多进程模式下的 P2P、容错、HTTP API、延迟卸载等场景。仓库内已有的测试目录还包括amd、blend、comprehensive、correctness、integration、musa、sglang、xpu等它们遵循同一套文件约定。前置条件创建名为k8s的队列在创建任何流水线之前需要先在 Buildkite 集群中创建一个名为k8s的队列进入Organization Settings → Default cluster → Queues → New Queue创建即可。该队列不需要任何配置也不需要注册任何 agent。因为这里使用的是 agent-stack-k8s 方案——它在 K8s 中运行一个 controller Pod持续轮询 Buildkite 中匹配队列的任务一旦有任务到达就创建一个临时的 Pod 来执行任务结束随即删除 Pod。这区别于传统裸机 agent模式在机器上安装 Buildkite agent 二进制、注册到 Web UI 创建的队列、以 systemd 服务管理。详细对比与一次性集群安装K3s GPU Operator CI 基础镜像可参考 .buildkite/k3_harness/README.md。如果你希望使用其他队列名可在安装 agent-stack 时通过环境变量指定BUILDKITE_QUEUEmy-queue .buildkite/k3_harness/install-agent-stack.sh AGENT_TOKEN GITHUB_TOKEN而流水线步骤中通过agents.queue指定队列名两者必须一致。逐流水线配置Buildkite Web UI 操作步骤配置流程对于每个测试目录在 Buildkite UI 中创建一个流水线每个目录下的BK_WEB_SETUP.md都记载了该测试的精确设置环境变量、GitHub 触发器过滤条件与配置建议。简版步骤如下进入组织 →New Pipeline在Steps编辑器中粘贴该测试的buildkite-pipeline.yml内容agents: queue: k8s env: HF_TOKEN: your HuggingFace token steps: - label: :pipeline: Upload pipeline command: buildkite-agent pipeline upload .buildkite/k3_tests/test-name/pipeline.ymlagents.queue必须与你上面创建的队列名一致。它将上传步骤路由到 agent-stack-k8s先检出仓库、运行路径过滤若构建未被跳过则上传真正的pipeline.yml后续每个步骤同样指向该队列。HF_TOKEN用于访问受门控的模型如 Llama、Qwen。可以像上面那样在env块中设置也可以在Pipeline Settings → Environment Variables中设置两种方式均可。在GitHub Settings下按照该测试BK_WEB_SETUP.md中的说明配置触发器过滤条件保存——任务会自动在 K8s 队列上运行。需要说明的是当前仓库中已实际使用的上传步骤统一改用了common_scripts/upload-pipeline.sh包装脚本见下文基于路径的跳过而非直接调用buildkite-agent pipeline upload。例如 unit/buildkite-pipeline.yml 中的命令为- label: :pipeline: Upload pipeline command: bash .buildkite/k3_tests/common_scripts/upload-pipeline.sh .buildkite/k3_tests/unit/pipeline.yml触发器策略并非所有测试都应在每次 push 时运行仓库给出的通用模式如下测试重量触发时机过滤条件示例轻量级1 GPU20 分钟每次 push / 每个 PR无过滤重量级多 GPU30 分钟PR label 或 main 分支build.pull_request.labels includes full \|\| build.branch dev对于按 label 触发的流水线务必将Rebuild on PR label change设为Yes这样给已有 PR 添加 label 就能触发构建。以 multiprocess/BK_WEB_SETUP.md 为例其过滤器为build.pull_request.labels includes mp || build.pull_request.labels includes full || build.branch dev这是一个 2 GPU、Docker-in-Docker、约 45 分钟的重型测试只会在mp/fulllabel 或 dev 分支推送时运行而不是每个 PR 都跑而 correctness/BK_WEB_SETUP.md 是 1 GPU 轻量测试过滤器为空每个 push/PR 都运行适合作为必须通过的 GitHub status check。基于路径的跳过文档改动自动通过buildkite-pipeline.yml的上传步骤运行common_scripts/upload-pipeline.sh而不是直接执行buildkite-agent pipeline upload。该包装脚本.buildkite/k3_tests/common_scripts/upload-pipeline.sh内部 source 了 path-filter.sh对构建中变更的文件进行检查其行为为跳过Skip当所有变更文件都匹配琐碎trivial模式时——*.md、LICENSE*、NOTICE*、.gitignore、.gitattributes、.editorconfig、.mailmap、CODEOWNERS或位于docs/、asset/、.github/下的任何文件——脚本直接以 0 退出且不上传pipeline.yml构建只有一个上传步骤且为绿色auto-pass。其中.github/被视为琐碎是因为 k3 测试运行在 Buildkite 而非 GitHub Actions 上workflow / CODEOWNERS / 模板的改动不会影响它们强制运行Force-run当任何变更文件位于.buildkite/下时——这类 PR 通常是在修复 k3 CI 本身因此希望在 PR 上直接测试而不是等合入后再测正常运行Run只要存在至少一个非琐碎文件就上传包含真实测试步骤的pipeline.yml。变更文件的检测逻辑见path-filter.sh中_path_filter_get_changed_filesPR 构建基于origin/${BUILDKITE_PULL_REQUEST_BASE_BRANCH}默认为main的 merge-base 做 diff由于 Buildkite 是浅克隆shallow clone脚本会先git fetch --no-tags --depth200 origin $base_branch拉取足够的历史Push 构建diffHEAD~1..HEAD定时构建BUILDKITE_SOURCEschedule从不跳过例如夜间 baseline 上传场景无法确定变更文件浅克隆无父提交、缺失 base 分支等回退为不跳过safer default。在should_skip_ci()中还有一个显式的 opt-out若 GitHub PR 上添加了force-cilabelBuildkite 会自动拾取 PR labels通过BUILDKITE_PULL_REQUEST_LABELS环境变量暴露此时无论变更了哪些文件都会运行完整流水线。此外upload-pipeline.sh在跳过时会通过buildkite-agent annotate --style success在构建上标注已跳过仅琐碎文件变更的说明便于排查。新增一个测试的完整步骤创建目录.buildkite/k3_tests/test-name/编写run.shsource 共享的环境设置脚本#!/usr/bin/env bash set -euo pipefail cd $(cd $(dirname $0)/../../.. pwd) source .buildkite/k3_harness/setup-env.sh # ... your test commands ...仓库中的真实示例可参考 unit/run.sh它先为本次构建创建独立 scratch 子目录并通过LMCACHE_TEST_TMPDIR暴露避免并发 Pod 冲突然后 sourcesetup-lmcache-only-env.sh、用uv pip install -r requirements/test.txt安装依赖、生成未跟踪的 gRPC 绑定python lmcache/v1/multiprocess/transport/grpc_impl/_proto_gen/_generate.py最后带覆盖率运行 pytest。编写pipeline.yml将 GPU 限制设置为测试所需steps: - label: :test_tube: My Test command: .buildkite/k3_tests/test-name/run.sh timeout_in_minutes: 30 agents: { queue: k8s } plugins: - kubernetes: podSpec: containers: - name: container-0 image: lmcache/ci-base:latest imagePullPolicy: Never # local image, imported into K3s containerd resources: limits: nvidia.com/gpu: 1 volumeMounts: - { name: hf-cache, mountPath: /root/.cache/huggingface } volumes: - { name: hf-cache, hostPath: { path: /data/huggingface, type: DirectoryOrCreate } }关于 CI 基础镜像ci-base.Dockerfile.buildkite/k3_harness/ci-base.Dockerfile构建一个包含 CUDA Python 3.12 uv 构建依赖不含 vLLM/LMCache的镜像由setup-cluster.sh自动构建、自动检测 GPU 计算能力设置TORCH_CUDA_ARCH_LIST并直接导入 K3s containerd无需 registry因此imagePullPolicy: Never是合理的。修改requirements/*.txt或 Dockerfile 后用REBUILD_IMAGE1 .buildkite/k3_harness/setup-cluster.sh重建。编写buildkite-pipeline.yml粘贴进 Buildkite UI Steps 编辑器的片段使用common_scripts/upload-pipeline.sh以获得基于路径的跳过agents: queue: k8s steps: - label: :pipeline: Upload pipeline command: bash .buildkite/k3_tests/common_scripts/upload-pipeline.sh .buildkite/k3_tests/test-name/pipeline.yml编写BK_WEB_SETUP.md记录该测试的 Buildkite UI 设置环境变量、触发器过滤条件、配置建议可以现有测试的BK_WEB_SETUP.md为模板chmod x你的run.sh并在 Buildkite UI 中创建流水线。可选数据集卷如果测试需要预下载的数据如 ShareGPT添加 datasets 卷volumeMounts: - { name: datasets, mountPath: /root/correctness } volumes: - { name: datasets, hostPath: { path: /data/datasets, type: DirectoryOrCreate } }可选Docker-in-Docker如果测试要在 Pod 内运行 Docker 容器securityContext: privileged: true volumeMounts: - { name: docker-sock, mountPath: /var/run/docker.sock } volumes: - { name: docker-sock, hostPath: { path: /var/run/docker.sock } }深入pipeline.yml 中的工程细节在仓库真实的pipeline.yml中unit/pipeline.yml 展示了远超模板的工程细节值得作为编写新测试的参考/dev/shm扩容K8s 默认将/dev/shm限制为 64 MiB会导致tests/v1/shm_allocator通过SharedMemory分配 5 GiB出现 SIGBUS。因此通过emptyDir: { medium: Memory, sizeLimit: 16Gi }挂载 16 GiB tmpfs 到/dev/shmGDS scratch 目录挂载宿主机本地 NVMe 上的 hostPath/scratch/data/gds-scratch。注释明确说明不能使用 subPath——K8s 的 subPath bind-mount 会破坏 cuFile 的文件系统类型检测overlayfs 上的/tmp会报CU_FILE_IO_NOT_SUPPORTED。run.sh为每次构建创建独立子目录并通过LMCACHE_TEST_TMPDIR暴露test_gds_backend、test_cache_engine及 xpu benchmark 等需要 GDS 的测试会消费该变量资源请求requests/limits 分开设置如 requests cpu 32/memory 96Gilimits cpu 64/memory 200Gi nvidia.com/gpu: 1并挂载hf-cache共享卷复用模型权重构件收集通过artifact_paths上传覆盖率 HTML/XML 与耗时报告durations/test.html、coverage-test.xml、coverage-test/**/*。结合 K3s Harness这些 Pod 背后的运行环境要真正理解 k3_tests 的运行前提需要阅读 .buildkite/k3_harness/README.md。该 harness 在任意 GPU 机器上搭建单节点 K3s NVIDIA GPU Operator 来运行 LMCache CI一次性安装setup-cluster.sh安装 K3s、Helm、GPU Operator、构建并导入 CI 基础镜像、创建宿主机卷目录可安全重跑→smoke-test.sh验证 Pod 内 GPU 可用→install-agent-stack.sh BUILDKITE_AGENT_TOKEN GITHUB_TOKEN创建 K8s secret 并安装 agent-stack-k8s共享卷所有 Pod 通过 hostPath 挂载/data/huggingface模型权重读多写少与/data/datasets测试数据集GPU 分配每个步骤通过nvidia.com/gpulimits 请求 GPU由 K8s 设备插件原子分配不再需要裸机时代的pick-free-gpu.shGPU 健康检查CI 任务启动时通过setup-env.sh中的check_gpu_health检查 GPU——若 Pod 分到的 GPU 空闲内存不足 80%通常由残留的宿主机进程导致任务立即失败并给出清晰报错而不是在冗长的安装后才遭遇晦涩的 CUDA OOM宿主级监控则可通过sudo bash .buildkite/k3_harness/setup-gpu-monitor.sh安装每 10 分钟运行的 cron 任务gpu-monitor.sh区分kubepodscgroup 内的 K8s 进程与残留宿主机进程日志位于/var/log/gpu-monitor.log环境隔离每个 Pod 拥有独立的临时文件系统任务结束即清除无共享 pip/uv 缓存、无跨 Pod 竞争卸载teardown.sh移除 K3s、GPU Operator 与 agent-stack但保留/data/*下的共享数据。结语LMCache 的k3_tests体系把文档改动自动通过、CI 修复强制触发、重型测试按需运行这三类需求用一套自包含目录 路径过滤脚本 Buildkite UI 配置的方式优雅地落地。新增测试时只需遵循run.shpipeline.ymlbuildkite-pipeline.ymlBK_WEB_SETUP.md四件套约定即可无缝接入这套 K8s 原生的按需 CI 流水线。【免费下载链接】LMCacheLMCache: Supercharge Your LLM with the Fastest KV Cache Layer项目地址: https://gitcode.com/GitHub_Trending/lm/LMCache创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考