如何对运行中的Golang程序做内存profile?解决kubelet内存持续上涨问题
运行中Go程序内存Profile操作指南(含kubelet场景)
前置说明
Go标准库自带的net/http/pprof可直接采集运行中程序的内存Profile,kubelet作为官方Go开发的项目,默认已集成pprof监听端点,无需修改代码即可直接采集。
kubelet内存Profile操作步骤
1. 拉取堆内存Profile
kubelet默认在10250端口暴露pprof接口,执行对应命令拉取当前堆内存快照:
- 无认证场景:
curl -k https://<kubelet节点IP>:10250/debug/pprof/heap > heap.pprof
- 开启客户端认证场景:
curl -k --cert /var/lib/kubelet/pki/kubelet-client-current.pem --key /var/lib/kubelet/pki/kubelet-client-current.pem https://<kubelet节点IP>:10250/debug/pprof/heap > heap.pprof
本地调试同节点kubelet时,可直接用127.0.0.1代替节点IP访问
2. 多时间点采样对比
要定位内存持续上涨问题,建议间隔10~30分钟拉取多份快照,方便后续对比增量:
# 首次采样 curl ... > heap_1.pprof # 30分钟后二次采样 curl ... > heap_2.pprof
3. 分析Profile文件
本地安装对应版本Go环境后,用go tool pprof工具分析:
- 基础内存占用分析:
go tool pprof heap.pprof
进入交互界面后输入top,即可查看当前内存占用最高的Top10函数调用链。
- 增量对比分析:
go tool pprof -diff_base heap_1.pprof heap_2.pprof
进入交互界面输入top,可直接查看两个采样时间点之间内存增量最高的函数,快速定位泄漏点。
- 可视化调用链:
本地安装graphviz后,在pprof交互界面输入web,可自动生成SVG格式的内存分配调用链图,直观查看分配路径。
通用自研Go程序内存Profile方案
如果是自行开发的Go程序,先集成pprof能力再执行采集:
- 代码中引入pprof包:
import _ "net/http/pprof"
- 程序启动时开启pprof监听端口:
go func() { log.Println(http.ListenAndServe("0.0.0.0:6060", nil)) }()
后续采集、分析流程和kubelet完全一致,访问http://<程序IP>:6060/debug/pprof/heap拉取Profile即可。
注意事项
- 拉取内存Profile对运行中程序的性能影响极小,生产环境可放心执行,不会影响业务正常运行。
- 若需要查看包含已被GC回收对象的全量分配记录,将拉取路径改为
/debug/pprof/allocs即可。 - 若kubelet修改了默认监听端口,将命令中的10250替换为实际配置的端口即可。
内容的提问来源于stack exchange,提问作者Daniel Safta
相关产品推荐
相关产品推荐

