业务上云迁移至腾讯云 Serverless 集群后,使用perf
生成服务器的火焰图。
背景
业务模块使用的基础镜像是Ubuntu20.04
,上云前的做法是在机器上docker run的,命令如下:
docker run --cap-add CAP_SYS_ADMIN --privileged=true --pid=container:${targetContainerId} --network=container:${targetContainerId} ${image}:${imageTag} -ti ... |
上云后通过在 Pod 中的容器之间共享进程命名空间的方式实现,在业务Pod中注入一个用于perf
分析的容器。
安装 perf
apt-get install linux-tools-generic |
注意事项
安装 linux-tools-generic 完成后,需要建立软链接,不然查看 perf
版本,会提示如下报错信息。
root@game-server-6-6f446dcxxx-5j45b:~# perf |
这里报错其实是因为
perf
已经内置在linux-tools-generic
里面,所以我们安装后创建perf
软链接即可(5.4.0-125-generic 版本目录根据实际情况替换即可)。
使用 perf 生成火焰图
pod 共享进程命名空间
使用 Pod .spec
中的 shareProcessNamespace
字段可以启用进程命名空间共享,官方例子:
apiVersion: v1 |
注意事项
我们需要在 perf
容器中分析业务容器 gamesvr
,这个操作需要 SYS_PTRACE 权能。所以我们需要为 perf
Container 设置权能。通过安全上下文(Security Context)定义 Pod 或 Container 的特权与访问控制设置。
这里列举部分能力:
CAP_SYS_MODULE: 允许插入和删除内核模块 |
我们使用 perf
来分析业务进程,所以需要 CAP_SYS_PTRACE 权能。
Linux Capabilities 的定义的形式为 CAP_XXX。但是你在 Container 字段使用时,需要将名称中的 CAP_ 部分去掉。例如,要添加 CAP_SYS_PTRACE,可在 capabilities 列表中添加 SYS_PTRACE。
perf 容器注入
我这里工作负载是使用的 deployment,通过 openkruise sidecarset 注入,这里就不赘述。注入完成后我们 exec 进入 perf 容器,执行 ps -ef
可以看到业务容器的进程 gamesvr
的进程ID是13。
root@game-server-6-6f446dcxxx-5j45b:~# ps -ef |
perf 分析
执行 perf record -F 99 -g -m 1 -p ${targetContainerId} -- sleep 120
,targetContainerId 是业务进程ID。
root@game-server-6-6f446dcxxx-5j45b:~# perf record -F 99 -g -m 1 -p 13 -- sleep 120 |
查看分析文件
root@game-server-6-6f446dcxxx-5j45b:~# perf report -i perf.data > perf.txt |
生成火焰图,这里会用到火焰图工具。
root@game-server-6-6f446dcxxx-5j45b:~# git clone https://github.com/brendangregg/FlameGraph.git |
这里生成的 demo.svg 就是我们需要的火焰图(下面是一个例图)。开发可以通过火焰图来查看看服务的性能热点。
总结
这里协助开发使用 perf
生成火焰图的过程中遇到了2个问题,一是安装 perf
装不上报错,二是由于 perf
容器没有 SYS_PTRACE 权能导致生成的分析数据没有函数名称(只有地址信息)。通过协助排查问题加深了对 k8s Security Context的理解。