multiple app nodes how to expose jmx in kubernetes?

此生再无相见时 提交于 2019-12-02 16:38:15

Another option is to forward JMX port from K8 pod to your local PC with kubectl port-forward.

I do it like this:

1). Add following JVM options to your app:

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.port=1099
-Dcom.sun.management.jmxremote.rmi.port=1099
-Djava.rmi.server.hostname=127.0.0.1

The critical part here is that:

  • The same port should be used as 'jmxremote.port' and 'jmxremote.rmi.port'. This is needed to forward one port only.

  • 127.0.0.1 should be passed as rmi server hostname. This is needed for JMX connection to work via port-forwarding.

2). Forward the JMX port (1099) to your local PC via kubectl:

kubectl port-forward <your-app-pod> 1099

3). Open jconsole connection to your local port 1099:

jconsole 127.0.0.1:1099

This way makes it possible to debug any Java pod via JMX without having to publicly expose JMX via K8 service (which is better from security perspective).

Another option that also may be useful is to attach the Jolokia (https://jolokia.org/) agent to the Java process inside the container so it proxies the JMX over HTTP port and expose or port-forward this HTTP port to query JMX over HTTP.

We did it in following way

  1. Add a unique label for each pod. ex: podid=asdw23443
  2. Create a new service with selector of podid=asdw23443. Make sure in the service you expose jmx ports on pod through nodeport or loadbalancer.

If you are selecting nodeport in service, because you a doing a NAT operation you may have to give following JVM argument for each jvm you need to connect through jconsole

-Djava.rmi.server.hostname=<your-ip-address>
Liran Cohen

I think one way is to add a label to your pod with a unique string \ id for example pod_name and use the expose command to create a new service with the selector of this unique id\string.

kubectl label pods <podname> podname=<podname>
kubectl expose pod <podname> --port=9010 --name=<podname>_jmx

Adding to https://stackoverflow.com/a/39927197/1387184, I wanted to monitor all instances of the same pod at once, since we are hardcoding the port as 1099, it was difficult as I can do only one portforward to one pod with that port.

I used Shell Script to dynamically assign pod when running the docker

Dockerfile CMD /run.sh

run.sh

JMX_PORT=$(((RANDOM % 20)+1099))

echo "Running JMX on Port $JMX_PORT"

java ``eval echo $JAVA_OPTS`` ...

deployment.yml env: - name: JAVA_OPTS value: "-Xms256m -Xmx6144m -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.port=$JMX_PORT -Dcom.sun.management.jmxremote.rmi.port=$JMX_PORT -Djava.rmi.server.hostname=127.0.0.1"

the eval will evaluate the JMX_PORT to bash value, each pod when starts will likely to get different pod. I

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!