【集群】云原生批调度实战:Volcano 测试流程拆解

【集群】云原生批调度实战:Volcano 测试流程拆解

Fre5h1nd Lv6

本文隶属于《云原生批调度实战:Volcano 深度解析》系列中的 性能测试子系列。完整系列导航:

  1. 测试工具理论概览篇
  2. 实操注意事项篇
  3. 测试流程拆解
  4. _待发布_:指标采集篇
  5. _待发布_:自定义镜像篇

本文将以 Volcano 为代表,解析kube-scheduler-performance工具一次 调度器性能测试 从集群启动到结果归档的完整链路,搞清楚 每个步骤调用了哪些文件、各自作用是什么,为后续指标剖析与实验扩展打下基础。

阅读完本文,希望能够帮你快速实现:

  1. 复现最小规模的 Volcano 性能测试;
  2. 在源码中快速定位某一步骤的入口脚本 / YAML。

1️⃣ 执行链路总览

执行一次最小测试的命令非常简单:

1
2
make prepare-volcano start-volcano end-volcano \
NODES_SIZE=1 JOBS_SIZE_PER_QUEUE=1 PODS_SIZE_PER_JOB=1

这背后却触发了 ≥ 10 个 Makefile 目标与 30+ 个 YAML / Shell / Go 文件。整体时序如图所示(流程简化,仅保留关键节点):

graph TD;
    A[prepare-volcano] --> B[up-volcano];
    B --> C[kind 创建测试集群];
    C --> D[wait-volcano];
    D --> E[test-init-volcano];
    A -.->|完成后调用| F[start-volcano];
    F --> G[reset-auditlog-volcano];
    G --> H[test-batch-job-volcano];
    F -.-> |完成后调用| I[end-volcano];
    I --> J[down-volcano];

Tips: prepare-volcano → start-volcano → end-volcano 由根 Makefile 的 define test-scheduler 宏在编译期自动展开。

宏展开示例:Volcano

define test-scheduler 是一个带占位符 $(1) 的宏,最后通过 $(foreach sched,$(SCHEDULERS),$(eval $(call test-scheduler,$(sched))))kueue / volcano / yunikorn 进行循环替换。下面以 Volcano 为例简要对比“模板”与“实例”——

模板片段(截自 Makefile:110:140)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
define test-scheduler

.PHONY: prepare-$(1)
prepare-$(1):
make up-$(1)
make wait-$(1)
make test-init-$(1)

.PHONY: start-$(1)
start-$(1):
make reset-auditlog-$(1)
make test-batch-job-$(1)

.PHONY: end-$(1)
end-$(1):
make down-$(1)

.PHONY: up-$(1)
up-$(1):
make -C ./clusters/$(1) up

.PHONY: down-$(1)
down-$(1):
-make -C ./clusters/$(1) down

.PHONY: wait-$(1)
wait-$(1):
make -C ./clusters/$(1) wait

bin/test-$(1): $(shell find ./test/utils ./test/$(1) -type f)
$(GO_IN_DOCKER) go test -c -o ./bin/test-$(1) ./test/$(1)

展开后(自动生成)的部分规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.PHONY: prepare-volcano
prepare-volcano:
make up-volcano
make wait-volcano
make test-init-volcano

.PHONY: start-volcano
start-volcano:
make reset-auditlog-volcano
make test-batch-job-volcano

.PHONY: end-volcano
end-volcano:
make down-volcano

...

借助这种“写一次、生成三份”的做法,大幅减少了针对不同调度器写重复 Make 目标的工作量。


2️⃣ 关键 Makefile 目标拆解

目标所在文件主要命令职责说明
prepare-volcanoMakefilemake up-volcano make wait-volcano make test-init-volcano集群启动 + 基础就绪检查 + 预热测试二进制
up-volcanoclusters/volcano/Makefilekind create cluster & 部署 Volcano创建 Kind 集群并应用 Volcano 相关 Kustomize 资源
wait-volcano同上kubectl wait --for=condition=Ready等待所有 Pod Ready,含 controller / scheduler
test-init-volcanoMakefile运行 bin/test-volcano -run ^TestInit生成初始队列、扩容节点
start-volcanoMakefilemake reset-auditlog-volcano make test-batch-job-volcano清空上一轮 audit 日志 & 正式发压
reset-auditlog-volcanoclusters/volcano/Makefilekubectl delete audit-log ConfigMap置空历史日志,保证数据窗口准确
test-batch-job-volcanoMakefilebin/test-volcano -run ^TestBatchJob按参数批量提交 Job / Pod 并记录时间线
end-volcanoMakefilemake down-volcano销毁 Kind 集群,释放资源

3️⃣ clusters/volcano 目录速览

  • kind.yaml:集群版本、节点数量、containerd 本地镜像仓库挂载;
  • deployment.yaml:Volcano Controller 与 Scheduler 部署模板;
  • kustomization.yaml:声明所有资源并支持 image 覆盖;
  • service.yaml:暴露 Volcano webhook / metrics(如需)。

这些文件通过 kustomize build 管道被 up-volcano 目标应用到 Kind 集群中。


4️⃣ test/volcano 测试代码剖析

核心 Go 测试位于 test/volcano/batch_job_test.go,流程摘要:

  1. provider.AddNodes():根据 NODES_SIZE 参数批量创建假 Node;
  2. provider.CreateQueues():生成指定数量的 Queue CR;
  3. provider.SubmitBatchJobs():循环创建 Job;
  4. WaitForCondition():轮询 Job 或 Pod 状态,统计完成时间。

所有 Kubernetes API 操作均通过 client-go 的 fake client 与真实 API Server 通信,审计日志会在 kube-apiserver 侧产出。

假节点(Node)是怎么批量注入的?

provider.AddNodes() 内部调用了一个 NodeBuilder,利用 K8s API 直接向集群注册 Ready 状态的“虚拟节点”,关键代码如下:

1
2
3
```
在具体 Provider 中(以 Volcano 为例),只需循环调用 `WithName()` 后写入集群即可:
```33:49:test/volcano/provider_test.go

这样就能瞬间创建上千个可调度节点,避免真实机器资源瓶颈。


5️⃣ hack 脚本的幕后协同

脚本触发时机作用
hack/kind-with-local-registry.shup-volcano启动本地 5001 registry + 注入 containerd 配置(**在每个 Kind 节点的 /etc/containerd/certs.d/ 写入 hosts.toml**,指向本地仓库),实现“边拉边推、本地秒级拉取”
hack/local-registry-with-load-images.shup-volcano 期间将远端镜像拉取后重新打 tag 推到本地 registry,Kind 节点下载极快
hack/replace-qps.sh可选修改 APIServer QPS,一键替换所有带 # <--QPS 注释的 YAML 中的数值,从而把 --kube-api-qps 或 webhook QPS 提到 1000+,缓解 API Server 限流
hack/save-result-images.sh测试结束后调用 Grafana API 截图面板,写入 output/ 归档

containerd 配置注入示例

hack/kind-with-local-registry.sh 关键片段:

1
2
3
4
```
脚本会在每个节点的 `registry_dir="/etc/containerd/certs.d/kind-registry:5000"` 下生成 `hosts.toml`:
```toml
[host."http://kind-registry:5000"]

这样 containerd 在拉取镜像时会先查找本地 registry,实现“离线加速&可复用”。

修改 APIServer QPS 示例

有时压测因 API Server QPS 受限(默认 50)而瓶颈,可以:

1
2
# 把所有 YAML 中的占位符替换为 1000
hack/replace-qps.sh 1000

脚本原理:遍历项目内所有 *.yaml,将 # <--QPS 注释前的数字一次性替换:

1

随后重新 make prepare-volcano ...,即可在新版集群里验证高 QPS 配置对吞吐量的影响。


6️⃣ 结语

至此,我们已经串起了 Volcano 性能测试的最小可运行链路,并定位了关键 Makefile 目标与 YAML / Go 源码。下一篇将深入 指标采集与可视化,详解 audit-exporter 如何把 CREATED / SCHEDULED / RUNNING 三条曲线绘制到同一张 Grafana 面板。

📌 实践练习:如果感兴趣,可以尝试把 JOBS_SIZE_PER_QUEUE 改为 2,再次运行测试,观察 logs/results/ 目录下是否出现新的时间戳文件夹,并查看面板截图差异。



  • 希望这篇博客对你有帮助!如果你有任何问题或需要进一步的帮助,请随时提问。
  • 如果你喜欢这篇文章,欢迎动动小手给我一个follow或star。

🗺参考文献

[1] Github - kube-scheduling-perf

[2] A Comparative Analysis of Kueue, Volcano, and YuniKorn - Wei Huang, Apple & Shiming Zhang, DaoCloud

  • 标题: 【集群】云原生批调度实战:Volcano 测试流程拆解
  • 作者: Fre5h1nd
  • 创建于 : 2025-07-27 16:21:35
  • 更新于 : 2025-08-01 16:24:27
  • 链接: https://freshwlnd.github.io/2025/07/27/k8s/k8s-scheduler-performance-volcano-process/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论