Volcano 基准测试脚本体系全解:从集群搭建、拓扑模拟到微秒级调度延迟采集
2026/9/17 11:48:16 网站建设 项目流程

Volcano 基准测试脚本体系全解:从集群搭建、拓扑模拟到微秒级调度延迟采集

【免费下载链接】volcanoA Cloud Native Batch System (Project under CNCF)项目地址: https://gitcode.com/GitHub_Trending/vol/volcano

导读

本文聚焦 Volcano 仓库 benchmark/scripts 下的 Shell 脚本体系,它构成了 Volcano 性能基准测试框架的可执行主干:通过Makefile统一编排,覆盖 Kind/KWOK 模拟集群的创建、Volcano 与监控组件安装、Gang/Pod 两类调度场景的压测执行、审计日志导出(audit-exporter)与 Prometheus 指标报表采集,以及一键清理。读完本文,你将能完整复现一套针对 Volcano 调度器的基准测试环境,理解每个脚本的职责、输入输出与调用链,并掌握 microsecond 级调度延迟与 Pod 时间戳回退两种指标采集方案。

一、脚本全景:11 个脚本的职责与调用关系

benchmark/scripts/README.md 以一张表格概括了整个脚本体系。下表逐行说明各脚本的职责及对应的 Make 目标(调用方):

脚本职责调用方
common.sh共享环境变量、日志函数、require_cmdwait_for_deployment被所有脚本 source
create-cluster.sh创建 Kind 集群,启用审计日志与 NodePort 映射make create-cluster
create-kwok-nodes.sh安装 KWOK 控制器并创建模拟节点make create-nodes
build-images.sh构建 audit-exporter 镜像并加载进 Kind 集群make build-images
install-volcano.sh通过 Helm 安装 Volcano(本地源码或发布版 Chart)make install-volcano
install-monitoring.sh部署 Prometheus、Grafana、kube-state-metrics、audit-exportermake install-monitoring
run-tests.sh应用调度器配置、执行 Go 测试、自动采集报表make test-configmake test-gang-env
collect-report.sh从 Prometheus 查询 audit-exporter 指标,写 JSON 报表run-tests.sh调用;make report
export-grafana-charts.sh通过 Render API 将 Grafana 面板导出为 PNGmake export-charts
cleanup.sh拆除 VCJob、监控、Volcano、KWOK;可选删除集群make cleanupmake cleanup-all
create-hypernodes.sh为拓扑感知调度创建 HyperNode CR(在 Volcano 安装后执行)make create-hypernodes
cleanup-kwok-nodes.sh删除 KWOK 节点与 HyperNode(cleanup.sh的子任务)cleanup.sh

这些脚本并非各自孤立,而是按照 benchmark/Makefile 中的目标组织成一条完整流水线:make setup依次执行集群创建→镜像构建→KWOK 节点→Volcano 安装→监控安装(各步骤均可通过USE_EXISTING_CLUSTERSKIP_KWOKSKIP_INSTALL_VOLCANOSKIP_INSTALL_MONITORING跳过),随后make test-gang-env/make test-pod-env/make test-config触发压测。

二、shared 基础:common.sh 的统一设施

common.sh是整个脚本体系的“公共底座”,被所有脚本通过source "$(dirname "$0")/common.sh"引入。它提供了四类设施:

1. 环境变量默认值:所有可调参数都在这里统一收敛,例如CLUSTER_NAME=volcano-benchmarkKWOK_NODE_COUNT=100CPU_PER_NODE=32MEMORY_PER_NODE=256GiKWOK_VERSION=v0.7.0,以及现有集群模式开关USE_EXISTING_CLUSTERSKIP_INSTALL_VOLCANOSKIP_INSTALL_MONITORINGSKIP_KWOK等(见 common.sh)。

2. 路径解析:脚本通过BASH_SOURCE推算出BENCHMARK_DIR(benchmark 根目录)与VOLCANO_ROOT(仓库根目录),从而保证脚本无论从哪个目录被调用都能正确定位配置、清单与 Helm Chart。

3. 日志函数log_info/log_warn/log_error输出带时间戳的[INFO][WARN][ERROR]前缀,其中 warn 与 error 走 stderr。

4. 工具函数require_cmd校验必需命令是否存在(缺失即退出);wait_for_deployment通过kubectl rollout status等待 Deployment 就绪;wait_for_pods_ready通过kubectl wait --for=condition=Ready等待 Pod 就绪(见 common.sh)。

三、环境搭建脚本:集群、节点、镜像与组件安装

3.1 create-cluster.sh:Kind 集群与审计日志

create-cluster.sh负责创建 Kind 集群,关键点在于:

  • 渲染 Kind 配置:用sed将 config/kind-config.yaml 中的__VOLCANO_ROOT__占位符替换为仓库绝对路径(Kind 要求 hostPath 为绝对路径),生成config/.kind-config.rendered.yaml
  • 审计日志目录预创建:预先创建benchmark/logs/,确保 apiserver 审计日志挂载首次启动即成功;
  • 集群生命周期管理:若同名集群已存在则先删除再创建;创建完成后将 kubeconfig 导出到benchmark/kubeconfig并等待全部节点 Ready(见 create-cluster.sh)。

3.2 create-kwok-nodes.sh:KWOK 模拟节点与拓扑域

KWOK(Kubernetes WithOut Kubelet)用于低成本模拟大规模节点。create-kwok-nodes.sh的执行逻辑为:

  1. 检测kwok-controllerDeployment 是否已存在,不存在则按KWOK_VERSION下载并应用 KWOK 的 CRD、控制器与stage-fast.yaml
  2. Flat 模式(默认):创建KWOK_NODE_COUNT个节点,每个节点带有type: kwok标签、kwok.x-k8s.io/node=fake注解、NoSchedule污点,以及通过CPU_PER_NODE/MEMORY_PER_NODE指定的容量(见 create-kwok-nodes.sh);
  3. Topology 模式ENABLE_TOPOLOGY=true):按 spine→rack 两级拓扑域均匀分布节点,并打上topology-racktopology-spine标签;节点数与域配置的对应关系为nodes_per_rack = KWOK_NODE_COUNT / TOPOLOGY_RACKSracks_per_spine = TOPOLOGY_RACKS / TOPOLOGY_SPINES(见 create-kwok-nodes.sh);
  4. 自定义标签KWOK_NODE_LABELS支持逗号分隔的key=value,会附加到所有节点上,用于配合 hypernode-controller 的自动发现模式(例如KWOK_NODE_LABELS="topology-rack=rack-0,topology-spine=spine-0,gpu=A100")。

脚本内置幂等保护:若现有type=kwok节点数已满足需求则直接跳过创建。

3.3 build-images.sh:镜像构建策略

build-images.sh按两种模式构建镜像:

  • 默认(发布版):仅构建 audit-exporter 镜像(该镜像未发布到 DockerHub),随后kind load docker-image载入 Kind 集群;
  • BUILD_VOLCANO=true(本地源码):在仓库根目录执行make images构建vc-schedulervc-agent-schedulervc-controller-managervc-webhook-manager等全部 Volcano 组件镜像,并逐一加载进 Kind(见 build-images.sh)。

Dockerfile 位于 manifests/audit-exporter/Dockerfile,构建上下文为仓库根目录。

3.4 install-volcano.sh:双模式安装与调度器调参

install-volcano.sh支持两种安装模式:

  • --release <version>:从官方 Helm 仓库安装指定版本(如v1.14.2),并启用agent_scheduler_enable=truescheduler_config_file=volcano-scheduler-configmap
  • --local:直接使用仓库内 installer/helm/chart/volcano 本地 Chart 安装,适合验证未发布的源码改动。

安装前脚本会先清理历史残留:删除所有volcano.sh后缀的 CRD、卸载已存在的 Helm release(见 install-volcano.sh)。此外还支持通过--scheduler-config在安装后应用自定义调度器配置并滚动重启volcano-scheduler

值得关注的是安装时会注入custom.scheduler_kube_api_qps/burstcustom.controller_kube_api_qps/burst四个 Helm 参数,默认值分别为 5000/10000,用于在压测前放大 Volcano scheduler 与 controller-manager 访问 Kubernetes API 的 QPS/Burst 上限,避免客户端限流成为基准测试瓶颈(见 install-volcano.sh)。

3.5 install-monitoring.sh:监控栈与自定义仪表盘

install-monitoring.sh依次完成:

  1. 应用 installer/volcano-monitoring.yaml 部署 Prometheus、kube-state-metrics 与 Grafana;
  2. 将 manifests/monitoring/grafana-dashboard.json 作为 ConfigMap 挂载到 Grafana 的/var/lib/grafana/dashboards/benchmark(通过 strategic patch 实现);
  3. 应用 manifests/audit-exporter/daemonset.yaml 部署 audit-exporter DaemonSet——Prometheus 通过installer/volcano-monitoring.yaml中已有的kubernetes-service-endpoints抓取任务自动发现它,无需额外改动 Prometheus 配置;
  4. 使用wait_for_deployment依次等待各组件就绪(见 install-monitoring.sh)。

AUDIT_EXPORTER_IMAGE被自定义,脚本会用sed替换 DaemonSet 清单中的默认镜像名,支持私有仓库场景。

四、压测执行:run-tests.sh 与测试用例源码

4.1 run-tests.sh 的工作流

run-tests.sh是压测的统一入口,用法为run-tests.sh <scenario> --config=<profile.yaml>,核心流程如下:

  1. 配置解析--config=指定 YAML 配置;--template=则用envsubst将模板中的$JOBS$REPLICAS$MIN_AVAILABLE$PODS$SCHEDULER_NAME等变量渲染为临时配置(见 run-tests.sh);
  2. Prometheus 探测:记录测试开始前的 Prometheus 时间戳(time()查询),若 Prometheus 不可达则跳过 audit-exporter 报表(PROM_AVAILABLE=false);
  3. 执行 Go 测试cd到仓库根目录执行go test -count=1 -v -timeout 1800s "./benchmark/testcases/<scenario>/..." -run TestFromConfig,输出以tee写入results/test-<scenario>-<时间戳>.log
  4. 自动采集报表:测试结束后等待 10 秒供 Prometheus 抓取,再以--before/--after两个时间戳调用collect-report.sh(见 run-tests.sh)。

4.2 Gang 场景的测试源码剖析

Gang 场景测试代码位于 benchmark/testcases/gang/gang_test.go,其结构可作为“新增场景”的参照模板:

  • VCJobConfig/TaskConfig结构体完整定义了任务模板可配置项:命名空间、MinAvailable、队列名、Job/Task 两级网络拓扑、分区策略、节点选择器等(见 gang_test.go);
  • BuildVCJob基于cases/vcjob-template.yamltext/template渲染出batch.volcano.sh/v1alpha1的 Job 对象,并为空字段应用默认值(镜像busybox:1.36、命令/bin/sh -c sleep 30,见 constant.go);
  • CreateGangJobs通过workqueue.ParallelizeUntilBENCHMARK_CREATE_CONCURRENCY(默认 16)并发提交指定数量的 VCJob;
  • RunGangTest依次等待“全部 Pod 创建完成”(5 分钟)与“全部 Pod 被调度”(10 分钟),两个等待分别对应创建吞吐与调度吞吐的验证。

4.3 YAML 配置文件示例

以 testcases/gang/cases/comprehensive.yaml 为例,配置文件同时演示了 Job 级与 Task 级的完整参数,包括:

jobs: 5 jobTemplate: name: gang-comprehensive minAvailable: 10 queue: default # job 级网络拓扑配置 enableNetworkTopology: false networkTopologyMode: hard tasks: - name: master replicas: 1 image: busybox:1.36 cpu: 100m memory: 100Mi enableNodeSelector: false - name: worker replicas: 10 image: busybox:1.36 command: ["/bin/sh", "-c", "sleep 30"] cpu: 50m memory: 50Mi # task 级分区策略(拓扑分组) enablePartitionPolicy: false partitionTotalPartitions: 2 partitionSize: 5 # task 级网络拓扑配置 enablePartitionNetworkTopology: false partitionNetworkMode: soft enableNodeSelector: false

五、指标采集:audit-exporter 报表与 Pod 时间戳回退

5.1 collect-report.sh:微秒级延迟报表

collect-report.sh从 Prometheus 查询 audit-exporter 暴露的指标并生成 JSON 报表,其实现有三个亮点:

  1. 直方图分位数计算:为避免短时间窗下increase()外推误差,脚本在--before/--after两个时间点分别查询sum by (le) (pod_scheduling_latency_seconds_bucket{namespace="default"}),用 jq 做桶差分后线性插值出 P50/P90/P99(见 collect-report.sh);未提供时间戳时回退到histogram_quantile+increase(...[10m])
  2. 调度吞吐计算:直接解析本机 apiserver 审计日志文件,筛选ResponseComplete+create pods/binding+ HTTP 2xx 事件,按stageTimestamp落在时间窗内的数量除以时间窗长度得到“pods/sec”(见 collect-report.sh);
  3. 报表输出:生成results/report-<时间戳>.json,包含时间窗、P50/P90/P99(秒)、调度总数、吞吐量、Grafana 与 Prometheus 地址,并同时在终端以毫秒打印结果(见 collect-report.sh)。

5.2 两种延迟采集方案的取舍

框架提供两条延迟采集路径:

方案精度前置条件适用场景
audit-exporter(推荐)微秒级(metav1.MicroTimeapiserver 开启审计日志 + 镜像已构建精确延迟分析,Pod 可即时清理
Pod 时间戳回退秒级(metav1.TimeDRY_RUN=true保留 Pod调试、未开启审计日志的环境

audit-exporter 之所以被推荐,原因有二:审计事件携带MicroTime精度(而 Pod 对象上的metav1.Time只有秒级);同时pods/binding是通用绑定入口,与具体调度器无关——无论 Pod 由 Volcano、agent-scheduler 还是其他调度器绑定,都能被统计。而 Pod 时间戳方案的局限在于亚秒级延迟会显示为 0ms,且必须搭配DRY_RUN=true使 Pod 在采集时仍然存活。

5.3 启用 apiserver 审计日志(微秒级方案前置)

若在现有集群上使用 audit-exporter,需为 kube-apiserver 增加以下启动参数:

--audit-policy-file=/etc/kubernetes/policies/audit-policy.yaml --audit-log-path=/var/log/kubernetes/kube-apiserver-audit.log --audit-log-maxsize=10240 --audit-log-maxage=7 --audit-log-maxbackup=3

审计策略文件位于 third_party/kube-apiserver-audit-exporter/audit-policy.yaml。对于 kubeadm 集群,编辑控制平面节点上的/etc/kubernetes/manifests/kube-apiserver.yaml,在commandvolumeMountsvolumes中分别加入审计策略文件与日志目录的挂载,kubelet 会自动重启 apiserver 静态 Pod 完成生效。

5.4 可观测指标一览

框架的指标来自三个来源:

  1. audit-exporter(调度器无关的微秒级延迟),核心指标包括:
    • pod_scheduling_latency_seconds(Histogram):Pod 创建到pods/binding创建的时间,user标签标识调度器;
    • batchjob_completion_latency_seconds(Histogram):Job 创建到完成的时间(涵盖batch.Jobbatch.volcano.sh/Job);
    • api_requests_totalpod_deleted_totalpod_completed_total(Counter)等;
  2. Volcano 内部指标volcano_session_*volcano_plugin_*volcano_action_*等,例如volcano_e2e_job_scheduling_latency_milliseconds(Job 从创建到最后一个 task 被 assume 的时长)、volcano_worker_scheduling_cycle_duration_milliseconds(agent worker 单次调度周期)等;
  3. kube-state-metrics:Pod/Job 生命周期计数。

服务通过 NodePort 暴露:Prometheus:30003,Grafana:30004(admin/admin),仪表盘地址为/d/volcano-benchmark

六、拓扑感知调度:HyperNode 的创建与三种接线方式

6.1 create-hypernodes.sh 的实现

create-hypernodes.sh在 Volcano 安装完成后执行(前置校验hypernodes.topology.volcano.shCRD 是否存在),按TOPOLOGY_RACKS×TOPOLOGY_SPINES生成两级 HyperNode(见 create-hypernodes.sh):

  • Tier-1(rack):每个 rack 一个 HyperNode,通过labelMatch选择带type: kwoktopology-rack=rack-<i>标签的节点;
  • Tier-2(spine):每个 spine 一个 HyperNode,通过exactMatch引用其下属 rack HyperNode。

关键约束:执行时传入的TOPOLOGY_RACKS/TOPOLOGY_SPINES必须与create-kwok-nodes.sh阶段保持一致,否则 HyperNode 的 labelSelector 无法匹配对应节点。

6.2 三种拓扑接线方式

  1. KWOK 模拟拓扑(默认):ENABLE_TOPOLOGY=true建节点 → 安装 Volcano →make create-hypernodes建 CRD;
  2. 真实节点自定义拓扑:给真实节点打topology-rack标签后创建对应 HyperNode。由于脚本的 rack labelSelector 固定包含type: kwok,真实节点需自行补充该标签,或直接手写 HyperNode 清单(如 benchmark/README.md 中topology.volcano.sh/v1alpha1HyperNode示例);
  3. hypernode-controller 自动发现:仅需给节点打topology-racktopology-spine标签,控制器会根据 Volcano ConfigMap 中的 label discoverer 配置自动创建 HyperNode——这要求在使用 create-kwok-nodes.sh 时通过KWOK_NODE_LABELS注入拓扑标签。调度器使用虚拟ClusterHyperNode作为全局根节点,因此只需 rack(tier 1)与 spine(tier 2)两级,无需显式根节点。

七、清理:cleanup.sh 的幂等拆除

cleanup.sh提供两级清理粒度(见 cleanup.sh):

  • make cleanup:仅清理测试资源(按标签volcano.sh/benchmark=true删除 VCJob 与裸 Pod、删除 PodGroup)、监控栈、KWOK 节点(调用cleanup-kwok-nodes.sh --all)、Volcano(Helm uninstall + 删除 CRD)及本地产物(binresultslogs、渲染配置);
  • make cleanup-all:在 cleanup 基础上执行kind delete cluster删除整个 Kind 集群(USE_EXISTING_CLUSTER=true时明确跳过,绝不删除外部集群)。

每个子项都遵循SKIP_*开关:SKIP_INSTALL_MONITORING=true时跳过监控清理、SKIP_KWOK=true时跳过 KWOK 清理、SKIP_INSTALL_VOLCANO=true时跳过 Volcano 清理,保证与搭建阶段的选择严格对称。

八、参数速查与两种运行模式

8.1 全局变量速查

变量默认值说明
CLUSTER_NAMEvolcano-benchmarkKind 集群名
USE_EXISTING_CLUSTERfalse跳过 Kind 建集群与镜像构建,使用现有 kubeconfig
SKIP_INSTALL_VOLCANOfalse跳过 Volcano 安装(使用集群中已装版本)
SKIP_INSTALL_MONITORINGfalse跳过监控栈安装
SKIP_KWOKfalse跳过 KWOK 安装与节点创建;运行测试时也需传入以剔除模板中的 KWOKnodeSelector/tolerations
AUDIT_EXPORTER_IMAGEvolcanosh/kube-apiserver-audit-exporter:devaudit-exporter 镜像(私有仓库需覆盖)
KUBECONFIG~/.kube/configkubeconfig 路径
KWOK_NODE_COUNT100KWOK 节点数
CPU_PER_NODE32每节点 CPU
MEMORY_PER_NODE256Gi每节点内存
KWOK_VERSIONv0.7.0KWOK 控制器版本
VOLCANO_VERSIONHelm 仓库安装的发布版标签(如v1.14.2
VOLCANO_*_KUBE_API_QPS/BURST5000/10000Volcano scheduler/controller 的 API 客户端限流
PROM_URLhttp://localhost:30003Prometheus 地址
DRY_RUNfalse跳过测试后清理(调试或 Pod 时间戳采集)

Gang 场景参数:JOBS(默认 10)、REPLICAS(默认 100)、MIN_AVAILABLE(默认 100);Pod 场景参数:PODS(默认 500)、SCHEDULER_NAME(默认agent-scheduler)。完整参数(网络拓扑、分区策略、节点选择器等)见 testcases/gang/cases/comprehensive.yaml 与 testcases/pod/cases。

8.2 典型使用流程

Kind 本地集群快速验证:

cd benchmark make setup VOLCANO_VERSION=v1.14.2 # 建集群 + 装 Volcano + 装监控 make test-gang-env JOBS=10 REPLICAS=100 MIN_AVAILABLE=100 make cleanup-all

现有集群(裸金属/云托管/自建多节点):

make setup USE_EXISTING_CLUSTER=true SKIP_INSTALL_VOLCANO=true SKIP_INSTALL_MONITORING=true kubectl port-forward svc/prometheus-service -n volcano-monitoring 30003:8080 & make test-gang-env SKIP_KWOK=true JOBS=10 REPLICAS=100 MIN_AVAILABLE=100

无审计日志时的延迟回退采集:

DRY_RUN=true make test-gang-env JOBS=10 REPLICAS=100 MIN_AVAILABLE=100 make collect-pod-latency # 结果写入 results/pod-latency-<时间戳>.json make clean-vcjobs # 清理残留

8.3 新增测试场景的步骤

框架支持通过以下三步扩展新场景(见 benchmark/README.md 的 "Adding New Scenarios"):

  1. 创建testcases/<scenario>/config/,放入scheduler-config.yamlqueue.yaml
  2. 创建testcases/<scenario>/*_test.go实现测试逻辑(可参照 gang_test.go 的TestFromConfig约定);
  3. 运行make setup && make test-config SCENARIO=<scenario> CONFIG=<profile>.yaml

结语

common.sh的公共设施,到create-cluster.sh/create-kwok-nodes.sh/install-volcano.sh/install-monitoring.sh的环境搭建四件套,再到run-tests.shcollect-report.sh组成的“压测+报表”闭环,Volcano 的 benchmark 脚本体系用一组职责单一、可组合、可跳过的脚本,把“在任意规模的模拟集群上量化调度器性能”这件事做成了标准流水线。理解这套脚本,不仅能直接复现本文所述的两类调度场景压测,也能为你自己的调度器性能验证与指标埋点方案提供现成参考。

【免费下载链接】volcanoA Cloud Native Batch System (Project under CNCF)项目地址: https://gitcode.com/GitHub_Trending/vol/volcano

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询