Kubernetes JVM监控基于灵活的Logtail Kubernetes能力,通过自动发现等手段,为Kubernetes中所有基于JVM运行的服务提供灵活且一站式的JVM指标采集方案。

前提条件

  • 已创建实例。具体操作,请参见创建实例
  • 已安装监。具体操作,请参见安装监控组件
    说明 需要通过全栈监控Kubernetes组件安装特殊版Logtail镜像,Logtail镜像Tag需为v1.2.2.0-monitor-aliyun及以上版本。

采集原理

Java Management Extensions(JMX)技术是Java SE平台的标准功能,主要用于监控和管理Java应用的运行状态、资源信息、JVM虚拟机运行情况等信息。JMX支持通过Remote RMI方式进行暴露,类似于一个Prometheus Exporter。与通过Javaagent集成数据相比,通过RMI接口读取指标更安全、集成成本更低。

在Kubernetes中,JVM指标采集的部署模型与日志采集组件部署模型相同,都为Daemonset。依托于日志采集组件多维度Kubernetes资源选择能力,采集JVM监控数据时,也支持通过环境变量、Kubernetes Labels、Namespace、Pod名称、容器名称过滤数据。更多信息,请参见日志采集组件多维度Kubernetes资源选择能力但不同的是由于RMI涉及Java进程之间的通信,Kubernetes资源选择可能命中大量非相关进程,Logtail增加了一个特殊的环境变量ILOGTAIL_JMX_PORT进行进一步精确限定目标选择范围。

JVM监控

准备工作

针对部署于Kubernetes中的Java应用,如果您要通过Logtail自动采集JVM监控数据,需要先完成如下3个操作。

  1. 在环境变量中增加POD_IP声明。
    配置示例如下:
                - name: POD_IP
                  valueFrom:
                    fieldRef:
                      fieldPath: status.podIP
  2. 设置JVM启动参数。
    设置com.sun.management.jmxremote参数,用于开启JMX远程访问。
    • 设置com.sun.management.jmxremote.local.only参数为false。
    • 设置com.sun.management.jmxremote.ssl参数和com.sun.management.jmxremote.authenticate参数为false,否则在接入配置中需设置JMX密码
    • 设置com.sun.management.jmxremote.port参数和com.sun.management.jmxremote.rmi.port参数为声明的RMI访问端口。
    • 设置java.rmi.server.hostname参数为环境变量POD_IP的值。
       -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=9999
        -Dcom.sun.management.jmxremote.rmi.port=9999
        -Djava.rmi.server.hostname=$(POD_IP)
  3. 在环境变量中增加ILOGTAIL_JMX_PORT声明,值为具体暴露的指标端口,即com.sun.management.jmxremote.port参数值。
完成上述配置后,请进入目标Pod,使用jps命令查看具体的JVM启动参数,如下图所示。其中,JAVA_TOOL_OPTIONS=""声明用于避免使用jps程序时附带环境变量JAVA_TOOL_OPTIONS,产生端口冲突。JVM监控

操作步骤

  1. 登录日志服务控制台
  2. 日志应用区域,单击全栈监控
  3. SLS全栈监控页面,单击目标实例。
  4. 数据接入页面,选择Kubernetes JVM监控。

    首次创建目标监控项的接入配置时,打开创建开关,可进入配置页面。如果您已创建过接入配置,则单击创建图标,可进入配置页面。

  5. 单击使用现有机器组
    安装监控组件后,日志服务自动创建名为{instanceID}-{clusterID}-k8s-nodes的机器组,您可以直接使用该机器组。
  6. 选中目标机器组({instanceID}-{clusterID}-k8s-nodes),将该机器组从源机器组移动到应用机器组,单击下一步
    重要 如果机器组心跳为FAIL,您可单击自动重试。如果还未解决,请参见Logtail机器组无心跳进行排查。
  7. 数据源设置配置向导中,配置如下参数,然后单击完成

    设置完成后,日志服务将自动生成Metricstore等资产。更多信息,请参见资产说明

    参数说明
    一般配置
    配置名称自定义设置Logtail采集配置的名称。
    集群自定义设置Kubernetes集群的名称。

    设置该参数后,日志服务会为通过该Logtail采集配置采集到的Kubernetes JVM监控数据添加cluster=集群名称的标签。

    重要 请确保该集群名称唯一,否则可能出现数据冲突。
    Jmx用户名JMX访问用户名。

    在Kubernetes场景中,建议不设置。

    JMX密码JMX访问密码。

    在Kubernetes场景中,建议不设置。

    全局标签为采集到的Kubernetes JVM监控数据添加自定义标签,该标签为键值对形式。

    设置该参数后,日志服务会为通过该Logtail采集配置采集到的Kubernetes JVM监控数据添加标签。

    K8s选择器配置
    Namespace输入匹配Namespace名称的正则表达式,用于指定待采集的命名空间。
    Pod名称输入匹配Pod名称的正则表达式,用于指定待采集的Pod。
    容器名称输入匹配容器名称的正则表达式,用于指定待采集的容器。
    环境变量白名单环境变量白名单,用于指定待采集的容器。默认为空,表示采集所有容器的标准输出。如果您要设置环境变量白名单,那么EnvKey必填,EnvValue可选填。
    • 如果EnvValue为空,则容器环境变量中包含EnvKey的容器都匹配。
    • 如果EnvValue不为空,则容器环境变量中包含EnvKey=EnvValue的容器才匹配。

      EnvValue默认为字符串匹配,即只有EnvValue和环境变量的值完全相同才会匹配。如果该值以^开头并且以$结尾,则为正则匹配,例如:设置EnvKeyNGINX_SERVICE_PORT,设置EnvValue^(80|6379)$,表示可匹配服务端口为80、6379的容器。

    多个白名单之间为或关系,即只要容器的环境变量满足任一键值对即可被匹配。

    环境变量黑名单环境变量黑名单,用于排除不采集的容器。默认为空,表示不排除任何容器。如果您要设置环境变量黑名单,那么EnvKey必填,EnvValue可选填。
    • 如果EnvValue为空,则容器环境变量中包含EnvKey的容器的日志都将被排除。
    • 如果EnvValue不为空,则容器环境变量中包含EnvKey=EnvValue的容器才会被排除。

      EnvValue默认为字符串匹配,即只有EnvValue和环境变量的值完全相同才会匹配。如果该值以^开头并且以$结尾,则为正则匹配,例如:设置EnvKeyNGINX_SERVICE_PORT,设置EnvValue^(80|6379)$,表示可匹配服务端口为80、6379的容器。

    多个黑名单之间为或关系,即只要容器的环境变量满足任一键值对即可被排除。

    K8s Label白名单通过Kubernetes Label白名单指定待采集的容器。如果您要设置Kubernetes Label白名单,那么LabelKey必填,LabelValue可选填。
    • 如果LabelValue为空,则Kubernetes Label中包含LabelKey的容器都匹配。
    • 如果LabelValue不为空,则Kubernetes Label中包含LabelKey=LabelValue的容器才匹配。

      LabelValue默认为字符串匹配,即只有LabelValue和Kubernetes Label的值完全相同才会匹配。如果该值以^开头并且以$结尾,则为正则匹配。例如设置LabelKeyapp,设置LabelValue^(test1|test2)$,表示匹配Kubernetes Label中包含app:test1、app:test2的容器。

    多个白名单之间为或关系,即只要Kubernetes Label满足任一白名单即可被匹配。

    K8s Label黑名单通过Kubernetes Label黑名单排除不采集的容器。如果您要设置Kubernetes Label黑名单,那么LabelKey必填,LabelValue可选填。
    • 如果LabelValue为空,则Kubernetes Label中包含LabelKey的容器都被排除。
    • 如果LabelValue不为空,则Kubernetes Label中包含LabelKey=LabelValue的容器才会被排除。

      LabelValue默认为字符串匹配,即只有LabelValue和Kubernetes Label的值完全相同才会匹配。如果该值以^开头并且以$结尾,则为正则匹配。例如设置LabelKeyapp,设置LabelValue^(test1|test2)$,表示匹配Kubernetes Label中包含app:test1、app:test2的容器。

    多个黑名单之间为或关系,即只要Kubernetes Label满足任一黑名单对即可被排除。

    容器Label白名单容器Label白名单,用于指定待采集的容器。默认为空,表示采集所有容器的标准输出。如果您要设置容器Label白名单,那么LabelKey必填,LabelValue可选填。
    • 如果LabelValue为空,则容器Label中包含LabelKey的容器都匹配。
    • 如果LabelValue不为空,则容器Label中包含LabelKey=LabelValue的容器才匹配。

      LabelValue默认为字符串匹配,即只有LabelValue和容器Label的值完全相同才会匹配。如果该值以^开头并且以$结尾,则为正则匹配。例如:配置LabelKeyio.kubernetes.container.name,配置LabelValue^(nginx|cube)$,表示可匹配名为nginx、cube的容器。

    多个白名单之间为或关系,即只要容器Label满足任一白名单即可被匹配。

    容器Label黑名单容器Label黑名单,用于排除不采集的容器。默认为空,表示不排除任何容器。如果您要设置容器Label黑名单,那么LabelKey必填,LabelValue可选填。
    • 如果LabelValue为空,则容器Label中包含LabelKey的容器都将被排除。
    • 如果LabelValue不为空,则容器Label中包含LabelKey=LabelValue的容器才会被排除。

      LabelValue默认为字符串匹配,即只有LabelValue和容器Label的值完全相同才会匹配。如果该值以^开头并且以$结尾,则为正则匹配。例如:设置LabelKeyio.kubernetes.container.name,设置LabelValue^(nginx|cube)$,表示可匹配名为nginx、cube的容器。

    多个黑名单之间为或关系,即只要容器Label满足任一黑名单对即可被排除。

    高级配置
    K8s Label附带采集设置Kubernetes Label标签后,日志服务将在采集到的JVM监控数据中添加Kubernetes Label相关字段。

    例如设置Label名称为app,Label别名为k8s_label_app,当Kubernetes中包含名为app的Label(例如app=serviceA)时,日志服务将在JVM监控数据添加字段k8s_label_app: serviceA

    环境变量附带采集设置环境变量标签后,日志服务将在采集到的JVM监控数据中添加环境变量相关字段。

    例如设置环境变量名称为VERSION,环境变量别名为env_version,当容器中包含名为VERSION的环境变量(例如VERSION=v1.0.0)时,日志服务将在JVM监控数据添加字段env_version: v1.0.0

    新版垃圾收集器JMX模式打开开关后,支持兼容G1等新版垃圾收集器。
    默认JVM指标打开开关后,Logtail将采集预定义的核心JVM指标。
    JMX采集范围过滤器支持通过JMX Bean范围、JMX Bean正则、JMX Bean类型以及采集JMX属性范围进行采集过滤。

接入案例

例如在名为default的命名空间下启动SpringBoot Demo服务,然后通过环境变量ILOGTAIL_JMX_PORT声明暴露9999端口,在环境变量JAVA_TOOL_OPTIONS中添加针对9999端口暴露JMX指标的JVM启动参数。
说明 使用环境变量JAVA_TOOL_OPTIONS引用环境变量POD_IP时,需要先定义环境变量POD_IP
apiVersion: apps/v1
kind: Deployment
metadata:
  name: jvm-new-1
  namespace: default
spec:
...
  template:
    metadata:
      labels:
        app: jvm1
    spec:
      containers:
        - image: evanljp/full-stack:jvm-new-0.1
          name: jvm
          env:
            - name: "ILOGTAIL_JMX_PORT"
              value: "9999"
            - name: "ILOGTAIL_JMX_TAGS"
              value: "a=b,c=d"
            - name: POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: JAVA_TOOL_OPTIONS
              value: >-
                -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=9999
                -Dcom.sun.management.jmxremote.rmi.port=9999
                -Djava.rmi.server.hostname=$(POD_IP)
                -Dserver.port=8081
          ...
​

基于上述声明,您只需在接入配置中完成如下配置,即可接入Kubernetes JVM监控数据到服务。

JVM监控

后续步骤

接入Kubernetes JVM监控数据后,全栈监控应用会自动生成专属仪表盘。您可以通过仪表盘分析监控数据。更多信息,请参见查看仪表盘