【问题标题】:multiple app nodes how to expose jmx in kubernetes?多个应用程序节点如何在 kubernetes 中公开 jmx?
【发布时间】:2016-05-13 02:14:14
【问题描述】:
  1. kubernetes 中,我可以使用service 公开服务。这很好。
  2. 假设我有 1 个 Web 实例和 10 个 Java 服务器实例。
  3. 我有一个 windows 网关,用于通过安装在其上的 jconsole 访问这 10 个 java 服务器实例。
  4. 显然我不会通过 kubernetes 服务公开所有应用的 jmx 端口。

我在这里有什么选择?我应该如何允许 kubernetes 集群 Windows 网关外部访问这 10 个服务器 jmx 端口?这里有什么做法吗?

【问题讨论】:

    标签: docker kubernetes kubernetes-service


    【解决方案1】:

    添加到https://stackoverflow.com/a/39927197/1387184,我想同时监控同一个 pod 的所有实例,因为我们将端口硬编码为 1099,这很困难,因为我只能对具有该端口的一个 pod 进行一次端口转发。

    我在运行docker时使用Shell Script动态分配pod

    Dockerfile CMD /run.sh

    运行.sh

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

    echo "Running JMX on Port $JMX_PORT"

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

    部署.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。我

    【讨论】:

      【解决方案2】:

      另一个选项是使用 kubectl port-forward 将 JMX 端口从 K8 pod 转发到本地 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)。打开与本地端口 1099 的 jconsole 连接:

      jconsole 127.0.0.1:1099
      

      这种方式可以通过 JMX 调试任何 Java pod,而无需通过 K8 服务公开 JMX(从安全角度来看这更好)。

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

      【讨论】:

      • 这是我遇到过的最直接的解释,而且效果很好。谢谢!
      • 谢谢!大帮助
      • 设置 -Djava.rmi.server.hostname=127.0.0.1 对我们有用。
      • 我欠你一杯咖啡!
      • 如何从远程主机连接到这个 jmx 服务器?
      【解决方案3】:

      我认为一种方法是为您的 pod 添加一个带有唯一字符串 \id 的标签,例如 pod_name,然后使用 Expose 命令创建一个具有此唯一 id\string 选择器的新服务。

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

      【讨论】:

        【解决方案4】:

        我们是通过以下方式做到的

        1. 为每个 pod 添加一个唯一标签。例如:podid=asdw23443
        2. 使用选择器 podid=asdw23443 创建新服务。确保在服务中通过 nodeport 或负载均衡器在 pod 上公开 jmx 端口。

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

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

        【讨论】:

        • 我不确定我是否明白您是否为每个 pod 实例都有一个 podid?因此,如果您将其从 10 扩展到 20,那么您可以在没有负载均衡器的情况下访问每个 pod 实例?我想访问特定的 pod 实例。
        • 我不确定我是否明白您是否为每个 pod 实例都有一个 podid?所以如果你把它从 10 个扩展到 1000 个,那么你就有 1000 个服务?
        • 是的,在这种方法中,您必须为每个 pod 创建一个服务。如果你有 1000 个 pod,那么应该有 1000 个服务。
        • 我正在努力解决的一件事:当我不提前知道 Pod 将被安排到哪个工作人员时,如何将 JVM arg 设置为运行进程的 IP 地址?
        猜你喜欢
        • 2022-01-02
        • 2021-06-05
        • 2019-02-20
        • 1970-01-01
        • 2018-12-26
        • 2016-09-23
        • 2020-03-09
        • 1970-01-01
        • 2020-06-11
        相关资源
        最近更新 更多