使用sidecar container dump 正在运行的容器

本文最后更新于:7 小时前

引言

memory dump是分析线上程序内存占用非常好的工具

windows上可以直接任务管理器右键生成dump,假如需要根据条件比如CPU 内存占用到多少生成dump可以使用procdump

额外的,还可以使用dotmemory.exe创建dump

linux呢?

可以使用dotnet-dumpdotnet-gcdump

经我测试,dotnet-gcdump安装后可直接执行命令无问题,但在dump中未发现更多数据,于是尝试使用dotnet-dump

但是我在正式服务器上安装一堆东西执行命令后却报错:

1
dotnet-dump fails with "Writing dump failed (HRESULT: 0x80004005)"

GPT告诉我这是因为docker run时未添加特权参数--cap-add=SYS_PTRACE --security-opt seccomp=unconfined导致的

但问题是,我只需要为这个线上容器(Container)创建dump而不是要重新起一个容器

本文介绍解决方法

解决方案

微软的官方文档里面有提到这种方法:Collect diagnostics in Linux containers

即为sidecar container

就是另起一个带有特权参数的容器,通过命名空间共享(share a process namespace)

在特权容器中创建dump

这里给出我的命令

以下命令皆由AI生成

操作步骤

正常使用dotnet-dump的命令

这里先给出正常情况下,特权参数启用testServer时的命令以做参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
###docker run --name test007 --security-opt seccomp=unconfined --rm --cap-add=SYS_PTRACE testServer

docker exec -it test007 bash
###add proxy
export https_proxy=http://127.0.0.1:7890
export http_proxy=http://127.0.0.1:7890


###install sdk
apt-get update
apt-get install -y wget apt-transport-https software-properties-common

wget https://packages.microsoft.com/config/debian/$(lsb_release -rs)/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
dpkg -i packages-microsoft-prod.deb

apt-get update
apt-get install -y dotnet-sdk-5.0


####install dump tool
dotnet tool install --global dotnet-dump --version 5.0.251802
dotnet tool install --global dotnet-gcdump --version 5.0.251802


export PATH="$PATH:$HOME/.dotnet/tools"

###should get error: dotnet-dump fails with "Writing dump failed (HRESULT: 0x80004005)" if not --security-opt seccomp=unconfined --rm --cap-add=SYS_PTRACE
dotnet-dump collect -p 1 -o /tmp/webservice.dmp --type Full

exit
docker cp test007:/tmp/webservice.dmp .

这里因为我的服务用的.NET 5.0因此选用5.0的版本,假如不知道对应安装的dotnet-dump版本可查看dotnet-dump versions

PS:测试时可以使用docker commit test007 test007-2命令临时将安装的内容保存,方便调试

sidecar container dotnet-dump生成dump

正常sidecar应该是这样的命令

1
docker run --rm -it --name t07 --pid=container:test007       --cap-add SYS_PTRACE    -v /tmp/dumps:/dumps_out     test007-2    bash -c "dotnet-dump collect -p 1 -o /dumps_out/myapp.dmp --type Full"

这里使用安装了dotnet-dump的临时image:test007-2

生成的dump文件为Host/tmp/dumps/myapp.dmp

但实际执行会发现报错:

Process 1 not running compatible .NET runtime.

微软的官方文档里有提到这个报错:Use .NET CLI tools in a sidecar container or from the host

它的方案是共享/tmp 路径,这里我没明白什么意思,但是我找到另一种支持的方法

sidecar container createdump生成dump

Microsoft.NETCore.App中已经自带了createdump程序,可以直接生成dump

这个文件位于容器的/usr/share/dotnet/shared/Microsoft.NETCore.App目录中,根据你安装的runtime版本有所不同,因此首先我找到本地自带的createdump版本

1
2
docker run  --rm -it --name t07   mcr.microsoft.com/dotnet/aspnet:5.0    bash -c "ls /usr/share/dotnet/shared/Microsoft.NETCore.App/"
####output 5.0.5

直接使用createdump创建dump

1
docker run --rm -it --name t07 --pid=container:test007       --cap-add SYS_PTRACE    -v /tmp/dumps:/dumps_out         mcr.microsoft.com/dotnet/aspnet:5.0         bash -c "/usr/share/dotnet/shared/Microsoft.NETCore.App/5.0.5/createdump --full     --name /dumps_out/myapp.dmp    1"

生成的dump文件为Host/tmp/dumps/myapp.dmp

1为test007dotnet服务的pid,可以通过命令查询

5.0.5为本机mcr.microsoft.com/dotnet/aspnet:5.0createdump版本

同时,使用aspnet:5.0的镜像还避免了正式服务多实例数据异常的风险,可以说是一劳多得,一箭双雕

传输

dump文件一般很大,所以需要压缩传输

tar -czvf dump.tar.gz /tmp/dumps/myapp.dmp

假如压缩后还是很大,且正式服务器带宽不大,可以看我之前的文章:

使用docker加速阿里云ECS下载

参考资料


使用sidecar container dump 正在运行的容器
http://blog.wangshuai.app/2025-05-21-csharp_dump_in_docker/
作者
王帅
发布于
2025年5月21日
许可协议