所谓应用监控,更多的是基于java jvm的监控,因为公司运行的中间件大部分都是基于tomcat,Springboot,SpringCloud,当然也必须支持WebLogic.在Kubernetes现有方案中,监控那块主要是通过cAdvisor,Heapster的组件获取Pod消耗的memory,CPU和网络的信息,但如果需要更深入的了解Pod中运行的应用的信息就基本没有提供缺省的方案。

那么到底应用监控涉及什么的指标,我整理一下大致包括:

  • JVM Heap
  • JVM Non Heap Memory
  • GC
  • Thread montoring
  • DataSource
  • Transactions Per Seconds
  • Throughput 等等等等。。。

我这篇是基于JMX+InfluxDB+Grafana的尝试。

  • 1.整体架构

主要技术点在于:

  • 在tomcat下打开jmx监控选项,暴露另一个端口35135
  • 通过jmxtrans基于JSON文件获取需要的jmx数据,然后将数据传入InfluxDB
  • 基于Grafana选择InfluxDB数据进行展现。

  • 2.实施步骤
  • 2.1 镜像准备

InfuxDB和Grafana都基于Pod方式部署,首先拉取镜像

docker pull docker.io/influxdb:1.4.
docker pull docker.io/grafana/grafana:4.6.
[root@k8s-master tomcatjmx]# cat grafana.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: grafana
spec:
replicas:
template:
metadata:
labels:
app: "grafana"
spec:
containers:
- name: grafana
image: docker.io/grafana/grafana:4.6.
ports:
- containerPort:
---
apiVersion: v1
kind: Service
metadata:
name: grafanasvc
labels:
app: grafana
spec:
ports:
- port:
protocol: TCP
targetPort:
name: http
type: NodePort
selector:
app: grafana
[root@k8s-master tomcatjmx]# cat influxdb.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: influxdb
spec:
replicas:
template:
metadata:
labels:
app: "influxdb"
spec:
containers:
- name: influxdb
image: docker.io/influxdb:1.4.
ports:
- containerPort:
name: influxdbport
- containerPort:
name: influxadmin
---
apiVersion: v1
kind: Service
metadata:
name: influxdbsvc
labels:
app: influxdb
spec:
ports:
- port:
protocol: TCP
targetPort:
name: http
- port:
protocol: TCP
targetPort:
name: admin
type: NodePort
selector:
app: influxdb
  • 2.2 应用镜像构建

整个结构如下:

 jmx的打开问题

首先需要修改catalina.sh,打开jmx选项

JAVA_OPTS="$JAVA_OPTS $JSSE_OPTS -Xms512m -Xmx1024m -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=35135"

jmx的获取问题

下载jmxtrans-all.jar包

jmxtrans运行命令如下:

java -Djmxtrans.log.dir='/usr/local/log' -jar /usr/local/jmxtrans--all.jar -j /usr/local/

其中-j指到需要获取指标的配置文件,比如tomcat.json文件。

[root@node1 caas]# cat tomcat.json
{
"servers" : [ {
"port" : "",
"host" : "HOSTNAME",
"queries" : [
{
"obj" : "java.lang:type=Memory",
"attr" : [ "HeapMemoryUsage", "NonHeapMemoryUsage" ],
"resultAlias":"jvmMemory",
"outputWriters" : [ {
"@class" : "com.googlecode.jmxtrans.model.output.InfluxDbWriterFactory",
"url" : "http://influxdbsvc:8086/",
"username" : "root",
"password" : "root",
"database" : "caasdb"
}]
},
{
"obj" : "java.lang:type=Threading",
"attr" : [ "ThreadCount", "PeakThreadCount", "TotalStartedThreadCount", "DaemonThreadCount"],
"resultAlias":"jvmThreading",
"outputWriters" : [ {
"@class" : "com.googlecode.jmxtrans.model.output.InfluxDbWriterFactory",
"url" : "http://influxdbsvc:8086/",
"username" : "root",
"password" : "root",
"database" : "caasdb"
}]
},
{
"obj" : "java.lang:type=Memory",
"attr" : [ "HeapMemoryUsage"],
"resultAlias":"HeapMemoryUsage",
"outputWriters" : [ {
"@class" : "com.googlecode.jmxtrans.model.output.InfluxDbWriterFactory",
"url" : "http://influxdbsvc:8086/",
"username" : "root",
"password" : "root",
"database" : "caasdb"
}]
},
{
"obj" : "Catalina:type=GlobalRequestProcessor,name=\"http-apr-8080\"",
"attr" : [ "bytesSent" ],
"resultAlias":"tomcatByteSent",
"outputWriters" : [ {
"@class" : "com.googlecode.jmxtrans.model.output.InfluxDbWriterFactory",
"url" : "http://influxdbsvc:8086/",
"username" : "root",
"password" : "root",
"database" : "caasdb"
}]
},
{
"obj" : "java.lang:name=CMS Old Gen,type=MemoryPool",
"resultAlias": "cmsoldgen",
"attr" : [ "Usage" ],
"outputWriters" : [ {
"@class" : "com.googlecode.jmxtrans.model.output.InfluxDbWriterFactory",
"url" : "http://influxdbsvc:8086/",
"username" : "root",
"password" : "root",
"database" : "caasdb"
}]
},
{
"obj" : "java.lang:type=GarbageCollector,name=*",
"resultAlias": "gc",
"attr" : [ "CollectionCount", "CollectionTime" ],
"outputWriters" : [ {
"@class" : "com.googlecode.jmxtrans.model.output.InfluxDbWriterFactory",
"url" : "http://influxdbsvc:8086/",
"username" : "root",
"password" : "root",
"database" : "caasdb"
}]
},
{
"obj" : "Catalina:type=Engine",
"attr" : [ "backgroundProcessorDelay"],
"resultAlias":"EngineDelay",
"outputWriters" : [ {
"@class" : "com.googlecode.jmxtrans.model.output.InfluxDbWriterFactory",
"url" : "http://influxdbsvc:8086/",
"username" : "root",
"password" : "root",
"database" : "caasdb"
}]
}
]
}]
}

详解

"outputWriters" : [ {
"@class" : "com.googlecode.jmxtrans.model.output.InfluxDbWriterFactory",
"url" : "http://influxdbsvc:8086/",
"username" : "root",
"password" : "root",
"database" : "caasdb"

这一段主要是访问influxdb的服务,同时创建caasdb数据库,用户名密码都是root

"servers" : [ {
"port" : "",
"host" : "HOSTNAME",

port主要是tomcat暴露出来的jmx端口

host是指tomcat位于的主机位置或者主机名称

在容器中运行多个进程问题

这样jmxtrans会启动另一个进程,也就是说在这个Pod中会同时启动俩个进程。所以我们要通过supervisor来启动。

supervisor配置

[root@node1 caas]# cat supervisord.conf
[supervisord]
nodaemon=true [program:tomcat]
command=/usr/local/apache-tomcat-8.5./bin/catalina.sh run [program:jmxtrans]
command=/usr/local/updatejson.sh

为什么不是直接java -jar而是一个叫updatejson.sh的脚本呢?

因为我们需要在这个脚本中将配置json文件的host字段替换成为Pod的主机名或者ip

[root@node1 caas]# cat updatejson.sh
#!/bin/bash sed -i "s/HOSTNAME/${HOSTNAME}/" /usr/local/tomcat.json java -Djmxtrans.log.dir='/usr/local/log' -jar /usr/local/jmxtrans--all.jar -j /usr/local/

Supervisord不显示tomcat日志问题

需要在supervisord.conf下加入loglevel和redirect_stderr选项

[root@node1 caas]# cat supervisord.conf
[supervisord]
nodaemon=true
loglevel=debug [program:tomcat]
command=/usr/local/apache-tomcat-8.5./bin/catalina.sh run
stdout_logfile=/usr/local/apache-tomcat-8.5./logs/catalina.log
redirect_stderr=true [program:jmxtrans]
command=/usr/local/updatejson.sh

基本OK了,整个Dockerfile如下

FROM linux7-jre:8u151

RUN mkdir -p "/usr/local"

COPY caas/*.*  /usr/local/

WORKDIR /usr/local

RUN yum install -y python-setuptools && \
easy_install supervisor && \
yum clean all && \
tar -xvf apache-tomcat-8.5.6.tar.gz && \
cp /usr/local/catalina.sh /usr/local/apache-tomcat-8.5.6/bin/catalina.sh && \
mv /usr/local/supervisord.conf /etc/ && \
chmod +x /usr/local/updatejson.sh ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.6
ENV PATH $CATALINA_HOME/bin:$PATH
ENV JAVA_HOME /usr/java/default WORKDIR $CATALINA_HOME EXPOSE 8080 35135 CMD ["supervisord"]

启动以后看到pod运行

服务如下:

比较核心的需要kubectl logs influxdb-4115439627-rm9zb查看一下,确认有数据写入。

  • 2.3 Grafana配置

datasource配置

新建一个Dashboard

点击Panel Title,然后选择编辑Edit

选择相应的指标,形成报告。

grafana配置详情参考下图

  • 3.其他问题
  • 为什么jmxtrans不放在host中进行对多个tomcat的收集

每个jmxtrans需要指定一个配置文件,在这个配置文件中指定监控的主机名,如果都共用一个的话,那所有的指标都会汇集到一起,如果要区分的话,就必须放到Pod中。

  • grafana每次当pod发生变化时,图标无法自动更新,必须手工配置,这个比较难搞。
  • Q. How do I use the second y axis, secondYAxis function does not work

    A. You can switch any series to the second y axis by clicking on the colored line to left of the series name in the legend below the graph. Alternately, use the "Display Styles" > "Series Specific overrides" to define an alias or regex + "Y-axis: 2" to move metrics to the right Axis

  • 4.例子程序

消耗CPU的小程序

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%@page import="java.util.*"%> <%@ page contentType="text/html;charset=windows-1252"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"/>
<title>Random</title>
</head>
<html>
<body>
<h3> <%
java.util.Random generator = new java.util.Random();
generator.ints(, , ).sorted();
%>
random sort finished .........
</h3> </body>
</html>

消耗内存的小程序

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%@page import="java.util.*"%> <%@ page contentType="text/html;charset=windows-1252"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"/>
<title>Outofmemory</title>
</head>
<html>
<body>
<h3> <% List<String> heapList = new ArrayList<String>(); for (int i=;i<;i++) {
heapList.add(new String("Shobhna"));
} %>
put heapList success.........
</h3> </body>
</html>

Kubernetes下的应用监控解决方案的更多相关文章

  1. Kubernetes 下零信任安全架构分析

    点击下载<不一样的 双11 技术:阿里巴巴经济体云原生实践> 本文节选自<不一样的 双11 技术:阿里巴巴经济体云原生实践>一书,点击上方图片即可下载! 作者 杨宁(麟童) 阿 ...

  2. Kubernetes集群的监控报警策略最佳实践

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/M2l0ZgSsVc7r69eFdTj/article/details/79652064 本文为Kub ...

  3. OpenStack 监控解决方案

    正如你们看到的那样,到目前为止(OpenStack Kilo),OpenStack自己的监控组件Telemetry并不是完美, 获取的监控数据以及制作出来的图表有时候让人匪夷所思,因其重点并不是监控而 ...

  4. Linux 下 SSH 远程超时解决方案

    Linux 下 SSH 远程超时解决方案 今天突然看到一个问题说是如何解决SSH远程超时的问题. 找了一点资料.用于解决这个需求~ 第一种:OpenSSH 配置文件设置 位于112行的 "C ...

  5. Promethus+Grafana监控解决方案

    [MySQL]企业级监控解决方案Promethus+Grafana Promethus用作监控数据采集与处理,而Grafana只是用作数据展示 一.Promethus简介 Prometheus(普罗米 ...

  6. Prometheus在Kubernetes下的服务发现机制

    Prometheus作为容器监控领域的事实标准,随着以Kubernetes为核心的云原生热潮的兴起,已经得到了广泛的应用部署.灵活的服务发现机制是Prometheus和Kubernetes两者得以连接 ...

  7. 在Kubernetes下部署Prometheus

    使用ConfigMaps管理应用配置 当使用Deployment管理和部署应用程序时,用户可以方便了对应用进行扩容或者缩容,从而产生多个Pod实例.为了 能够统一管理这些Pod的配置信息,在Kuber ...

  8. Greenplum数仓监控解决方案(开源版本)

    Greenplum监控解决方案 基于Prometheus+Grafana+greenplum_exporter+node_exporter实现 关联图 一.基本概念 1.Prometheus ​ Pr ...

  9. Zabbix企业级开源监控解决方案

    Zabbix企业级开源监控解决方案 目录 Zabbix企业级开源监控解决方案 一.Zabbix 1. 监控系统的必要性 2. 监控软件的作用 3. Zabbix的定义 4. Zabbix的监控原理 5 ...

随机推荐

  1. Python——turtle生成图片保存

    代码示例如下: from Tkinter import * from turtle import * import turtle forward(100) ts = turtle.getscreen( ...

  2. C# 笔记——委托

    委托是一个类型安全的对象,它指向程序中另一个以后会被调用的方法(或多个方法).通俗的说,委托是一个可以引用方法的对象,当创建一个委托,也就创建一个引用方法的对象,进而就可以调用那个方法,即委托可以调用 ...

  3. leetcode 之Rotate List(18)

    这题我的第一想法是用头插法,但实际上并不好做,因为每次都需要遍历最后一个.更简单的做法是将其连成环,找到相应的位置重新设头结点和尾结点.这过 有很多细节需要注意,比如K有可能是大于链表长度的,如何重新 ...

  4. O(n)回文子串(Manacher)算法

    O(n)回文子串(Manacher)算法 资料来源网络 参见:http://www.felix021.com/blog/read.php?2040 问题描述: 输入一个字符串,求出其中最大的回文子串. ...

  5. python 函数内置方法short_desc

    1. 给函数设置一个文本 def action_checked(self, request): pass action_checked.short_desc = "签到" # sh ...

  6. QT中循环显示图片和简单的显示图片

    请关注我的github https://github.com/linqiaozhou 以下实例代码不久后将会上传到我的github 这是我最近一个项目中的部分代码 //以下是简单的在QT中显示图片的代 ...

  7. Jmeter-----随机生成手机号后8位并去重,来进行注册手机号的压测

    要求:对注册接口进行100000次压测,手机号已126开头,后面的8位数不限 前言:在进行测试中,我们需要对注册接口进行压测100000次,那么就要求手机号码每次填写的不一致,否则手机号使用一次后会出 ...

  8. JavaScript best practices JS最佳实践

    JavaScript best practices JS最佳实践 0 简介 最佳实践起初比较棘手,但最终会让你发现这是非常明智之举. 1.合理命名方法及变量名,简洁且可读 var someItem = ...

  9. The 18th Zhejiang University Programming Contest Sponsored by TuSimple -C Mergeable Stack

    题目链接 题意: 题意简单,就是一个简单的数据结构,对栈的模拟操作,可用链表实现,也可以用C++的模板类来实现,但是要注意不能用cin cout,卡时间!!! 代码: #include <std ...

  10. Bootstrap 实现CRUD示例及代码

    https://github.com/wenzhixin/bootstrap-table-examples/blob/master/crud/index.html <!DOCTYPE html& ...