- 在
kubernetes
中,我可以使用service
来公开服务。这很好。 - 假设我有1个Web实例和10个Java服务器实例。
- 我有一个Windows网关,我习惯通过其上安装的jconsole访问那10个Java服务器实例。
- 显然,我不会通过kubernetes service公开所有应用程序的jmx端口。
我有哪些选择? 我应该如何使这个外部的kubernetes集群Windows网关能够访问那10个服务器的jmx端口? 有什么最佳实践吗?
kubernetes
中,我可以使用service
来公开服务。这很好。我有哪些选择? 我应该如何使这个外部的kubernetes集群Windows网关能够访问那10个服务器的jmx端口? 有什么最佳实践吗?
另一种选择是使用 kubectl port-forward 将 K8 Pod 的 JMX 端口转发到您的本地 PC。
我是这样做的:
1). 将以下 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
这里的关键在于:
应该使用相同的端口作为 'jmxremote.port' 和 'jmxremote.rmi.port'。这是为了仅转发一个端口。
应该将 127.0.0.1 作为 RMI 服务器主机名传递。这是为了使 JMX 连接通过端口转发工作。
2). 通过 kubectl 将 JMX 端口 (1099) 转发到本地 PC:
kubectl port-forward <your-app-pod> 1099
3). 打开 jconsole 连接到本地端口 1099:
jconsole 127.0.0.1:1099
这种方式使得可以通过JMX调试任何Java Pod,而不必公开暴露JMX通过K8服务(从安全角度来看更好)。
另一个也可能有用的选项是在容器内部将Jolokia代理 (https://jolokia.org/) 添加到Java进程中,以便将JMX代理到HTTP端口并公开或端口转发此HTTP端口以查询JMX over HTTP。
除了 https://dev59.com/x1sW5IYBdhLWcg3wQVb2#39927197 中提到的内容,我想要同时监控同一 Pod 的所有实例,但是由于我们将端口硬编码为 1099,所以只能对一个使用该端口的 pod 进行 portforward,这就很难了。
我使用 Shell 脚本在运行 docker 时动态分配 pod:
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"
eval 将 JMX_PORT 的值作为 bash 值进行评估,每个 pod 启动时都可能会获得不同的 pod。
如果你在服务中选择了nodeport,因为你正在执行NAT操作,你可能需要为每个需要通过jconsole连接的JVM提供以下JVM参数:
-Djava.rmi.server.hostname=<your-ip-address>
我认为一种方法是给你的pod添加一个标签,使用一个唯一的字符串或ID,例如pod_name,并使用expose命令创建一个新的服务,该服务的选择器为这个唯一的ID\字符串。
kubectl label pods <podname> podname=<podname>
kubectl expose pod <podname> --port=9010 --name=<podname>_jmx
-Djava.rmi.server.hostname=127.0.0.1
。 - jitter