【集群】云原生批调度实战:调度器测试与监控工具 kube-scheduling-perf

【集群】云原生批调度实战:调度器测试与监控工具 kube-scheduling-perf

Fre5h1nd Lv6

本系列《云原生批调度实战:Volcano 深度解析》计划分为以下几篇,点击查看其它内容。

  1. 云原生批调度实战:Volcano 深度解析(一)批处理背景需求与Volcano特点
  2. 云原生批调度实战:Volcano 深度解析(二)Volcano调度流程与调度状态
  3. 云原生批调度实战:Volcano 安装与初试
  4. 云原生批调度实战:调度器测试与监控工具 kube-scheduling-perf
  5. 云原生批调度实战:调度器测试监控结果

kube-scheduling-perf:Kubernetes多调度器性能测试框架全解析

项目简介

kube-scheduling-perf 项目为 Kubernetes 社区主流调度器(如 Kueue、Volcano、YuniKorn)提供了统一、自动化的性能测试与对比分析框架。通过自动化脚本和标准化测试流程,用户可在本地快速搭建测试集群,批量运行多种调度器的性能基准测试,并自动收集、汇总测试结果,极大提升了调度器性能评测的效率和可复现性。


目录结构与核心组件说明

clusters 目录

  • clusters/ 目录下包含了每个调度器(kueue、volcano、yunikorn)及 overview 的子目录。
  • 每个调度器子目录下都包含一个 Makefilekind.yaml,用于定义该调度器测试集群的启动、销毁、等待等操作。
  • overview/ 子目录用于搭建统一的监控与可视化环境(如 Prometheus + Grafana),并负责性能数据的采集与展示。

bin 目录

  • bin/ 目录用于存放自动编译生成的二进制文件,如 kind(用于创建K8s集群)、test-xxx(各调度器的测试用例可执行文件)。
  • 这些二进制文件由 Makefile 自动生成和调用,用户无需手动干预。

Makefile 语法与目标说明

.PHONY 说明

  • .PHONY 是 Makefile 的一个特殊声明,用于标记”伪目标”。
  • .PHONY 声明的目标不会与同名文件或目录冲突,每次执行 make 时都会被强制执行。
  • 例如:
    1
    2
    3
    .PHONY: up
    up:
    # ...命令...

目标与依赖格式

  • Makefile 的每个目标格式为:
    1
    2
    3
    目标名: 依赖1 依赖2 ...
    命令1
    命令2
  • 冒号后面可以跟依赖目标,表示在执行当前目标前会先执行依赖目标。
  • 命令必须以Tab缩进。

自动化测试流程详解

1. make命令的起点:default 目标

当你在项目根目录下执行 make 时,实际上会触发 Makefile 中的 default 目标。其内容如下:

1
2
3
4
5
6
7
8
9
10
11
.PHONY: default
default:
make serial-test \
RESULT_RECENT_DURATION_SECONDS=250 TEST_TIMEOUT_SECONDS=350 \
NODES_SIZE=1000 \
QUEUES_SIZE=1 JOBS_SIZE_PER_QUEUE=10000 PODS_SIZE_PER_JOB=1
# ...(省略多组不同参数的serial-test调用)
make serial-test \
RESULT_RECENT_DURATION_SECONDS=300 TEST_TIMEOUT_SECONDS=400 \
NODES_SIZE=1000 GANG=true \
QUEUES_SIZE=1 JOBS_SIZE_PER_QUEUE=1 PODS_SIZE_PER_JOB=10000
  • 这里依次调用了多次 serial-test,每次传入不同的集群规模、作业数量、Pod数量、是否GANG调度等参数。
  • 这样做的目的是批量测试不同场景下各调度器的性能,保证测试的全面性和对比性。

2. serial-test 目标的作用

1
2
3
4
5
6
7
8
9
10
11
12
.PHONY: serial-test
serial-test: bin/kind
$(foreach sched,$(SCHEDULERS), \
make prepare-$(sched); \
make start-$(sched); \
make end-$(sched); \
)
make \
prepare-overview \
start-overview \
save-result \
end-overview
  • serial-test 首先依赖 bin/kind,确保本地有 kind 工具(用于创建K8s集群)。
  • 然后对 SCHEDULERS(即 Kueue、Volcano、YuniKorn)中的每个调度器,依次执行 prepare-xxxstart-xxxend-xxx 三个目标。
  • 最后执行 overview 相关目标和结果保存。

3. serial-test 的每一步剖析

3.1 bin/kind

1
2
bin/kind:
$(GO_IN_DOCKER) go build -o ./bin/kind sigs.k8s.io/kind
  • 用 Docker 构建 kind 工具的二进制文件,确保后续可以用 kind 创建本地K8s集群。

3.2 prepare-xxx、start-xxx、end-xxx

这些目标通过 define test-scheduler 宏自动生成。以 kueue 为例:

  • prepare-kueue:启动集群、等待就绪、初始化测试。
  • start-kueue:重置审计日志,运行批量作业调度测试。
  • end-kueue:销毁测试集群。

其它调度器(如 volcano、yunikorn)流程类似。

3.3 overview 相关目标

prepare-overview

1
2
3
4
.PHONY: prepare-overview
prepare-overview:
make up-overview
make wait-overview
  • 启动 overview 监控集群,并等待其所有服务就绪。

start-overview

1
2
3
.PHONY: start-overview
start-overview:
make -C ./clusters/overview start-export
  • 在 overview 集群中启动数据导出与采集服务(如 patch、kustomize、kubectl create 等)。

save-result

1
2
3
4
5
6
.PHONY: save-result
save-result:
sleep $(RESULT_RECENT_DURATION_SECONDS)
RECENT_DURATION="$(RESULT_RECENT_DURATION_SECONDS)second" ./hack/save-result-images.sh
make down
# 归档测试环境变量、日志、输出到 results 目录
  • 等待一段时间,采集最新的监控数据,调用脚本保存结果,并归档到 results/ 目录。

end-overview

1
2
3
.PHONY: end-overview
end-overview:
make down-overview
  • 销毁 overview 监控集群,释放资源。

目标之间的调用关系图

graph TD
    A[make] --> B[default]
    B --> C1[serial-test(参数1)]
    B --> C2[serial-test(参数2)]
    B --> Cn[serial-test(参数n)]
    C1 --> D1[prepare-scheduler]
    C1 --> D2[start-scheduler]
    C1 --> D3[end-scheduler]
    C1 --> E[prepare-overview/start-overview/save-result/end-overview]
    D1 --> F1[up-scheduler]
    D1 --> F2[wait-scheduler]
    D1 --> F3[test-init-scheduler]
    D2 --> G1[reset-auditlog-scheduler]
    D2 --> G2[test-batch-job-scheduler]
    D3 --> H[down-scheduler]

注意事项

注意1:加速镜像拉取

在国内环境下需要使用CDN加速镜像拉取[2],在Makefile文件中替换GOPROXY ?= https://proxy.golang.org,directGOPROXY ?= https://mirrors.aliyun.com/goproxy/,https://proxy.golang.com.cn,https://goproxy.cn,https://goproxy.bj.bcebos.com/,https://gocenter.io,direct

注意2:内核版本适配

问题说明

如之前KIND安装博客所述,本人所使用服务器内核版本过低(3.10.0-1160.71.1.el7.x86_64),无法运行较高版本的Kubernetes和Kind,权衡之计是进行版本降级以解决兼容性问题。

  • 降级之后,仍然会收到报错:✗ Preparing nodes 📦 ; Command Output: WARNING: Your kernel does not support cgroup namespaces. Cgroup namespace setting discarded.
    • 具体分析后发现 Kind 自动添加 cgroupns 参数:从日志中可以看到,kind 在创建集群时自动添加了 –cgroupns=private 参数,这是较新版本 kind 的默认行为。
    • 解决方案:修改 kind 配置,./hack/kind-with-local-registry-fixed.sh中,在kind create ...之前增加以下代码:
      1
      2
      3
      4
      5
      6
      7
      ...
      # 新增以下代码:Disable cgroup namespaces for older kernels
      export KIND_EXPERIMENTAL_DISABLE_CGROUP_NAMESPACES=true

      # Create kind cluster with containerd registry configuration
      kind create cluster --config "${KIND_CONFIG:-}" --name "${KIND_CLUSTER_NAME:-kind}"
      ...

版本降级目标

  • Go版本: 1.24 → 1.23.10
  • Kind版本: v0.27.0 → v0.19.0
  • Kubernetes版本: v1.25.3 → v1.27.1

修改列表

Go

  • go.mod中:go 1.24go 1.23.10
  • Makefile中:GO_IMAGE ?= $(IMAGE_PREFIX)docker.io/library/golang:1.24GO_IMAGE ?= $(IMAGE_PREFIX)docker.io/library/golang:1.23.10

Kind

  • go.mod中:sigs.k8s.io/kind v0.27.0sigs.k8s.io/kind v0.19.0

节点Kubernetes:

  • go.mod中:修改k8s配置 v0.32.1v0.27.1
    1
    2
    3
    4
    5
    k8s.io/api v0.27.1
    k8s.io/apimachinery v0.27.1
    k8s.io/apiextensions-apiserver v0.27.1 // indirect
    k8s.io/client-go v0.27.1 // indirect
    k8s.io/component-base v0.27.1 // indirect
  • go.mod中:修改 sigs.k8s.io/e2e-framework v0.6.0sigs.k8s.io/e2e-framework v0.4.0,因为v0.6.0需要go版本大于1.23.0
  • ./cluster目录下的kueuevolcanoyunikornoverview四个目录中修改kind.yaml文件:docker.io/kindest/node:v1.32.2docker.io/kindest/node:v1.27.1

go.sum 版本管理文件[3]

  • 修改go.mod后,需要删除go.sum并执行go mod tidy以重新生成go.sum以匹配新的依赖版本。
  • 必要时开启CDN镜像加速export GOPROXY=https://mirrors.aliyun.com/goproxy/,direct
  • 如果一直出现奇怪的错误,例如go: github.com/wzshiming/kube-scheduling-perf/gopath/pkg/mod/github.com/pkg/errors@v0.9.1: import path "github.com/wzshiming/kube-scheduling-perf/gopath/pkg/mod/github.com/pkg/errors@v0.9.1" should not have @version,可能是因为已安装的旧版本未删除,应该删除旧的 gopath 并重新构建,以确保参数生效:
    1
    2
    sudo rm -rf gopath
    make

其它

  • 之后./hack/local-registry-with-load-images.sh会自动提前拉取镜像。
  • 注意:如果你是通过 Makefile 自动构建 bin/kind,请务必删除旧的 bin/kind 并重新构建,以确保新参数生效:
    1
    2
    sudo rm -f bin/kind
    make bin/kind
  • 注意:同理,如果修改版本前已经下载了相关go包,也应该删除旧的 gopath 并重新构建,以确保参数生效:
    1
    2
    sudo rm -rf gopath
    make

版本兼容性说明

Kind v0.19.0

  • 支持Kubernetes v1.27.x版本
  • 与Go 1.20.3兼容
  • 适合在较老的内核版本上运行

Kubernetes v1.27.1

  • 与Kind v0.19.0兼容
  • 支持较老的内核版本
  • 提供了稳定的API和功能

Go 1.20.3

  • 与Kind v0.19.0兼容
  • 支持Kubernetes v1.27.x客户端库
  • 在较老系统上有良好的兼容性

总结

  • make 触发 default,批量执行多组参数化的 serial-test
  • serial-test 依次对每个调度器完成:集群部署→初始化→批量作业测试→集群销毁→结果采集。
  • overview 相关目标 负责性能数据的统一采集与可视化。
  • clusters 目录 负责各调度器及监控集群的生命周期管理。
  • bin 目录 存放自动生成的工具和测试用例二进制文件。
  • .PHONY 声明伪目标,保证每次都能正确执行。

本项目通过 Makefile 的自动化编排、参数化测试、统一的日志与指标采集、可视化监控等手段,实现了 Kubernetes 多调度器性能对比的”一键化”与标准化。极大降低了测试门槛,提高了效率和可复现性,非常适合调度器开发者、性能分析师和社区贡献者使用与扩展。



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

🗺参考文献

[1] Github - kube-scheduling-perf

[2] Go 国内加速镜像

[3] 深入理解 Go Modules 的 go.mod 与 go.sum

  • 标题: 【集群】云原生批调度实战:调度器测试与监控工具 kube-scheduling-perf
  • 作者: Fre5h1nd
  • 创建于 : 2025-06-24 21:12:48
  • 更新于 : 2025-06-28 12:48:07
  • 链接: https://freshwlnd.github.io/2025/06/24/k8s/k8s-scheduler-performance-test/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论