pprof使用

go环境安装

pprof工具是go tool里的工具, 所以需要提前安装golang环境

官方文档: https://go.dev/doc/install

1
2
3
4
$ wget https://go.dev/dl/go1.23.2.linux-amd64.tar.gz
$ rm -rf /usr/local/go && tar -C /usr/local -xzf go1.23.2.linux-amd64.tar.gz
$ echo "export PATH=$PATH:/usr/local/go/bin" >> /etc/profile
$ source /etc/profile

或者通过docker运行

1
2
$ docker run -itd --name golang-env --net host golang bash
$ docker exec -it golang-env bash

获取kubelet数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
开启kube-apiserver http访问代理
kubectl proxy --address='0.0.0.0' --accept-hosts='^*$'

$ export NODENAME=k8s-node-1

通过cURL代理导出
$ curl 127.0.0.1:8001/api/v1/nodes/${NODENAME}/proxy/debug/pprof/heap?seconds=30 > kubelet.heap # 内存
$ curl 127.0.0.1:8001/api/v1/nodes/${NODENAME}/proxy/debug/pprof/profile?seconds=30 > kubelet.profile # cpu

通过go导出
$ go tool pprof http://127.0.0.1:8001/api/v1/nodes/${NODENAME}/proxy/debug/pprof/heap?seconds=30 # 内存
Saved profile in /root/pprof/pprof.kubelet.samples.memory.001.pb.gz
$ go tool pprof http://127.0.0.1:8001/api/v1/nodes/${NODENAME}/proxy/debug/pprof/profile?seconds=30 # cpu
Saved profile in /root/pprof/pprof.kubelet.samples.cpu.001.pb.gz

通过kubectl查看,慢
$ kubectl get --raw "/api/v1/nodes/${NODENAME}/proxy/debug/pprof/heap" > kubelet.heap # 内存
$ kubectl get --raw "/api/v1/nodes/${NODENAME}/proxy/debug/pprof/profile" > kubelet.profile # cpu
$ kubectl get --raw "/api/v1/nodes/${NODENAME}/proxy/debug/pprof/goroutine?debug=2"

获取apiserver的数据

kube-apiserver 需要启用--profiling 如果没有配置关闭的话在1.18之后是默认开启

–profiling=true

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
开启kube-apiserver http访问代理
$ kubectl proxy --address='0.0.0.0' --accept-hosts='^*$'

通过cURL代理导出
$ curl 127.0.0.1:8001/debug/pprof/heap?seconds=30 > apiserver.heap # 内存
$ curl 127.0.0.1:8001/debug/pprof/profile?seconds=30 > apiserver.profile # cpu


通过go导出
$ go tool pprof http://127.0.0.1:8001/debug/pprof/heap?seconds=30 # 内存
Saved profile in /root/pprof/pprof.kube-apiserver.alloc_objects.alloc_space.inuse_objects.inuse_space.001.pb.gz

$ go tool pprof http://127.0.0.1:8001/debug/pprof/profile?seconds=30 # cpu
Saved profile in /root/pprof/pprof.kube-apiserver.alloc_objects.alloc_space.inuse_objects.inuse_space.001.pb.gz

NGINX INGRESS

1
2
$ curl 127.0.0.1:10245/debug/pprof/heap?seconds=60 -o nginx.heap  # 内存
$ curl 127.0.0.1:10245/debug/pprof/profile?seconds=60 -o nginx.profile # cpu

ISTIO数据

1
https://github.com/istio/istio/wiki/Analyzing-Istio-Performance

可视化展示

web方式

1
2
3
4
5
安装graphviz工具
$ yum install -y graphviz

可视化web方式访问
$ go tool pprof -http 0.0.0.0:80 kubelet.heap

svg导出火焰图(好像不行)

如何看懂火焰图: https://www.ruanyifeng.com/blog/2017/09/flame-graph.html
https://www.cnblogs.com/conscience-remain/p/16142279.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
抓perf:
# perf record -F 99 -p 110 -g -- sleep 30
上面的代码中,perf record表示记录,-F 99表示每秒99次,-p 110是进程号,即对哪个进程进行分析,-g表示记录调用栈,sleep 30则是持续30秒。

火焰图:
具体步骤:
1、 首先,yum安装 perf 工具
yum -y install perf

2、 再从github下载分析脚本
git clone https://mirror.ghproxy.com/https://github.com/brendangregg/FlameGraph.git

3、 使用perf script工具对perf.data进行解析
perf script -i perf.data &> perf.unfold

4、 将perf.unfold中的符号进行折叠
FlameGraph/stackcollapse-perf.pl perf.unfold &> perf.folded

5、 最后生成svg图
FlameGraph/flamegraph.pl perf.folded > perf.svg
1
2
3
$ git clone https://ghproxy.com/https://github.com/brendangregg/FlameGraph.git
$ FlameGraph/stackcollapse-go.pl kubelet.heap > kubelet.out
$ FlameGraph/flamegraph.pl kubelet.out > kubelet.svg

日志级别热更新

可以通过接口,动态热更新kubelet/kube-apiserver的日志级别:

1
2
3
4
5
6
7
8
9
10
11
开启kube-apiserver http访问代理
$ kubectl proxy --address='0.0.0.0' --accept-hosts='^*$'

更新kube-apiserver日志级别
$ curl -X PUT http://127.0.0.1:8001/debug/flags/v -d "4"
successfully set klog.logging.verbosity to 4

# 同样也更新kubelet日志级别
$ export NODENAME=k8s-node-1
$ curl -X PUT http://127.0.0.1:8001/api/v1/nodes/${NODENAME}/proxy/debug/flags/v -d "4"
successfully set klog.logging.verbosity to 4

参考: