在Kubernetes上使用VisualVM(JMX连接)

首先

我打算在运行在k8s上的Java应用程序中使用VisualVM进行连接。
我认为在监视和分析Java应用程序时使用。
由于是容器,所以通常使用Prometheus进行指标收集,但这次我们将使用Java开发人员熟悉的工具,即在Java端准备的工具。

※本次实施时没有准备Java应用程序,而是针对Jenkins容器进行操作
※可以使用Prometheus对JMX和Jenkins进行度量收集

环境信息

Kubernetes:1.18
helm:v3.2
※https://helm.sh/docs/intro/quickstart/
Java:1.8
Jenkins:2.235

Kubernetes:1.18
helm:v3.2
※https://helm.sh/docs/intro/quickstart/
Java:1.8
Jenkins:2.235

准备 Jenkins 容器

使用Helm部署Jenkins容器。

首先,我们将创建一个用于部署的参数文件。
※使用NodePort连接到Pod
※这次我们将使用端口号32000进行jmx连接
※在hostname中指定的IP地址是k8s的worker节点的IP地址。您可以通过以下命令进行确认。

$ kubectl get nodes --namespace jenkins -o jsonpath="{.items[0].status.addresses[0].address}"
master:
  serviceType: NodePort
  javaOpts: >
    -Djava.rmi.server.hostname=0.0.0.0
    -Dcom.sun.management.jmxremote=true
    -Dcom.sun.management.jmxremote.port=32000
    -Dcom.Sun.management.jmxremote.local.only=false
    -Dcom.sun.management.jmxremote.rmi.port=32000
    -Dcom.sun.management.jmxremote.ssl=false
    -Dcom.sun.management.jmxremote.authenticate=false
    -Djava.rmi.server.hostname=192.168.10.51
  jmxPort: 32000

同样,我们将创建一个用于 JMX 访问的 Service 定义的 yaml 文件。

apiVersion: v1
kind: Service
metadata:
  name: jenkins-jmx
  namespace: jenkins
spec:
  ports:
  - name: jmx
    nodePort: 32000
    port: 32000
    protocol: TCP
    targetPort: 32000
  selector:
    app.kubernetes.io/component: jenkins-master
    app.kubernetes.io/instance: jenkins
  type: NodePort

我会立即部署。
※您可以使用helm pull stable/jenkins命令下载helm所需的全部文件。

# jenkins namespace 作成
$ kc create ns jenkins

# k8s 接続設定(context)確認
$ kc config current-context
sandbox

# k8s 接続設定(context)の namespace 設定
$ kc config set-context sandbox --namespace jenkins

# k8s 接続先 namespace 確認
$ kc config get-contexts
CURRENT   NAME                CLUSTER             AUTHINFO   NAMESPACE
*         sandbox             sandbox             sandbox    jenkins

# helm repository 追加・レポジトリ情報アップデート
$ helm repo add stable https://kubernetes-charts.storage.googleapis.com
"stable" has been added to your repositories

$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "stable" chart repository
Update Complete. ? Happy Helming!?

# Jenkins コンテナデプロイ
# helm install <リリース名> <Chart 名> -f <parameter file> --namespace <デプロイ先 namespace>
# リリース名:デプロイに対する helm での管理上の名前
# Chart 名:利用するテンプレート名的なもの
$ helm install jenkins stable/jenkins -f values.yaml --namespace jenkins
NAME: jenkins
LAST DEPLOYED: Sat Jul 25 hh:mm:ss 2020
NAMESPACE: jenkins
STATUS: deployed
REVISION: 1
NOTES:
1. Get your 'admin' user password by running:
  printf $(kubectl get secret --namespace jenkins jenkins -o jsonpath="{.data.jenkins-admin-password}" | base64 --decode);echo
2. Get the Jenkins URL to visit by running these commands in the same shell:
  export NODE_PORT=$(kubectl get --namespace jenkins -o jsonpath="{.spec.ports[0].nodePort}" services jenkins)
  export NODE_IP=$(kubectl get nodes --namespace jenkins -o jsonpath="{.items[0].status.addresses[0].address}")
  echo http://$NODE_IP:$NODE_PORT/login

3. Login with the password from step 1 and the username: admin
・・・

# デプロイの確認
$ helm list
NAME    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART         APP VERSION
jenkins jenkins         1               2020-MM-DD hh:mm:ss.950509962 +0900 JST deployed        jenkins-2.4.1 lts

由于helm创建的容器中没有JMX连接服务的定义,因此需要单独部署服务。

$ kubectl get svc
NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
jenkins         NodePort    10.43.173.89   <none>        8080:31036/TCP   12m
jenkins-agent   ClusterIP   10.43.130.60   <none>        50000/TCP        12m

$ kubectl apply -f svc.yaml
service/jenkins-jmx created

# kubectl get svc
NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)           AGE
jenkins         NodePort    10.43.173.89   <none>        8080:31036/TCP    12m
jenkins-agent   ClusterIP   10.43.130.60   <none>        50000/TCP         12m
jenkins-jmx     NodePort    10.43.97.82    <none>        32000:32000/TCP   19s

用Java VisualVM进行连接。

现在,我们将连接到已启动的 Jenkins 容器。
启动 Java VisualVM,并连接到 Jenkins 容器。
尽管它也包含在JDK中,但这次我们将使用附带在 Pleiades(all in one eclipse)中的版本为1.8的 Java VisualVM 进行连接。
https://mergedoc.osdn.jp/

※请解压缩后使用 Java\8\bin\jvisualvm.exe 运行。

image.png
    1. 在左侧菜单上右键点击“远程”,然后点击“添加远程主机”

 

    1. 在“主机名”处输入使用javaOpts指定的主机名(IP地址),然后点击“确认”

 

    1. 确认在左侧菜单上添加了远程机器

 

    1. 在左侧菜单上右键点击注册的机器,然后点击“添加JMX连接”

 

    1. 在“连接”中已经输入了主机名,接着输入冒号后面的端口号(本例中为32000)

 

    1. 勾选“不使用SSL连接”,然后点击“确认”

 

    1. 确认在左侧菜单注册的远程机器下添加了连接

 

    双击添加的连接,确认信息显示在主页面上

连接后的界面

image.png

监视标签

image.png

线程标签

image.png

而且如果通过jconsole连接,情况如下所示。
※ jconsole和VisualVM的二进制文件位于同一个文件夹中
※ 连接目标与在VisualVM中设置的连接目标相同

image.png

总结。

我們試著在運行在k8s上的容器中連接VisualVM和jconsole的方法。由於無法使用常見的開啟端口連接的方法,因此我們添加以下設定進行連接。

    • java の起動オプション(javaOpts)に hostname を追加し、Worker ノードの IP アドレスを設定

 

    jmx で接続するポートと Nodeport で開放するポートを同じ値にする

请参考使用您熟悉的工具进行连接,而不是使用Prometheus。

bannerAds