千家信息网

容器化 RDS:借助火焰图定位Kubernetes性能问题

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,容器化RDS系列文章:容器化RDS:计算存储分离架构下的"Split-Brain"容器化RDS:计算存储分离还是本地存储?容器化RDS:你需要了解数据是如何被写"坏"的容器化RDS:借助 CSI 扩展
千家信息网最后更新 2026年10月31日容器化 RDS:借助火焰图定位Kubernetes性能问题

容器化RDS系列文章:

  • 容器化RDS:计算存储分离架构下的"Split-Brain"

  • 容器化RDS:计算存储分离还是本地存储?

  • 容器化RDS:你需要了解数据是如何被写"坏"的

  • 容器化RDS:借助 CSI 扩展 Kubernetes 存储能力


借助 CSI(Container Storage Interface),加上对 Kubenetes 核心代码的少量修改,可以 out-tree 的方式高效且低耦合的方式扩展 Kubenetes 存储管理子模块。

如《 容器化 RDS:借助 CSI 扩展 Kubernetes 存储能力 》介绍,以 out-tree 方式添加 PVC 扩容(Resize)特性。

从可执行程序到可用编程产品,还需要设计结合业务需求的性能基准测试,并对发现的性能瓶颈进行优化。

经验数据表明,相同功能的编程产品的成本,至少是已经过测试的程序的三倍。 --人月神话

本文将分享性能基准测试的优化案例:

  • 发现性能瓶颈

  • 确定问题组件

  • 借助 CPU Profile 和 Flame Graph,快速缩小范围,定位到问题 code-path

  • 有针对的优化


| 发现性能瓶颈

测试用例:

批量创建100个读写模式为RWO,容量为1GiB 的 PVC

期望测试结果:

180秒内全部创建成功并无报错

所有的编程人员都是乐观主义者,毕竟在可能出现问题的地方,一定都会遇到问题,在耗时 3600 秒后,95% 的 PVC 处于 Pending 状态,严格的说,在批量创建的场景,该功能不可用。


大量 PVC 处于 Pending 状态


| 定位问题组件

由于涉及组件众多:

  • kube-apiserver

  • kube-controller-manager

  • kubelet

  • external-provisioner

  • external-attacher

  • csi-driver

  • qcfs-csi-plugin


组件之间调用复杂,再加上无处不在的协程(goroutine),如果直接查看日志或是 debug code 定位问题,犹如大海捞针,更不要说定位性能瓶颈。所以,首要工作是先定位到问题组件。

在测试过程中,我们记录了所有组件和系统的资源使用情况,运气不佳,从 CPU 使用情况,内存使用情况,网络 I/O 和磁盘 I/O 来看都没有异常数据。

通过梳理存储管理相关组件的架构图:

架构图


以及业务流程的梳理,kube-controller-manager、external-provisioner 和 csi-driver 嫌疑较大。

通过 kubelet logs 查看日志,可以在 external-provisioner 中发现可疑日志:


I0728 19:19:50.504069    1 request.go:480] Throttling request took 192.714335ms, request: POST:https://10.96.0.1:443/api/v1/namespaces/default/eventsI0728 19:19:50.704033    1 request.go:480] Throttling request took 190.667675ms, request: POST:https://10.96.0.1:443/api/v1/namespaces/default/events

external-provisioner 访问 kube-apiserver 触发限流


external-provisioner 有重大嫌疑。


| 定位问题 code-path

我们可以立马进入调试环节:

  1. 阅读 external-provisioner 代码,加入调试日志,理解逻辑

  2. 不断缩小 code-path


步骤 1、2持续迭代,直到最终定位到问题函数,这是非常有效的办法。

或者采用 CPU profile:

  1. 采集堆栈样本

  2. 找到在采样手气内消耗 CPU 时间比率最高的函数,把该函数作为调试的起点


相比上一种,更高效的缩小问题的范围,节省更多的时间。

借助模块"net/http/pprof",对 external-provisioner 进行 60 秒的 CPU 采样,可以获得如下信息:

生成堆栈使用百分比排序:


函数的调用关系以及采样周期内 CPU 耗时百分比:





针对"net/http/pprof"稍微啰嗦几句:

  • 提供 CPU profile 和 Heap profile;

  • 在采样时获得堆栈(几乎所有)信息, 以此为依据估算整个采样周期内堆栈的CPU占用百分比, 并不是 100% 准确;

  • 采样成本并不低,100赫兹既可以采样够用的堆栈信息,又不会给应用程序带来过大开销;

  • CPU 采样频率默认为 100 赫兹,并硬编码到模块中, 不建议调到 500 赫兹以上。


网上已经有大量的相关文章,这里不赘述。

配合获取的 CPU profile 信息生成火焰图(Flame Graph):



这里针对火焰图再啰嗦下:

  • 借助第三方工具 go-torch 绘制

  • 每个矩形代表一个堆栈,采样时间内,CPU 占用百分比越高 Y 轴越长,X 轴表明了堆栈之间的调用关系

  • 从左到右按照字母表排序

  • 颜色随机选择,无具体含义


网上已经有大量的相关文章,这里不赘述。

可以发现函数 addClaim 和 lockProvisionClaimOperation 的 CPU 占用比率达到 36.23%。


来自于 external-provisioner 调用的第三方模块 kubenetes-incubator/external-storage


所以,只要引用例如了模块 Kubenetes-incubator/external-storage 实现卷创建功能,都可以复现 api throttling。

再针对性的加入调试日志到 code-path 中,理解逻辑,很快可以确定问题:

在创建卷时,external-storage 需要访问 API 资源(譬如 configmap、pvc、pv、event、secrets、storageclass 等),为减少 kube-apiserver 工作负荷,不建议直接访问 kube-apiserver,而应该利用本地缓存(由 informer cache 构建)。但 external-storage 恰好直接访问 kube-apiserver。通过下图可以看到,有18.84%的采样时间在 list event,这是导致 api throttling 的原因。



进一步分析,之所以有大量的 list event 是因为 Leader Election 的 Lock 实现粒度太细导致锁抢占严重。生产环境中,一个组件会启动多个实例,抢占到 Leader Lock 的实例即为 Leader 并对外提供服务,其他实例以 Slave 模式运行,一旦 Leader 出现问题,Slave 发现 Leader Lock 在租期内没有更新即可发起抢占成为新的 Leader 并接管服务。这样不仅提升了组件的可用性也避免了可能带来的 data race 问题。所以可以理解成是一个组件实例一把锁,并且只在 Leader 和 Slave 角色切换时才会重新选主,但 external-storage 原意为了提升并发度,运行多个实例同时为 Leader 提供服务,可以简单理解成一个 PVC 一把锁,100 PVC 就意味着多个实例要最少发生100次的 Lock 抢占。

最终定位到问题原因:

Lock 的抢占导致 api throttling,引发 Lock 抢占 timeout,timeout 后抢占重试,进一步恶化 api throttling。

从下图可以进一步得到验证,有 8.7% 的采样时间在进行 Leader Election。


| 解决问题

一旦发现问题的根源,解决它反而是件不难的事情。后面针对该问题做了修复:

  • 采用 sharedinformer cache

  • 修改 Leader Lock 粒度


再次生成运行,可以发现函数 addClaim 和 lockProvisionClaimOperation 的 CPU 占用百分比下降到 13.95%。


external-provisioner 日志中的 throttling 关键字消失


100 PVC 的时间缩短到60秒以内全部创建成功,无任何报错。


| 结语

对于终端用户而言,交互的界面越来越简单,但对于开发者而言,组件越来越多,编译一次的时间越来越久,加上无处不在的并发,导致定位问题的难度越来越大,尤其是性能问题。所以,对体系架构的理解能帮我们快速锁定问题组件,配合 Profile 工具和 Flame Graph 快速定位 code-path,再加上对业务逻辑的理解找到解决方案。


所有的编程人员都是乐观主义者,无论是什么样的程序,结果是勿庸置疑的:"这次它肯定会运行。" 或者 "我刚刚找出了最后一个问题。" --人月神话



| 作者简介

熊中哲·沃趣科技联合创始人

曾就职于阿里巴巴和百度,超过10年关系型数据库工作经验,目前致力于将云原生技术引入到关系型数据库服务中。

问题 组件 定位 性能 堆栈 时间 存储 容器 函数 实例 日志 测试 数据 模块 百分 信息 架构 瓶颈 百分比 程序 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技股 上海睿民互联网科技有限公司 深圳恒合互联网络科技有限公司 河南真二互联网科技有限公司 互联网科技垄断 互联网科技金融公司 宜安科技 互联网金融 奇士达互联网科技 互联网科技小额贷款 居家互联网科技有限公司 哈尔滨新华互联网科技 哈尔滨秒房互联网科技有限公司 华中科技有哪些互联网大佬 银川新华互联网科技职业技术培训学校图片 浙江互联网科技研学营 中国互联网公司排名锤子科技 爱医互联网络科技 广州富喜互联网络科技 山东大美朱楼互联网科技有限公司 众联互联网络科技 华服互联网科技怎么样 互联网通讯科技 银川新华互联网科技学校地址 中盈科技互联网信息有限公司 港股科技和互联网 南平创想时代互联网科技有限公司 世界互联网领先科技成果获奖 福州德业互联网科技 互联网科技新闻 长沙易易互联网科技有限公司
0