Java工程部署在 CentOS 服务器上。项目偶尔会出现无响应的情况,这时理所当然要上去用 JDK 相关命令看看堆栈和GC等信息了。近期在开发环境的docker排查问题时,发现GC异常频繁,且为full GC,导致系统资源消耗严重,然而jmap命令不可用,导致无法查看Java虚拟机内存占用情况,无法进一步分析。
jps、top、jstat命令均可用。
然而,使用jmap命令
1 | jmap -heap 1 |
打印堆栈信息时,却报错了
1 | Attaching to process ID 1, please wait... |
以上的关键信息就是:Can't attach to the process: ptrace(PTRACE_ATTACH, ..) failed for 1: Operation not permitted
,操作不允许。
解决方案
这其实不是什么 Bug,而是 Docker 自 1.10 版本开始加入的安全特性。
类似于 jmap 这些 JDK 工具依赖于 Linux 的 PTRACE_ATTACH,而是 Docker 自 1.10 在默认的 seccomp 配置文件中禁用了 ptrace。
主要有三种解决办法:
–security-opt seccomp=unconfined
简单暴力(不推荐),直接关闭 seccomp 配置。用法:
1 | docker run --security-opt seccomp:unconfined ... |
–cap-add=SYS_PTRACE
使用 –cap-add 明确添加指定功能:
1 | docker run --cap-add=SYS_PTRACE ... |
Docker Compose 的支持
Docker Compose 自 version 1.1.0 (2015-02-25) 起支持 cap_add。官方文档:cap_add, cap_drop。用法:
前面的 docker-compose.yml 改写后文件内容如下(相同内容部分就不重复贴了):
1 | version: '2' |