分析在 Kubernetes Linux 中运行的 dotnet 核心进程的内存转储

Posted

技术标签:

【中文标题】分析在 Kubernetes Linux 中运行的 dotnet 核心进程的内存转储【英文标题】:Analyze memory dump of a dotnet core process running in Kubernetes Linux 【发布时间】:2019-03-24 15:27:04 【问题描述】:

我在 Google Cloud (GKE) 中使用 Kubernetes。

我有一个应用程序正在囤积我需要的内存 to take a process dump as indicated here。当 pod 达到 512Mb 的 RAM 时,Kubernetes 将杀死它。

所以我连接到 pod

# kubectl exec -it stuff-7d8c5598ff-2kchk /bin/bash

然后运行:

# apt-get update && apt-get install procps && apt-get install gdb

找到我想要的进程:

root@stuff-7d8c5598ff-2kchk:/app# ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  4.6  2.8 5318004 440268 ?      SLsl Oct11 532:18 dotnet stuff.Web.dll
root      114576  0.0  0.0  18212  3192 ?        Ss   17:23   0:00 /bin/bash
root      114583  0.0  0.0  36640  2844 ?        R+   17:23   0:00 ps aux

但是当我尝试转储时...

root@stuff-7d8c5598ff-2kchk:/app# gcore 1
ptrace: Operation not permitted.
You can't do that without a process to debug.
The program is not being run.
gcore: failed to create core.1

我尝试了几个solutions like these,总是以相同的结果结束:

root@stuff-7d8c5598ff-2kchk:/app# echo 0 > proc/sys/kernel/yama/ptrace_scope
bash: /proc/sys/kernel/yama/ptrace_scope: Read-only file system

我找不到连接到 pod 并处理这个 ptrace 事情的方法。我发现 docker 有一个 --privileged 开关,但我找不到与 kubectl 类似的东西。

更新 我找到了how to enable PTRACE:

apiVersion: v1
kind: Pod
metadata:
  name: <your-pod>
spec:
  shareProcessNamespace: true
  containers:
  - name: containerB
    image: <your-debugger-image>
    securityContext:
      capabilities:
        add:
        - SYS_PTRACE

获取进程转储:

root@stuff-6cd8848797-klrwr:/app# gcore 1
[New LWP 9]
[New LWP 10]
[New LWP 13]
[New LWP 14]
[New LWP 15]
[New LWP 16]
[New LWP 17]
[New LWP 18]
[New LWP 19]
[New LWP 20]
[New LWP 22]
[New LWP 24]
[New LWP 25]
[New LWP 27]
[New LWP 74]
[New LWP 100]
[New LWP 753]
[New LWP 756]
[New LWP 765]
[New LWP 772]
[New LWP 814]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
pthread_cond_wait@@GLIBC_2.3.2 () at ../sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
185     ../sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: No such file or directory.
warning: target file /proc/1/cmdline contained unexpected null characters
Saved corefile core.1

有趣的是,我找不到 lldb-3.6,所以我安装了 lldb-3.8:

root@stuff-6cd8848797-klrwr:/app# apt-get update && apt-get install lldb-3
.6
Hit:1 http://security.debian.org/debian-security stretch/updates InRelease
Ign:2 http://cdn-fastly.deb.debian.org/debian stretch InRelease
Hit:3 http://cdn-fastly.deb.debian.org/debian stretch-updates InRelease
Hit:4 http://cdn-fastly.deb.debian.org/debian stretch Release
Reading package lists... Done
Reading package lists... Done
Building dependency tree
Reading state information... Done
Note, selecting 'python-lldb-3.6' for regex 'lldb-3.6'
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

查找 SOS 插件:

root@stuff-6cd8848797-klrwr:/app# find /usr -name libsosplugin.so
/usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.5/libsosplugin.so

运行 lldb...

root@stuff-6cd8848797-klrwr:/app# lldb `which dotnet` -c core.1
(lldb) target create "/usr/bin/dotnet" --core "core.1"

但它会永远隐藏起来,提示永远不会再到达(lldb)...

【问题讨论】:

如果您可以访问主机,您可以使用nsenter 从主机运行命令。不过,我不知道 GKE 在这方面是如何工作的。 @vlad 我仍然收到“ptrace:不允许操作”。即使在使用 securityContext 之后也会出错。任何猜测,为什么? 【参考方案1】:

我有类似的问题。尝试安装正确版本的 LLDB。来自特定 dotnet 版本的 SOS 插件链接到特定版本的 LLDB。例如 dotnet 2.0.5 与 LLDB 3.6 链接,v.2.1.5 与 LLDB 3.9 链接。 此文档也可能会有所帮助:Debugging CoreCLR

请注意,并非所有版本的 LLDB 都适用于某些操作系统。例如 LLDB 3.6 在 Debian 上不可用,但在 Ubuntu 上可用。

【讨论】:

请注意,我不会尝试加载 SOS,它会在此之前挂起,lldb 本身。我尝试先在 lldb 中加载 SOS,但在附加到实时进程和加载转储时它也会挂起。 @Vlad 。它似乎是 lldb 中的一个错误:github.com/nodejs/llnode/issues/61。尝试使用 lldb 4.0。我能够使用 .net 2.1.6+ lldb 4.0 gist.github.com/segor/dd98f3de05b23529af561ec4ed1305f7 加载转储

以上是关于分析在 Kubernetes Linux 中运行的 dotnet 核心进程的内存转储的主要内容,如果未能解决你的问题,请参考以下文章

kubernetes之kubelet运行机制分析

为什么 Kubernetes 很酷 | Linux 中国

在Linux中安装containerd作为kubernetes的容器运行时

kubernetes之kube-proxy运行机制分析

在 Kubernetes 实施混沌工程—— Chaos Mesh® 原理分析与控制面开发

Sonarqube 无法加载组件