1.部署说明
JMX Exporter 的两种用法
JMX-Exporter 提供了两种用法:
1.启动独立进程.JVM启动时指定参数,暴露JMX的RMI接口,JMX-Exporter调用RMI获取JVM运行时状态数据,转换为Prometheus metrics格式,并暴露端口让Prometheus采集.
2.JVM进程内启动.JVM启动时指定参数,通过javaagent的形式运行JMX-Exporter的jar包,进程内读取JVM运行时状态数据,转换为Prometheus metrics格式,并暴露端口让Prometheus采集。
官方不推荐使用第一种方式,一方面配置复杂,另一方面因为它需要一个单独的进程.
本次介绍的是第二种方法
添加jmx_exporter.yaml配置文件
---
lowercaseOutputLabelNames: true
lowercaseOutputName: true
# whitelistObjectNames: ["java.lang:type=OperatingSystem"]
ssl: false
# rules:
# - pattern: 'java.lang<type=OperatingSystem><>((?!process_cpu_time)\w+):'
# name: os_$1
# type: GAUGE
# attrNameSnakeCase: true
下载jmx_exporter的jar包
地址: https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/
选择时间比较近的
![](https://img-blog.csdnimg.cn/img_convert/6ad50b83799e2dbe847189b25648d6a4.png)
wget https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.17.2/jmx_prometheus_javaagent-0.17.2.jar
修改Jar打包镜像的配置
.
.
.
JMX_OPS = " -javaagent:/data2/${PROJECT_NAME}/jmx/jmx_prometheus_javaagent-0.17.0.jar=8784:/data2/${PROJECT_NAME}/jmx/jmx_exporter.yml"
.
.
.
# Dockerfile文件也要修改
FROM openjdk:17.0.2-jdk
ENV TZ=Asia/Shanghai
RUN useradd -g 33 -u 33 vray && mkdir -p /data2/${PROJECT_NAME}/jmx && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" > /etc/timezone
ADD ${JAR_NAME} /data2/${PROJECT_NAME}/
# 添加jmx_exporter的jar和配置
ADD jmx_prometheus_javaagent-0.17.0.jar /data2/${PROJECT_NAME}/jmx/
ADD jmx_exporter.yml /data2/${PROJECT_NAME}/jmx/
RUN chown -R 33.33 /data2
WORKDIR /data2/${PROJECT_NAME}
USER vray
# 端口暴露
EXPOSE ${JAVA_PORT} 8784
# 添加JMX_OPS
ENTRYPOINT java ${JMX_OPS} ${JAR_OPS} -jar /data2/${PROJECT_NAME}/${JAR_NAME}
修改deployment文件
kind: Deployment
apiVersion: apps/v1
metadata:
.
.
.
spec:
.
.
.
template:
metadata:
annotations:
# promethues通过这个标签动态获取到pod的信息
prometheus.io/scrape: jvm
# prometheus.io/port: 'JAVAPORT'
prometheus.io/port: '8784'
spec:
containers:
- .
env:
.
ports:
- containerPort: JAVAPORT
protocol: TCP
name: apiport
- containerPort: 8784
protocol: TCP
# jvm监控端口
name: jmxport
service也要修改
apiVersion: v1
kind: Service
metadata:
annotations:
prometheus.io/scrape: "true"
labels:
app: PROJECT_NAME
name: PROJECT_NAME
namespace: ENV
spec:
ports:
- name: PROJECT_NAME
port: JAVA_PORT
protocol: TCP
targetPort: JAVA_PORT
- name: jmxport
port: 8784
protocol: TCP
targetPort: 8784
selector:
app: PROJECT_NAME
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 3600
type: ClusterIP
修改Prometheus的配置文件添加JVM的监控项
kubectl -n monitoring edit cm/prometheus-config
# 添加下面配置
#Pod metrics #scrape=jvm
- job_name: 'jmx-exporter'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- action: keep
regex: jvm
source_labels:
- __meta_kubernetes_pod_annotation_prometheus_io_scrape
- action: replace
regex: (.+)
source_labels:
- __meta_kubernetes_pod_annotation_prometheus_io_path
target_label: __metrics_path__
- action: replace
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
source_labels:
- __address__
- __meta_kubernetes_pod_annotation_prometheus_io_port
target_label: __address__
# 匹配你在pod中定义的标签名,比如app: PROJECTNAME-DENV app: bims-meta-yfdev,tke的会默认加上pod-template-hash='XXXXXXXXXXXXX'
- action: labelmap
regex: __meta_kubernetes_pod_label_(.+)
- action: replace
source_labels:
- __meta_kubernetes_namespace
target_label: namespace
- action: replace
source_labels:
- __meta_kubernetes_pod_name
target_label: pod
添加后重启Prometheus的pod
可以查看到Prometheus多了一个监控项
![](https://img-blog.csdnimg.cn/img_convert/5c2f9e63d8b2847597ba925003d291a6.png)
找到对应的Grafana的Dashboard
地址: https://grafana.com/grafana/dashboards/?plcmt=footer
搜索jmx,导入模板后可以看到(这里使用的是11131这个模板)
![](https://img-blog.csdnimg.cn/img_convert/3ca06ce9fb01276f64042f57a4422f6d.png)
![](https://img-blog.csdnimg.cn/img_convert/7db882f4fac667b6f9211e11c0c81a96.png)
注意这里的job和container要对应
实践1:
从上图的中可以看到很多是没有数据的,因为他的数据表达式是:kube_pod_container_resource_limits_cpu_cores{job='kube-state-metrics', container='tomcat', pod="$pod"}
![](https://img-blog.csdnimg.cn/img_convert/5a7348ade4414d767bead4ac9651e84e.png)
这里我的模板是将所有的container赋值为tomcat
![](https://img-blog.csdnimg.cn/img_convert/11c24639689fc50c5ec121a40abea3c8.png)
可以看到我这里的container是不一样的,这时候我就修改为container="${container}",但是还是没有数据,因为这个$container是需要在模板中定义的
![](https://img-blog.csdnimg.cn/img_convert/3b73b5efe6c92a9d906098bd5615fef1.png)
![](https://img-blog.csdnimg.cn/img_convert/50151f5d56160b130bb0a7c688aa04d2.png)
![](https://img-blog.csdnimg.cn/img_convert/98fa565f8bb201137c8c7cf54e70a576.png)
可以看到这个变量需要在这里定义,我们也可以自己添加。
比如我们要自己添加container这个值,可以看到这里是没有container的标签的,跟target中的Labels是一样的
![](https://img-blog.csdnimg.cn/img_convert/7696efe2b2057e4c5a6da29474a961ff.png)
这个是从config中配置的
![](https://img-blog.csdnimg.cn/img_convert/48fc0165f2129f466f80bca1c7c405e8.png)
现在我们添加container的一个标签,因为这个标签是从kubernetes_sd_configs,中pod的所有信息中获取的,可以查看 https://blog.csdn.net/qq_33816243/article/details/126863790
添加后可以看到up后面已经有container这个标签
![](https://img-blog.csdnimg.cn/img_convert/31c80512d2088117b0be53a7c6d2d93d.png)
![](https://img-blog.csdnimg.cn/img_convert/d8a5d2bbc4500b4136a771fe0a0ad220.png)
可以看到up函数也可以查到这个标签,然后就可以在那个模板添加label_values(up{job="jmx-expoter"},container),然后就可以在模板中选择,这时候就可以用kube_pod_container_resource_limits_cpu_cores{job='kube-state-metrics', container="$container", pod="$pod"}
实践2:
关于函数label_join(jvm_info{pod="$pod"}, "jdk", ", ", "vendor", "runtime", "version")
先查询:
![](https://img-blog.csdnimg.cn/img_convert/4307d160d2efc9f8145c974a30738691.png)
![](https://img-blog.csdnimg.cn/img_convert/15ae2afefee55e3691bce878d2164006.png)
注意这里要选择Last这个计算函数,关于Grafana计算函数的使用可以参考 https://blog.csdn.net/m0_56079407/article/details/127780050
最终的图
![](https://img-blog.csdnimg.cn/img_convert/88ba40aa8ee27acb08771d854876e844.png)