为何需要远程debug
开发过程中一般在本地进行开发调试,然后上线。但在kubenetes环境下,本地调试非常困难。因为从注册中心获取的服务IP都是集群内虚拟IP,本机无法访问。虽然本地调试不容易实现,但远程调试还是可以实现的,弥补了部分不便。
非容器环境远程如何开启远程debug
首先讲一下非容器环境下如何开启远程调试。在远程主机上启动动JVM时加入debug参数即可打开,命令类似如下:
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar app.jar
参数说明:
transport=dt_socket:用socket方式进行通信;
server=y:表示当前是服务端;
suspend=n:是否在调试客户端建立连接之后启动 JVM。suspend=n表示启动时不中断;
address=5005:监听端口
容器环境下开启远程debug
原理
容器环境下开启远程debug原理非常简单,首先用debug模式运行JVM,监听debug端口。然后通过Service以一定的方式将Pod监听的debug端口暴露出去。暴露方式有两种,一种是NodePort,一种是externalIPs。
让Pod中JVM以debug模式运行
让Pod中JVM以debug模式运行就是在镜像启动命令中加入debug参数,方式有:
使用镜像的ENTRYPOINT
FROM primetoninc/jdk:1.8ADD ./target/jdktest-0.0.1-SNAPSHOT.jar app.jarENTRYPOINT ["java", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005", "-jar", "app.jar"]在Pod模板中指定CMD
apiVersion: apps/v1beta1kind: Deploymentmetadata:name: k8s-boot-deploymentnamespace: bcloudlabels:app: k8s-boot-deploymentspec:replicas: 1selector:matchLabels:app: k8s-boottemplate:metadata:labels:app: k8s-bootspec:containers:- name: springboot-demoimage: jdktest:1.0imagePullPolicy: Nevercommand: ["java"]args: ["-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005", "-jar", "app.jar"]ports:- containerPort: 8094
NodePort方式
创建以下类似service,将Pod的端口暴露出去。这种方式需查询pod部署节点的IP,然后用IDE直连30001端口即可。
apiVersion: v1kind: Servicemetadata:name: k8s-boot-servicenamespace: btestspec:type: NodePortports:- name: httpport: 8094 #web服务地址nodePort: 30000- name: debugport: 5005 #debug端口地址nodePort: 30001selector:app: k8s-boot
远程debug效果如下:

externalIPs方式
externalIPs是Kubenetes提供的另一种暴露方式,可将集群中任意节点作为暴露节点,请求时在转发到Pod所在节点。创建的Service如下:
apiVersion: v1kind: Servicemetadata:name: k8s-boot-servicenamespace: btestspec:type: NodePortports:- name: httpport: 8094protocol: TCP- name: debugprotocol: TCPport: 5005externalIPs:- 192.168.101.122 #暴露的IPselector:app: k8s-boot
以上例子中,在IDE上直连192.168.101.122,端口5005即可。
文章转载自CodingWithFun,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




