《Kubernetes监控篇:Kubernetes集群之微服务JVM内存监控》

文章目录

  • 一、背景信息
  • 二、监控方案
  • 三、部署架构
  • 四、部署操作
    • 4.1、资源下载
    • 4.2、修改Dockerfile
    • 4.3、修改yaml文件
    • 4.4、部署prometheus
      • 4.4.1、配置yaml文件
      • 4.4.2、配置文件详解
      • 4.4.3、部署prometheus服务
      • 4.4.3、检查prometheus服务
    • 4.5、部署alertmanager服务
    • 4.6、grafana部署配置
      • 4.6.1、grafana模板下载
      • 4.6.2、grafana导入数据源
      • 4.6.3、grafana模板导入
    • 4.7、grafana效果展示
    • 4.8、钉钉告警信息展示
  • 总结:整理不易,如果对你有帮助,可否点赞关注一下?


一、背景信息

复杂和高并发下的服务,必须保证每次gc不会出现性能下降,各种性能指标不会出现波动,gc回收规律而且干净,所以必须找到合适的jvm设置。而要找到合适的jvm设置,必须要了解当前java服务的jvm使用情况。所以我觉得非常有必要对java服务的jvm使用情况实时监控。

业务系统涉及到的java服务分为:tomcat类型、jar包类型、k8s微服务类型。


二、监控方案

方案一:业务系统java服务采用的是SpringBoot框架,SpringBoot自带监控功能Actuator,可以帮助实现对程序内部运行情况监控,比如监控状况、Bean加载情况、环境变量、日志信息、线程信息、健康检查、审计、统计和HTTP追踪等。Actuator同时还可以与外部应用监控系统整合,比如Prometheus,可以选择使用HTTP端点或JMX来管理和监视应用程序。

方案二:通过JMX Exporter来暴露 Java 应用的JVM监控指标,JMX Exporter有两种用法。

# 方法一:启动独立进程
JVM启动时指定参数,暴露JMX的RMI接口,JMX-Exporter调用RMI获取JVM运行时状态数据,
转换为Prometheus metrics格式,并暴露端口让Prometheus采集。

# 方法二:JVM进程内启动(in-process)
JVM启动时指定参数,通过javaagent 的形式运行JMX-Exporter 的jar包,
进程内读取JVM运行时状态数据,转换为Prometheus metrics格式,并暴露端口让Prometheus采集。

说明:官方不推荐使用第一种方式,一方面配置复杂,另一方面因为它需要一个单独的进程,而这个进程本身的监控又成了新的问题,所以本文重点围绕第二种用法讲如何在K8S 环境下使用JMX Exporter暴露JVM监控指标。


三、部署架构

1、监控系统架构图
《Kubernetes监控篇:Kubernetes集群之微服务JVM内存监控》_第1张图片
2、监控系统说明
由于kubernetes集群中有多个业务系统,分别部署在不同的namespace空间,针对不同的监控类型数据,如主机资源监控数据、容器监控数据、应用程序监控数据,分别采用不同的prometheus来采集数据。


四、部署操作

4.1、资源下载

jmx_prometheus_javaagent-0.16.1.jar和prometheus-jmx-config.yaml
《Kubernetes监控篇:Kubernetes集群之微服务JVM内存监控》_第2张图片


4.2、修改Dockerfile

# 修改前
FROM java:8u111-jdk
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    echo 'Asia/Shanghai' >/etc/timezone
ADD mpmt-cp-adapter.jar adapter.jar
EXPOSE 8083
ENTRYPOINT ["java","-Xmx2048m","-Xms512m","-XX:MaxMetaspaceSize=512m","-XX:MetaspaceSize=256m","-Djava.security.egd=file:/dev/./urandom","-jar","/adapter.jar","--spring.profiles.active=test"]

# 修改后
FROM java:8u111-jdk
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    echo 'Asia/Shanghai' >/etc/timezone
ADD mpmt-cp-adapter.jar adapter.jar
ADD prometheus-jmx-config.yaml /prometheus-jmx-config.yaml
ADD jmx_prometheus_javaagent-0.16.1.jar /jmx_prometheus_javaagent-0.16.1.jar
EXPOSE 8083
EXPOSE 7070
ENTRYPOINT ["java","-javaagent:/jmx_prometheus_javaagent-0.16.1.jar=7070:prometheus-jmx-config.yaml","-Xmx2048m","-Xms512m","-XX:MaxMetaspaceSize=512m","-XX:MetaspaceSize=256m","-Djava.security.egd=file:/dev/./urandom","-jar","/adapter.jar","--spring.profiles.active=test"]

4.3、修改yaml文件

# 修改前
---
apiVersion: v1
kind: Service
metadata:
  name: mpmt-adapter-svc
  labels:
    app: mpmt-adapter
spec:
  type: NodePort
  ports:
  - port: 8083
    targetPort: 8083
    protocol: TCP
    nodePort: 31087
  selector:
    app: mpmt-adapter
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mpmt-adapter

spec:
  serviceName: "mpmt-adapter"
  podManagementPolicy: Parallel    
  replicas: 1
  updateStrategy:
    type: RollingUpdate
  selector:
    matchLabels:
      app: mpmt-adapter
  template:
    metadata:
      labels:
        app: mpmt-adapter
    spec:
      containers:
      - name: mpmt-adapter
        image: server.harbor.com:8888/library/mpmt-adapter:202107191029
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8083
        resources:
          requests:
            cpu: "500m"
            memory: "4Gi"
          limits:
            cpu: "1000m"
            memory: "6Gi"

# 修改后
---
apiVersion: v1
kind: Service
metadata:
  name: mpmt-adapter-svc
  labels:
    app: mpmt-adapter 
    system: pasz #增加内容
    owner: sdjw #增加内容
    env: test #增加内容
spec:
  type: NodePort
  ports:
  - port: 8083
    targetPort: 8083
    protocol: TCP
    nodePort: 31087
  selector:
    app: mpmt-adapter
    system: pasz #增加内容
    owner: sdjw #增加内容
    env: test #增加内容
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mpmt-adapter
spec:
  serviceName: "mpmt-adapter"
  podManagementPolicy: Parallel
  updateStrategy:
    type: RollingUpdate
  selector:
    matchLabels:
      app: mpmt-adapter
      system: pasz #增加内容
      owner: sdjw #增加内容
      env: test #增加内容
  template:
    metadata:
      labels:
        app: mpmt-adapter
        system: pasz #增加内容
        owner: sdjw #增加内容
        env: test  #增加内容       
    spec:
      containers:
      - name: mpmt-adapter
        image: server.harbor.com:8888/library/mpmt-adapter:202107191029
        imagePullPolicy: IfNotPresent
        ports:
          - containerPort: 8083
            name: jdk #增加内容
          - containerPort: 7070
            name: jvm #增加内容
        resources:
          requests:
            cpu: "500m"
            memory: "4Gi"
          limits:
            cpu: "1000m"
            memory: "6Gi"

问题一:为什么需要添加lables标签?
1、在不同的namespace空间下,部署着不同的业务系统,同时将不同业务系统的监控数据通过grafana展示,那如果对服务进行细化区分会不会更好呢?比如说同样的monitor服务,不同namespace空间下都有,如果加上多种标签,系统名称、系统属主、系统环境等等,这样在告警时,是不是就能更好的知道当前什么系统、是哪家客户的,是生产环境还是测试环境以及什么服务出现了问题呢,这样就可以快速响应并处理问题。

效果如下图所示:
《Kubernetes监控篇:Kubernetes集群之微服务JVM内存监控》_第3张图片
2、添加lables标签还有一个目的就是实现告警分组,试想一下如果k8s集群中有多种业务系统,如A、B系统,A系统的告警信息发送到A系统告警钉钉群,B系统的告警信息发送到B系统告警钉钉群,这样A系统告警钉钉群成员就可以收到负责业务的告警信息,B系统告警钉钉群就不会收到。在企业中,告警分组也是常见的需求。

以下是alertmanager的配置文件,效果如下图所示:
《Kubernetes监控篇:Kubernetes集群之微服务JVM内存监控》_第4张图片
问题二:为什么需要对容器端口增加name标签?
2、对pod中多个容器端口进行name设置,如果上面jdk和name,jdk表示微服务容器业务端口名称,jvm是jvm进程监控端口名称,这里所有业务系统中所有的服务的jvm进程监控端口都未7070,并且name值均为jvm。设置不同的name名称是为了在prometheus.yaml文件中精准匹配jvm进程端口。


4.4、部署prometheus

4.4.1、配置yaml文件

# 在master节点
mkdir -p /data/pkgs/jvm_exporter
vim prometheus.yaml
CSDN下载地址:https://download.csdn.net/download/m0_37814112/20480830

4.4.2、配置文件详解

问题一:如何重写变量名称?
《Kubernetes监控篇:Kubernetes集群之微服务JVM内存监控》_第5张图片
说明:__meta_kubernetes_pod_host_ip、__meta_kubernetes_pod_container_port_name、__meta_kubernetes_namespace、__meta_kubernetes_pod_name、__meta_kubernetes_pod_node_name、__meta_kubernetes_pod_phase、__meta_kubernetes_pod_ready、__meta_kubernetes_pod_label_system、__meta_kubernetes_pod_label_owner、__meta_kubernetes_pod_label_env等这些变量是kubernetes自带的原生标签名称。通过action: replace,可替换__meta_kubernetes_namespace变成kubernetes_namespace,其它依次类推。

原生标签,如下图所示:
《Kubernetes监控篇:Kubernetes集群之微服务JVM内存监控》_第6张图片
重新替换标签后,效果如下图所示:
《Kubernetes监控篇:Kubernetes集群之微服务JVM内存监控》_第7张图片
问题二:如何新增标签?
说明:__meta_kubernetes_pod_label_app、__meta_kubernetes_pod_label_system、__meta_kubernetes_pod_label_owner、__meta_kubernetes_pod_label_env等这些标签不是kubernetes自带的原生标签,而是在微服务yaml文件里定义的,通过kubernetes转换成的。
《Kubernetes监控篇:Kubernetes集群之微服务JVM内存监控》_第8张图片


4.4.3、部署prometheus服务

# 1、根据yaml文件定义的prometheus服务部署在k8s-worker-112节点上,在该节点上创建数据存储目录
[root@k8s-worker-112 ~]# mkdir -pv /data/basic-data/prometheus

# 2、在k8s-master-111节点上执行
# 把default账号通过clusterrolebing绑定到clusterrole上
kubectl create clusterrolebinding nfs-clusterrolebinding -n default --clusterrole=cluster-admin  --user=system:serviceaccount:default:default
# 注意:nfs-clusterrolebinding可自定义设置

# 3、在k8s-master-111节点上执行
[root@k8s-master-111 ~]# cd /data/pkgs/jvm_exporter
[root@k8s-master-111 ~]# kubectl create -f prometheus.yaml

# 4、查看pod状态(如下图所示)
[root@k8s-master-111 ~]# kubectl get pods
NAME                                 READY   STATUS    RESTARTS   AGE
prometheus-server-54dd9f5568-wc44l   1/1     Running   0          8

4.4.3、检查prometheus服务

1、检查rules规则是否生效,如下图所示:
《Kubernetes监控篇:Kubernetes集群之微服务JVM内存监控》_第9张图片
2、检查目标target是否为up,如下图所示:
《Kubernetes监控篇:Kubernetes集群之微服务JVM内存监控》_第10张图片


4.5、部署alertmanager服务

《八、企业级监控系统之实现多节点Altermanager告警分组》


4.6、grafana部署配置

说明:这里默认grafana是已经安装了的,如果需要安装请参考《一、企业级监控之使用docker容器化部署grafana》

4.6.1、grafana模板下载

JVM监控模板

4.6.2、grafana导入数据源

说明:这里就不介绍了。

4.6.3、grafana模板导入

说明:这里就不介绍了。

4.7、grafana效果展示

效果如下图所示:
《Kubernetes监控篇:Kubernetes集群之微服务JVM内存监控》_第11张图片
《Kubernetes监控篇:Kubernetes集群之微服务JVM内存监控》_第12张图片

4.8、钉钉告警信息展示

效果如下图所示:
《Kubernetes监控篇:Kubernetes集群之微服务JVM内存监控》_第13张图片


总结:整理不易,如果对你有帮助,可否点赞关注一下?

更多详细内容请参考:企业级K8s集群运维实战

你可能感兴趣的:(《企业级K8s集群运维实战》,linux,devops,运维,centos,docker)