搬砖小抄

远程调试容器网络中的JAVA应用

字数统计: 725阅读时长: 2 min
2020/06/28 Share

假设因为某种原因,你想对已经部署的java应用进行调试,应该怎么做呢?我假设你的部署环境是这样子的:

  • 你的应用跑在kubernetes
  • 你的开发机不没有加入kubernetes集群,换而言之,你的开发机和应用的网络是不通的。
  • 你的容器启动命令并没有预留JVM远程调试参数(实际上也不可能在正式环境加这个参数)。

也就是说,虽然我们知道可以利用JVM的远程调试功能来解决这个问题,但是具体实施的时候,还需要解决以下问题:

  1. 打通开发机和JAVA应用之间的网络
  2. 不能重新打docker镜像,但是需要给JAVA应用的增加远程调试的启动参数

这里先给出解决办法:对于第一个问题,可以通过kubernetes对外暴露服务端口来实现,第二个问题则通过JAVA_TOOL_OPTIONS这个环境变量来解决。

环境描述

  • 集群环境: K3S
  • 开发工具: IDEA

JAVA 应用的Dockerfile

1
2
3
4
5
6
7
8
FROM openjdk:8
MAINTAINER jclazz@outlook.com
ENV TZ=Asia/Shanghai
RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN mkdir -p /my-app
WORKDIR /my-app
ADD ./target/my-app.jar ./
CMD java -Xms128m -Xmx256m -Djava.security.egd=file:/dev/./urandom -jar my-app.jar

如你所见,java应用的启动命令已经写死

具体过程

第一步:在开发工具(IDEA)中添加远程调试选项

说明

  • 第一个地方,IP填写K3S的集群IP(也就是任意集群节点的IP),端口为对外暴露的调试端口。这个IP和端口先记录下来,后面会用到
  • 第二个地方是根据第一个地方的设置自动变化的,称为远程调试参数也需要记录下来。
  • 第三地方要注意根据实际的运行环境一致,根据上面的Dockerfile可知,我们的应用跑在JVAV8的环境下。
  • 第四个地方,选择源代码所在的模块

第二步:修改Java应用的部署脚本

rancher管理面板中修改应用的配置(也就是升级):

  • 新增一个环境变量JAVA_TOOL_OPTIONS,值为上面记录的远程调试参数
  • 新增一个端口映射,将容器内的远程调试服务端口暴露在集群网络外部。

点击升级,应用启动后,会挂起,等待调试客户端连接

第三步:在开发工具(IDEA)中连接调试服务器,进行软件调试

选择之前新建的远程调试配置,点击调试

控制台显示远程调试连接成功

k3s控制台日志显示,之前挂起进程已经恢复,并且启动完毕。在这个过程中,如果有调试端点命中,在IDEA中看到激活的断点。

参考资料

CATALOG
  1. 1. 环境描述
  2. 2. 具体过程
    1. 2.1. 第一步:在开发工具(IDEA)中添加远程调试选项
    2. 2.2. 第二步:修改Java应用的部署脚本
    3. 2.3. 第三步:在开发工具(IDEA)中连接调试服务器,进行软件调试
  3. 3. 参考资料