容器中Java应用PID为1的问题
背景
Dockerfile中如果通过ENTRYPOINT 直接执行java -jar命令,会发现在容器中的java进程id是1,这样无法通过jstack,jmap,jinfo查看JVM相关信息。
pid |
描述 |
1 |
init进程,系统启动的第一个用户级进程,是其他所有进程的父进程,引导用户空间服务 |
2 |
kthreadd,内核线程管理 |
3 |
migration,用于进程在不同CPU间迁移 |
4 |
ksoftirqd,内核中软中断守护线程,用于系统空闲时定时处理软中断事务 |
5 |
watchdog,看门狗进程,用于监听内核异常,当系统出现宕机时,可利用watchdog记录宕机时堆栈信息 |
Dockerfile配置:
1 2 3 4 5 6 7 8 9
| # 环境 FROM williamyeh/java8:latest
# 拷贝jar文件 COPY /target/app.jar app.jar # 设置端口号 EXPOSE 2023 # 运行jar包 ENTRYPOINT ["java", "-jar", "app.jar", "&"]
|
1 2 3 4 5
| / # export LINES=32; export COLUMNS=142 / # jps -l 1 app.jar 42387 sun.tools.jps.Jps / #
|
方案
避免java应用作为第一个启动的应用。添加tini,作为第一个启动的应用。
- 运行apk add –no-cache tini
- 添加tini作为第一个运行的参数[“tini”, “java”, “-jar”, “app.jar”, “&”]
Dockerfile配置
1 2 3 4 5 6 7 8 9 10
| # 环境 FROM openjdk:8-jdk-alpine # 拷贝jar文件 COPY /target/app.jar app.jar # 运行tini RUN apk add --no-cache tini # 设置端口号 EXPOSE 2023 # 运行jar包 ENTRYPOINT ["tini", "java", "-jar", "app.jar", "&"]
|
1 2 3 4 5 6
| / # export LINES=32; export COLUMNS=142 / # jps -l 434 sun.tools.jps.Jps 354 arthas-boot.jar 7 app.jar / #
|
其他方案
除了使用tini来解决外,通过sh简单再开一个子进程也是可以的:
写好run.sh脚本放到项目中:
1 2
| #!/bin/sh java $JAVA_OPTS -jar tmp/$app.jar
|
1 2
| COPY ./target/$app.jar /tmp ENTRYPOINT [ "sh","-c","/tmp/run.sh"]
|