news 2026/9/15 18:16:36

Kubernetes 节点性能测试与剖析完整指南:集群搭建、E2E 测试、pprof 剖析与 Benchmark(SIG Node)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Kubernetes 节点性能测试与剖析完整指南:集群搭建、E2E 测试、pprof 剖析与 Benchmark(SIG Node)

Kubernetes 节点性能测试与剖析完整指南:集群搭建、E2E 测试、pprof 剖析与 Benchmark(SIG Node)

【免费下载链接】communityKubernetes Community Documentation项目地址: https://gitcode.com/GitHub_Trending/com/community

导读

本文是 Kubernetes SIG Node 官方《Measuring Node Performance》文档的深度展开版,系统讲解在真实 Kubernetes 集群中测量 Node 组件(尤其是 Kubelet)性能时的常见陷阱、集群搭建要点,以及四类可用的测量手段:性能仪表盘、集群 E2E 性能测试、Node E2E 性能测试、Go pprof 剖析与 Benchmark。读完本文,你将能够搭建可复现的基准环境,正确运行kubelet_perf.gonode_perf_test.go两类性能测试,并用go tool pprof定位 Kubelet 的 CPU 与堆内存热点,最终产出一份可信、可比较的节点性能数据。

为什么节点性能测量容易出错:测量前的核心认知

测量节点性能(Measuring Node Performance)并不只是"跑一个压测脚本"那么简单。文档开篇即指出:有大量因素会显著影响节点性能数据,因此在搭建集群时必须格外谨慎,确保你测量的是你想要测量的东西。

其中最容易被忽视的一点是:性能会随 commit 变化剧烈波动。Kubernetes 是高速迭代的项目,每次代码提交都可能引入性能回归或优化。因此文档强烈建议:

  • 精确记录测量时使用的Kubernetes 版本或 commit
  • 记录容器运行时(container runtime)版本(如 containerd、CRI-O 等);
  • 记录集群的完整搭建配置(节点规格、内核、cgroup 驱动等)。

只有把这些"测量元数据"写清楚,后续才能在不同 commit 之间、不同版本之间做有意义的性能对比。从本仓库的定位来看,该文档隶属于 SIG Node 开发文档,是社区贡献者在开发 Kubelet 相关功能时必须掌握的测量方法论。

影响测量结果的关键维度

从文档与 Kubernetes 实现来看,至少有以下维度必须在测量前明确:

维度影响应对建议
Addon Pod 数量与分布默认 8 个 addon pod + 每节点 2 个(fluentd-elasticsearchkube-proxy)会消耗资源并周期性触发 Kubelet 工作记录每个节点上运行的 addon;必要时禁用(见下文)
Pod 数量0 个 pod 与 100 个 pod 的节点,Kubelet 开销完全不同在多个 Pod 数量档位下分别测量,并等待系统进入稳态
Pod 负载类型空闲 pod 与有真实负载的 pod 结果不同默认用 pause 镜像;特殊场景用轻量任务(如 ping)
Pod 功能特性是否配置探针、卷、容器数量等直接影响 Kubelet 工作按目标场景配置 liveness/readiness 探针、卷等
节点数量单节点易管理,多节点可并行采样更稳健按需选择并记录

集群搭建(Cluster Set-up):建立可信的基准环境

Addon Pod:测量中最大的隐藏变量

默认情况下,Kubernetes 会运行8 个 addon pod,并且在kube-system命名空间中,每个节点还会额外运行2 个 podfluentd-elasticsearchkube-proxy。这些 addon 会持续产生 CPU 与内存开销,更重要的是它们会周期性唤醒 Kubelet 执行工作,污染你的测量结果。

一个典型例子是Heapster:它会定期轮询每个节点收集 stats 数据。如果不禁用 Heapster,Kubelet 就必须持续响应这些统计请求——这部分"服务统计数据的性能成本"会被计入你的测量结果,导致你测到的不是"节点自身开销"而是"节点 + 监控栈"的开销。禁用 Heapster 可以隐藏这部分成本,得到更纯粹的 Kubelet 数据。

禁用 Addon 的方法

禁用 addon 非常简单:SSH 登录 Kubernetes master 节点,将对应 addon 从/etc/kubernetes/addons/目录移动到备份位置即可。addon 清单的完整来源可参考 cluster/addons 目录。

不过文档也提醒:禁用 addon 虽然能获得更一致的测量结果,但禁用本身也可能带来性能影响——例如缺少 kube-proxy 时网络路径行为不同,缺少 fluentd 时日志采集路径不同。因此必须结合你的测量目标决定哪些 addon 需要禁用,并在报告中明确记录。

用多少个 Pod、什么样的 Pod?

性能数据会随节点上的 Pod 数量剧烈变化:0 个 pod 和 100 个 pod 的节点,Kubelet 的负载完全不是一个量级。因此文档建议在多个 Pod 数量档位下分别测量。

在单节点集群中,通过扩展 ReplicationController 可以轻松控制 Pod 数量,例如:

$ kubectl scale replicationcontroller pause --replicas=100

关键细节:必须等待系统进入稳态(steady-state)再开始测量。Pod 创建、镜像拉取、调度绑定、PLEG 同步等过程都会带来瞬时峰值,只有稳态下的数据才具有可比性。

关于 Pod 类型,文档给出两条重要经验:

  1. 大多数情况下,pause pod 能产生最一致的测量结果——因为系统不会被 Pod 内应用的真实负载所影响。pause 镜像是一个极简的空容器,只负责保持 Pod 沙箱存在。
  2. 但存在例外:Kubernetes 在部分场景下专门对"空闲 Pod"做了优化(例如cAdvisor housekeeping,即 stats 收集逻辑,会针对无所事事的容器做特殊处理)。此时让 Pod 执行一个极轻量的任务(比如简单的网络 ping)反而更能反映真实成本。

最后,还应考虑目标 Pod 需要使用的特性:如果目的是测量带探针场景下的性能,就应该使用配置了liveness 或 readiness 探针的 Pod;同样,卷、容器数量、端口等特性都应按需配置。从 Kubelet 组件文档 可知,探针由ProbeManager驱动,稳态下每个探针都会周期性运行并触发结果更新,这一机制正是"带探针 Pod 开销更高"的源码级解释。

其他搭建建议

节点数量是一个权衡:

  • 单节点:更容易管理日志、Pod、环境变量,适合快速迭代测量方案;
  • 多节点:可以在并行收集更多数据,得到更稳健的采样结果(例如跨节点取均值、识别异常节点)。

建议在文档中记录最终采用的节点拓扑,以及每种配置下的样本量。

性能仪表盘(Performance Dashboard):持续追踪 Kubelet 资源占用

Kubernetes 1.22起,Kubelet 的资源使用情况被纳入Kubernetes 性能仪表盘(perf-dash)进行跟踪,地址为 perf-dash.k8s.io。该仪表盘由kubernetes/perf-tests仓库支撑,用于持续监控上游 Kubelet 的 CPU / 内存资源占用趋势,便于社区及早发现资源利用率的回归(相关讨论可参见本仓库 sig-node/archive/ci-subgroup-notes-2021.md 中关于 perf 测试的会议记录)。

对于贡献者而言,这提供了一个"零成本"的持续观测入口:在自行搭建集群做单次测量之前,可以先查看仪表盘上的历史趋势,判断某个 commit 的改动是否已经引起资源占用变化。

E2E 性能测试:整体资源占用采集(kubelet_perf.go)

测试定位与入口

对于收集节点组件整体资源使用情况,Kubernetes 提供了端到端测试:test/e2e/node/kubelet_perf.go。该测试的定位是"集群级 e2e 性能测试",与仅测试 Kubelet 的 node e2e 测试不同,它需要一套完整集群来运行。

运行前置条件

  • 确保有一个按 集群搭建 一节正确配置的e2e 集群在运行(文档使用kubetest --up拉起);
  • 集群必须按上文要求做好 addon、Pod 数量等配置。

运行命令

$ kubetest --test --test_args="--ginkgo.focus=resource\susage\stracking"

--ginkgo.focus使用正则匹配要运行的测试用例,这里的resource usage tracking即匹配 kubelet_perf 相关的性能测试规格。

如果需要自定义测试中的 Pod 数量或其他参数,请修改测试代码后重新编译测试二进制

$ make WHAT=test/e2e/e2e.test

这是文档特别强调的一步:e2e 测试二进制是预编译的,修改参数后不重新编译,改动不会生效。

已知限制

文档明确说明:由于这些测试非常耗时,目前并未在 CI 中运行(见 kubernetes/kubernetes issue #81490 的讨论)。这意味着:

  • 该测试目前主要靠社区成员手动、按需运行;
  • 运行结果不具备 CI 的持续覆盖,因此更需要测量者严格遵守可复现性要求(记录 commit、版本、配置)。

Node E2E 性能测试:在性能敏感负载下测 Kubelet

测试定位与入口

与集群级 e2e 性能测试不同,Node E2E 性能测试test/e2e_node/node_perf_test.go)的目标是在部署了"性能敏感工作负载"之后,测量节点(Kubelet)的性能表现。它属于 node e2e 测试体系,只需单节点基础设施(Kubelet + kube-apiserver + etcd),无需完整控制平面。

相关资源:

  • 测试源码:test/e2e_node/node_perf_test.go
  • 结果看板:TestGrid 的sig-node-kubelet页面下的node-performance-test通道

运行方法

先按照 Node e2e 测试指南 完成环境准备(本仓库中该指南详细覆盖了 etcd、containerd、CNI 插件的安装与配置),然后运行:

$ make test-e2e-node FOCUS="Node Performance Testing" SKIP="" PARALLELISM=1

参数说明:

  • FOCUS="Node Performance Testing":只运行名称匹配该正则的性能测试;
  • SKIP="":不跳过任何用例(node e2e 默认会跳过[Flaky][Slow][Serial]类用例,此处显式清空);
  • PARALLELISM=1:串行执行,保证性能测试之间互不干扰。

Node E2E 测试机制的源码视角

从本仓库 node e2e 代码文档 可以深入理解这套测试的底层机制:

  • node e2e 与常规 e2e 的本质区别在于只测节点组件 Kubelet,基础设施只需要 Kubelet、kube-apiserver 与 etcd;
  • 测试套件提供**本地运行器(local runner)远程运行器(remote runner,目前仅集成 GCP)**两个入口;
  • 本地运行时,make test-e2e-node会依次:请求 sudo 权限 → 构建 Kubernetes 源码 → 启动本地 etcd、kube-apiserver、kubelet → 运行测试 → 输出结果到 STDOUT → 停止各进程;
  • 启动顺序由test/e2e_node/services管理:startEtcdstartAPIServerstartNamespaceController,Kubelet 则在测试框架中以子进程方式在后台拉起;
  • ginkgo.SynchronizedBeforeSuite阶段还会执行系统校验(--system-validate-mode,基于k8s.io/system-validators校验 docker/OS 等环境)、按NodePrePullImageList预拉取测试镜像,然后启动服务并waitForNodeReady()

这解释了为什么性能测试能拿到"干净"的数据:整套基础设施由测试框架独立拉起,与宿主环境隔离,测量对象就是单节点上的 Kubelet 本身。

更多运行控制参数

e2e-node-tests.md 还提供了与性能测量强相关的控制参数:

  • 本地有 swap 的机器需传TEST_ARGS='--kubelet-flags="--fail-swap-on=false"',否则 Kubelet 默认拒绝启动;
  • 远程运行时可用REMOTE=true,并配合IMAGESHOSTSIMAGE_PROJECTINSTANCE_PREFIX等控制目标主机;
  • RUN_UNTIL_FAILURE=true可让测试持续运行直到失败,适合排查偶发性性能异常;
  • CLEANUP=false保留 Kubelet 进程与二进制,便于手工调试;
  • 查看全部可用参数:make test-e2e-node PRINT_HELP=y

Profiling:用 pprof 剖析 Kubelet 的 CPU 与内存

启用 pprof 端点

Kubelet 内置了Go pprof handlers(来自net/http/pprof标准库),可以通过 HTTP 端点直接拉取性能剖析数据。启用方式有两种,任选其一:

  • 以命令行 flag 方式启动 Kubelet:--enable-debugging-handlers=true
  • 在 Kubelet 配置文件中设置:EnableDebuggingHandlers=true

采集 CPU profile

启用后,通过kubectl proxy建立本地代理,即可用 curl 拉取 profile:

$ kubectl proxy & Starting to serve on 127.0.0.1:8001 $ curl -G "http://localhost:8001/api/v1/proxy/nodes/${NODE}:10250/debug/pprof/profile?seconds=${DURATION_SECONDS}" > $OUTPUT $ KUBELET_BIN=_output/dockerized/bin/linux/amd64/kubelet $ go tool pprof -web $KUBELET_BIN $OUTPUT

命令逐段说明:

  • kubectl proxy &:在本地127.0.0.1:8001建立到 API server 的代理;
  • curl 通过代理路径访问nodes/${NODE}:10250上的 Kubelet 调试端点,${NODE}替换为目标节点名,${DURATION_SECONDS}为采样时长(例如 30),${OUTPUT}为保存 profile 的文件路径;
  • KUBELET_BIN指向与运行中 Kubelet同版本的 kubelet 二进制(符号表需要与之匹配,pprof 才能正确解析调用栈);
  • go tool pprof -web在浏览器中打开调用关系图,直观展示热点函数。

提示:--enable-debugging-handlers=true会暴露调试端点,请仅在你有权访问的测试/开发集群上开启,并在测量完成后关闭。

采集堆内存(heap)profile

pprof 同样可以提供堆使用情况,来自/debug/pprof/heap端点:

$ curl -G "http://localhost:8001/api/v1/proxy/nodes/${NODE}:10250/debug/pprof/heap" > $OUTPUT_HEAP $ go tool pprof -web $KUBELET_BIN $OUTPUT_HEAP

堆 profile 可用于定位内存泄漏或高频分配热点。关于 Go profiling 的更多细节,可参考 Go 官方的《Profiling Go Programs》。

pprof 与 Kubelet 内部机制的对应

结合 Kubelet 组件文档,你可以把 profile 中的热点函数映射到实际工作机制上:

  • SyncLoop / SyncPod:Kubelet 的核心工作循环,每个 Pod 都有独立的 worker goroutine(pod_workers.go),Pod 数量越多,这些 goroutine 的开销越明显——这正是"Pod 数量影响性能"的源码依据;
  • PLEG(Pod Lifecycle Event Generator):默认每 ~2 秒轮询一次运行时以检测状态变化,是稳态下周期性 CPU 开销的重要来源之一;
  • cAdvisor housekeeping(stats 收集):周期性采集容器统计信息,即文档提到的"针对空闲 Pod 做优化"的机制所在;
  • 探针(Probes)ProbeManager为每个配置了探针的 Pod 运行独立 worker 周期性探测。

如果在 profile 中看到这些函数占据显著比例,就能反向指导测量设计——例如区分"稳态同步开销"与"Pod 创建峰值开销"。

Benchmarks:在写代码前先考虑 Go Benchmark

为什么先考虑 Benchmark?

文档给出了一条非常务实的工作流建议:在费尽周折搭建真实集群测量之前,先问自己——我需要的数据能否通过一个 Benchmark 测试获得?

Go 提供了极其简单的基准测试机制:只需在_test.go文件中编写形如BenchmarkXxx(b *testing.B)的函数即可。对于纯逻辑、数据结构、算法层面的性能问题(例如某种计算是否值得优化),Benchmark 远比"起一个真实集群"快速、便宜、可复现。只有那些依赖真实运行时、真实调度、真实网络栈的问题,才值得动用前文的集群测量手段。

编写 Benchmark 的标准模式

// In foo_test.go func BenchmarkFoo(b *testing.B) { b.StopTimer() setupFoo() // Perform any global setup b.StartTimer() for i := 0; i < b.N; i++ { foo() // Functionality to measure } }

要点:

  • b.StopTimer()/b.StartTimer():把全局初始化开销排除在计时之外——setupFoo()这类一次性准备工作不应计入被测函数的耗时;
  • 循环体for i := 0; i < b.N; i++b.N由 testing 框架自动调整(从 1 开始倍增,直到运行时间稳定在基准时长阈值附近),被测函数必须放在这个循环内执行;
  • 被测对象foo():只放需要测量的函数,不要混入无关工作。

运行 Benchmark

$ go test -bench=. -benchtime=${SECONDS}s foo_test.go

参数说明:

  • -bench=.:正则匹配所有 Benchmark 函数(.匹配全部;也可写-bench=BenchmarkFoo只跑特定函数);
  • -benchtime=${SECONDS}s:每个 Benchmark 至少运行指定的秒数(例如-benchtime=10s),比默认的固定迭代次数更能反映稳态性能;
  • foo_test.go:被测测试文件路径。

现状与后续方向(原文档 TODO 的延续)

原文档列出的 TODO 反映了该领域仍在演进:

  • 测量 docker 性能(taotao 认领);
  • 扩充集群搭建章节;
  • 测量磁盘使用情况(vishh 认领);
  • 测量内存使用情况(yujuhong 认领);
  • 增加监控 Kubelet 指标(例如使用 Prometheus)的章节。

结合本仓库 sig-node/archive/ci-subgroup-notes-2021.md 中的记录可以看到后续进展:社区曾讨论 node performance 测试文档的现状与重构(指向本文所依据的 node-performance-testing.md)、kubelet_perf.go为何未进入kubelet-serial测试、以及资源利用回归被纳入kubernetes/perf-tests仓库跟踪等议题。这说明节点性能测量是一个持续演化的领域,社区正在逐步把"手动测量"沉淀为"持续跟踪"。

总结:一份可信的节点性能测量清单

把全文要点浓缩为可直接执行的检查清单:

  1. 记录测量元数据:Kubernetes commit/版本、容器运行时版本、集群拓扑与配置;
  2. 控制变量:明确 addon pod(必要时按需禁用)、Pod 数量(多档位)、Pod 类型(默认 pause,特殊场景用轻量任务)、Pod 特性(探针、卷等)、节点数量;
  3. 等待稳态:任何测量开始前,确保系统已进入稳态;
  4. 选择测量工具
    • 持续趋势 → Kubernetes 性能仪表盘(1.22+);
    • 集群整体资源占用 →kubelet_perf.gokubetest --test --test_args="--ginkgo.focus=resource\susage\stracking",改参数后记得make WHAT=test/e2e/e2e.test);
    • 单节点 Kubelet 性能 →node_perf_test.gomake test-e2e-node FOCUS="Node Performance Testing" SKIP="" PARALLELISM=1);
    • 定位热点 → Kubelet pprof(--enable-debugging-handlers=true+go tool pprof -web);
    • 纯逻辑性能 → 先写 Go Benchmark(go test -bench=. -benchtime=...);
  5. 如实记录:测量结果必须与第 1 步的元数据绑定,才能跨版本、跨 commit 比较。

参考文档(仓库内)

  • 节点性能测量(原文档)
  • Node e2e 测试运行指南
  • Node e2e 测试代码机制说明
  • Kubelet 组件结构与同步循环解析
  • SIG Node 开发文档总览
  • SIG Node 职责与范围

【免费下载链接】communityKubernetes Community Documentation项目地址: https://gitcode.com/GitHub_Trending/com/community

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 18:15:14

用Python搭建用户画像系统:标签体系、RFM模型与实战落地指南

做用户画像这事&#xff0c;我见过太多团队第一反应就是“先搞个大数据平台”&#xff0c;结果 Hadoop 集群搭好了&#xff0c;数据仓库建了半年&#xff0c;标签却还没影。实际上&#xff0c;对于绝大多数业务体量在千万级用户以下的场景&#xff0c;一套 Python 就能搭出够用…

作者头像 李华
网站建设 2026/9/15 18:13:42

离线环境搭建Ambari集群:Spark版本切换与CarbonData集成实践

1. 为什么要在离线环境折腾Ambari这套组合事情起因很简单&#xff0c;我接手了一套处于内网隔离环境的测试集群&#xff0c;硬件资源都到位了&#xff0c;但机房除了管理网段之外&#xff0c;基本没有出公网的通道。也就是说&#xff0c;常规的yum install、pip install、从Git…

作者头像 李华
网站建设 2026/9/15 18:13:22

MATLAB实现蜂窝小区用户调度:RR、Max C/I与比例公平算法详解

简介&#xff1a;一套面向蜂窝系统小区用户通信调度研究的Matlab程序包&#xff0c;适合通信工程专业学生、无线网络研究人员及算法初学者&#xff0c;用来理解小区中多用户资源分配的核心逻辑。程序包含三种经典调度算法&#xff0c;比例调度算法依据用户信道质量按比例分配时…

作者头像 李华
网站建设 2026/9/15 18:12:10

移动端点餐H5 DEMO详解:触摸滑动、购物车与订单流程实现

简介&#xff1a;一款基于HTML5、JavaScript与CSS构建的移动端点餐系统DEMO&#xff0c;聚焦餐饮App的菜单浏览、菜品分类、购物车、订单评价等核心场景&#xff0c;适合Web前端初学者、移动端开发入门者&#xff0c;也适合需要课程设计或毕业设计原型的高校学生&#xff0c;代…

作者头像 李华