简体   繁体   English

多个应用程序节点如何在 kubernetes 中公开 jmx?

[英]multiple app nodes how to expose jmx in kubernetes?

  1. In kubernetes I can expose services with service .kubernetes我可以使用service公开service This is fine.这可以。
  2. Lets say I have 1 web instance and 10 java server instances.假设我有 1 个 web 实例和 10 个 java 服务器实例。
  3. I have a windows gateway I'm used to access those 10 java servers instances via the jconsole installed on it.我有一个 Windows 网关,我习惯于通过安装在它上面的 jconsole 访问这 10 个 java 服务器实例。
  4. Obviously I do not expose all apps jmx port via kubernetes service.显然我没有通过 kubernetes 服务公开所有应用程序 jmx 端口。

What are my options here?我在这里有哪些选择? how should I allow this external to kubernetes cluster windows gateway access to those 10 servers jmx ports?我应该如何允许 kubernetes 集群 Windows 网关外部访问这 10 个服务器 jmx 端口? Any practices here?这里有什么做法吗?

Another option is to forward JMX port from K8 pod to your local PC with kubectl port-forward .另一种选择是使用kubectl port-forward将 JMX 端口从 K8 pod 转发到您的本地 PC。

I do it like this:我这样做:

1). 1)。 Add following JVM options to your app:将以下 JVM 选项添加到您的应用程序:

-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'.应该使用相同的端口作为“jmxremote.port”和“jmxremote.rmi.port”。 This is needed to forward one port only.这仅用于转发一个端口。

  • 127.0.0.1 should be passed as rmi server hostname. 127.0.0.1 应该作为 rmi 服务器主机名传递。 This is needed for JMX connection to work via port-forwarding.这是 JMX 连接通过端口转发工作所必需的。

2). 2)。 Forward the JMX port (1099) to your local PC via kubectl:通过 kubectl 将 JMX 端口 (1099) 转发到您的本地 PC:

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

3). 3)。 Open jconsole connection to your local port 1099:打开与本地端口 1099 的 jconsole 连接:

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).这种方式使得通过 JMX 调试任何 Java pod 成为可能,而无需通过 K8 服务公开暴露 JMX(从安全角度来看更好)。

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.另一个可能有用的选项是将 Jolokia ( https://jolokia.org/ ) 代理附加到容器内的 Java 进程,以便它通过 HTTP 端口代理 JMX 并公开或端口转发此 HTTP 端口以查询 JMX通过 HTTP。

We did it in following way我们按照以下方式做到了

  1. Add a unique label for each pod.为每个 pod 添加一个唯一的标签。 ex: podid=asdw23443例如:podid=asdw23443
  2. Create a new service with selector of podid=asdw23443.使用 podid=asdw23443 选择器创建一个新服务。 Make sure in the service you expose jmx ports on pod through nodeport or loadbalancer.确保在服务中通过 nodeport 或负载均衡器在 pod 上公开 jmx 端口。

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如果您在服务中选择 nodeport,因为您正在执行 NAT 操作,您可能必须为需要通过 jconsole 连接的每个 jvm 提供以下 JVM 参数

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

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.添加到https://stackoverflow.com/a/39927197/1387184 ,我想一次监视同一个 pod 的所有实例,因为我们将端口硬编码为 1099,这很困难,因为我只能将一个端口转发到一个带有该端口的吊舱。

I used Shell Script to dynamically assign pod when running the docker我在运行 docker 时使用 Shell Script 动态分配 pod

Dockerfile CMD /run.sh 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" 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. eval 会将 JMX_PORT 评估为 bash 值,每个 pod 在启动时可能会得到不同的 pod。 I一世

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.我认为一种方法是使用唯一的字符串 \\ id 为您的 pod 添加一个标签,例如 pod_name 并使用暴露命令使用此唯一 id\\string 的选择器创建一个新服务。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM