关键在于先区分泄漏主体:若容器内存稳定而dockerd rss从500mb涨至2gb+,则是dockerd自身泄漏,需检查netns残留、volume挂载、插件异常,并用pprof和debug日志分析堆内存增长。

排查 Docker 容器内存泄漏,关键在于分清“谁在漏”:是容器内应用本身,还是 Docker 守护进程(dockerd)自身。两者表现、工具和路径完全不同,混在一起查只会浪费时间。
先快速定位泄漏主体
打开终端,执行两组命令对比:
-
docker stats --no-stream—— 查看各容器的 MEM USAGE / LIMIT 是否持续上涨(尤其关注单个容器是否从几百 MB 涨到几 GB) -
ps aux --sort=-rss | head -10或top -o %MEM—— 找出 RSS 最高的进程,确认是不是dockerd(不是容器 PID)
如果容器内存涨、dockerd RSS 也同步涨 → 需进一步交叉验证;
如果容器内存平稳,但 dockerd RSS 从 500MB 涨到 2GB+ → 是 dockerd 自身泄漏;
如果只有某容器 RSS 持续上涨,其他容器和 dockerd 都稳定 → 泄漏在该容器应用内。
在 Linux 上通过 Docker 运行 OpenClaw,并使用 Tailscale 实现远程访问。⚠️ 涉及 sudo、Docker、Tailscale和凭证挂载——请先查阅安全章节...
容器内应用泄漏:进容器查进程与堆
适用于 Java/Python/Go 等常见语言服务:
-
Java 应用:进容器后,用
jcmd $(pgrep java) VM.native_memory summary看原生内存趋势;再用jmap -dump:format=b,file=/tmp/heap.hprof <pid></pid>导出堆快照,用 VisualVM 或 Eclipse MAT 分析大对象和引用链 -
Python 应用:启用
tracemalloc(代码中加import tracemalloc; tracemalloc.start()),或直接运行memray run your_app.py生成火焰图 -
通用方法:在容器内执行
cat /proc/1/status | grep -E "VmRSS|VmSize"获取主进程实际物理内存;用top -p $(pgrep -f your_entrypoint)动态观察 RSS 变化
dockerd 进程自身泄漏:查句柄、命名空间与插件
当 dockerd RSS 异常增长,但所有容器内存平稳时,重点检查底层资源未释放:
- 检查网络命名空间残留:
ls /var/run/docker/netns/ | wc -l,数量远超当前运行容器数(比如 200+ 个 netns,但只跑了 5 个容器)→ 表明 endpoint 未清理 - 检查 volume 挂载点:
mount | grep overlay2 | wc -l,结合docker volume ls对比,大量未关联 volume 的挂载说明卸载失败 - 临时禁用可疑插件:修改
/etc/docker/daemon.json,设"log-driver": "json-file"、"default-runtime": "runc",重启 dockerd 后观察 RSS 是否止涨
用 pprof 和 debug 日志精准抓堆
对 dockerd 开启深度诊断(需重启):
- 编辑
/etc/docker/daemon.json,加入:{"debug": true, "log-level": "debug"},然后sudo systemctl reload docker - 实时过滤内存相关日志:
sudo journalctl -u docker -f | grep -E "(malloc|free|unmount|layer.*get|gc)",重点关注反复出现的failed to unmount或get layer by diffID无对应 release - 调用内置 pprof 接口:
curl -s 'http://localhost:2376/debug/pprof/heap' | go tool pprof -http=:8080 -,查看*sync.Map、*net.Interface实例数是否线性增长










