一般情况下,我们要获取docker容器里的jvm信息只能进入容器后执行jmap,jstack,jstat 命令去获取,jstack,jstat还好,但是jmap dump的文件要拿出来,得先copy dump文件到挂载在宿主机上的目录,或者使用docker cp命令去获取,
如 https://pathtogeek.com/thread-heap-dumps-from-a-docker-container
1. Run the below command to bash into the container. Please change the CONTAINER_NAME appropriately
docker exec -it CONTAINER_NAME bash
2. Then type jps to find the all the Java application details and extract the PID for your application
jps
3. Then run the below command to get the thread dump. Please change the PID appropriately
jstack PID > threadDump.tdump
4. Then run the below command to get the Heap dump. Please change the PID appropriately
jmap -dump:live,format=b,file=heapDump.hprof PID
5. Then exit from the docker container and download the threadDump.tdump and heapDump.hprof from the docker container by running the below command. Please change the CONTAINER_NAME appropriately
sudo docker cp CONTAINER_NAME:threadDump.tdump .
sudo docker cp CONTAINER_NAME:heapDump.hprof .
现在我们要在宿主机上直接获取这些信息要怎么做的,
docker exec -it $containerid /bin/ps x 获取到我们需要的容器里的进程id
docker exec -it $containerid /jdk/bin/jstack $pid 获取容器里进程的jstack信息
一切执行顺利,我们继续试试jmap
docker exec -it $containerid /jdk/bin/jmap -dump:live,format=b,file=heapDump.hprof $pid
报错
why? 网上有篇文章提及了类似的情况 https://www.xiaocaicai.com/2018/07/09/docker-%E5%AE%B9%E5%99%A8%E9%87%8C%E6%97%A0%E6%B3%95%E4%BD%BF%E7%94%A8-jdk-%E7%9A%84-jmap-%E7%AD%89%E5%91%BD%E4%BB%A4%E7%9A%84%E9%97%AE%E9%A2%98/
线上java程序出现异常,需要打印内存信息进行debug,发现没有 jmap,jstack等工具。
发现容器基础镜像选择的是FROM java:-jre,jre环境是不包含这类工具的,遂将换成FROM java:,这类工具便包含在内了。
使用时发现还是不能使用,出现错误 “Can’t attach to the process: ptrace(PTRACE_ATTACH, ..) failed for : Operation not permitted docker” 查询资料后发现:
这其实不是什么 Bug,而是 Docker 自 1.10 版本开始加入的安全特性。
类似于 jmap 这些 JDK 工具依赖于 Linux 的 PTRACE_ATTACH,而是 Docker 自 1.10 在默认的 seccomp 配置文件中禁用了 ptrace。
相关资料 主要方法2个:
.使用 –cap-add 明确添加指定功能:
docker run –cap-add=SYS_PTRACE … .Docker Compose 自 version 1.1. (--) 起支持 cap_add。 version: '' services:
mysql:
...
api:
...
cap_add:
- SYS_PTRACE
那就死马当活马医把,修改marathon的配置
执行ps x|grep docker|grep web, 看到docker run命令里已经有 cap-add 这个参数了
再次执行,成功导出