Remote JVM debugging

Posted by Marcin on Tuesday, April 23, 2024

Scenario

Debugging applications in a local environment is straightforward, but what happens when your application is running in a Kubernetes cluster? Sometimes the best place to debug an issue is the remote instance itself. This article will guide you through the process of remotely debugging your Java applications running in Kubernetes.

Prerequisites

In this very short post I assume you have:

  • a Java application running in a Kubernetes cluster
  • IntelliJ IDEA
  • kubectl command-line tool installed and configured

Step 1: Start Your Java Application in Debug Mode

First, you need to ensure your Java application is running in debug mode. This is not happening by default.

Please adjust your application startup command by adding the following JVM options:

-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005

This will start your Java application in debug mode, listening on port 5005.

Let’s shortly explain what some of the options mean:

  • server=y stands for the server mode, which means that the JVM will listen for incoming debugger connections.
  • suspend=n means that the JVM will not wait for the debugger to connect before starting the application. This could be useful when you want to debug the application from the very beginning.
  • address=*:5005 specifies host and port on which the JVM will listen for incoming debugger connections.

Step 2: Expose Debug Port in Kubernetes

Expose Debug Port in Kubernetes deployment

That can be achieved by either modifying the deployment file or using kubectl port-forward command.

Below k8s deployment snippet shows how deployment could be adjusted in order to open debug port:

spec:
  template:
    spec:
      containers:
      - name: my-java-app
        image: my-java-app:latest
        ports:
        - containerPort: 8080
        - name: debug
          containerPort: 5005

Tunnel the Debug Port to Your Local Machine

On the other hand we can port forward the debug port to our local machine:

kubectl port-forward deployment/my-java-app 5005:5005

Step 3: Connect IntelliJ IDEA to the Remote JVM

I’m personally a big fan of IntelliJ IDEA, so I will guide you through the process of connecting to the remote JVM using IntelliJ IDEA.

  1. Go to Run -> Edit Configurations.

  2. Click on the + button and select Remote.

  3. In the Port field, enter 5005.

  4. Click OK.

  5. Now, you can start your debugging session by clicking on the debug icon or by pressing Shift + F9.

Conclusion

Debugging Java applications in Kubernetes might seem daunting at first, but with the right tools and configurations, it becomes a straightforward task. Happy troubleshooting! Just let me know what you think about this article in the comments.

Warning

Few things to note from security perspective:

  • as of writing this article intelliJ does not support authentication of the debugging connection!
  • because of above I prefer that debug socket listens only on localhost address (address=localhost:5005) and then use kubectl port-forward to tunnel the connection only to debug client machine
  • I would also recommend to change the default debug port to something less obvious (address=localhost:PORT)

Tip

Would I recommend to have debugging enabled by default on:

  • production? No, I would not.
  • staging? Yes. Just make sure that you have a way to secure the connection.

comments powered by Disqus