Prometheus+Grafna监控实践

在压测工作流程的"前期准备"章节中曾提到搭建监控,使用Prometheus和Grafana相结合就可以快速搭建一个强大的监控平台。

Prometheus主要负责监控数据的采集,存储以及对外提供查询功能,Grafana主要负责监控数据的图形化展示。

Prometheus

Prometheus是一套开源监控系统,它的架构主要如下所示:
Prometheus+Grafna监控实践_第1张图片

Prometheus Server

Prometheus Serve是Prometheus组件中的核心部分,负责实现对监控数据的采集,存储以及查询。

  • 数据采集:Prometheus Server周期性的轮询监控目标暴露的http接口,来获取监控数据。这些监控目标,可以是静态配置的到prometheus server上的,也可以是通过一些Service Disvovery服务动态发现的。
  • 数据存储:Prometheus Server本身就是一个时序数据库,将采集到的监控数据按照时间序列的方式存储在本地磁盘当中。
  • 数据查询:Prometheus Server对外提供了自定义的PromQL语言,实现对数据的查询以及分析。
Exporter

我们可以将Exporter即理解为上面prometheus server中提到的监控目标。

它主要是负责搜集系统指标以及业务指标,将这些数据通过http接口以promethues约定的数据格式对外提供。

  • 系统指标: 一些常用的系统,数据库、中间件等的指标都已经有现成的Exporter,只要安相应的Exporter即可,具体可见EXPORTERS
  • 业务指标: 可以通过引入对应语言的prometheus client,在代码中埋点的方式收集。prometheus支持java/C/python等大部分语言,具体可见clientlibs
WebUI
  • 自带UI: prometheus自带了一个简单的UI,我们可以用它来做PromQL的调试,看看要呈现的监控指标的图形是否符合预期
  • Grafana: Grafana是一个通用的可视化工具,可以将prometheus的采集到的数据美美的展示出来,具体可见grafana
Allertmanager

prometheus支持基于PromQL创建告警规则,如果满足告警条件,则产生告警信息并push到告警管理中心进行后续处理。

PushGateway

如果网络条件不支持prometheus server直接获取监控对象的数据,或者监控对象是一个很短时的任务,prometheus server还没来得及采集数据可能被销毁了,这个时候可以用pushGateway来做一个中转站,监控目标把监控数据push到中转站,prometheus server从中转站去pull数据。

实践

本次实践主要是基于一个mock server添加一些业务监控。

该mock server主要是模拟数据上报的接收方,建立及维护与数据上报服务器的tcp长连接,接受并解析约定格式的上报数据,最后对每条数据返回一个ack。

公司已经有pormetheus和Grafana了,所以这里不做额外搭建。需要做的事情主要如下:

  1. 业务代码中添加监控埋点: k8s上的mock server服务增加监控埋点,暴露http接口提供业务指标数据
  2. 与prometheus关联: 让prometheus能够采集到mock server的监控数据
  3. 与Grafana关联: 用grafana配置监控图表,展现prometheus采集的数据

业务代码中添加监控埋点

我的mock server是用python实现的,因此选用官方python版的prometheus_client

1. 安装
`pip install prometheus_client `
2. 埋点

Prometheus定义了4中不同的指标类型(metric type):Counter(计数器)、Gauge(仪表盘)、Histogram(直方图)、Summary(摘要),根据你想要的业务指标特性来选择。

  • Counter:只增不减的计数器,想要记录总次数,或者记录某段时间的速率变化例如QPS时使用
  • Gauge:可增可减的仪表盘,主要侧重反映当前系统状态,想要记录cpu,mem等时使用
  • Histogram:样本分布直方图,想要统计样本的分布情况时使用。在服务器端计算的分位数
  • Summary: 和Histogram类似,也是在统计分布情况时使用,不同的是在客户端计算分位数

在本例中,我定义了一个简单的统计收到的数据个数的计数器,然后在函数处理的合适位置打监控点加1计数

from prometheus_client import Counter

# 创建Counter类型
prom_received_total = Counter('evm_mocker_received_total', 'The total of evm mocker received event numbers')

def message_handle():
    ...
    # 在合适的位置埋点
    prom_received_total.inc()
3. 启动监控服务并暴露接口

只要在服务的入口函数中调用prometheus_client.start_http_server方法,即可以启动并暴露http监控端口,本例监控端口是8000。

from prometheus_client import start_http_server

start_http_server(8000)
4. 打包成docker镜像并部署到k8s

Dockerfile文件大致如下:

FROM python:3.6

LABEL maintainer="[email protected]"

# copy源码到image的指定路径
COPY . /data/evm_mocker

# 安装必要的包
RUN apt-get update
RUN apt-get upgrade -y
RUN apt-get install -y net-tools

RUN pip3 install fire \
    pymysql \
    prometheus_client

# 工作路径及入口方法
WORKDIR /data/evm_mocker
CMD [ "python3", "/data/evm_mocker/server.py" ]
  • 项目名叫做evm_mocker
  • 打包: docker build -t swc-harbor.nioint.com/sqe/evm_mocker:monitor -f docker/Dockerfile .
  • 推送到仓库: docker push swc-harbor.nioint.com/sqe/evm_mocker:monitor

k8s的Deployment配置如下 evm-mocker-deployment.yml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: evm-mocker-monitor
spec:
  replicas: 1
  selector:
    matchLabels:
      app: evm-mocker-monitor
  template:
    metadata:
      labels:
        app: evm-mocker-monitor
    spec:
      containers:
      - name: evm-mocker
        image: swc-harbor.nioint.com/sqe/evm_mocker:monitor
        imagePullPolicy: Always
        ports:
          - containerPort: 5555
            name: comm
          - containerPort: 8000
            name: monitor

service配置如下 evm-mocker-service.yml

apiVersion: v1
kind: Service
metadata:
  name: evm-mocker-monitor-service
  labels:
    name: evm-mocker-monitor-service
spec:
  type: NodePort
  ports:
  - port: 5555
    targetPort: 5555
    protocol: TCP
    name: comm
  - port: 8000
    targetPort: 8000
    protocol: TCP
    name: monitor
  selector:
    app: evm-mocker-monitor
  • evm-mocker-monitor服务的5555端口用于处理业务,8000端口用于监听数据的暴露
  • 部署命令: kubectl apply -f evm-mocker-deployment.yml -f evm-mocker-service.yml
5. 校验

部署好后,尝试访问服务的8000端口,观察是否能正常获取prometheus格式的数据。

调用kubectl get pods -o wide获得pod所在的node ip地址,调用kubectrl get svc获得pod 8000端口对应的外部端口号。

本例中最终的http接口是http://10.125.236.24:25448/ 。注意:此处访问接口后面接任意路径如/metrics, /prometheus也都能获取同样的数据。
Prometheus+Grafna监控实践_第2张图片

与prometheus关联

部署在k8s中的服务,如何由同样部署在k8s中的Prometheus server采集数据呢?

  1. 配置
    还记得在上文Promethues数据采集中提到的静态配置和动态发现吗?
    静态配置指的是往Prometheus server的配置文件中写死Exporter暴露的监控接口,这种方式每部署一个服务都得去配置文件里写一遍,不够灵活。好在k8s还支持动态发现,
    只要在部署service的yaml文件中添加metadata.annotations.prometheus.io/scrape='true’即可。

    evm-mocker-service.yml

    apiVersion: v1
    kind: Service
    metadata:
      ...
      annotations:
        prometheus.io/scrape: 'true' # 添加此行使得api能被发现
    spec:
      ...
    
  2. 校验
    在prometheus页面检查是否可以查询到上文配置的指标。

    Graph页面输入"evm_mocker_received_total" 查看console是否有数据。
    Prometheus+Grafna监控实践_第3张图片
    还可以通过Prometheus UI中的Status->Targets页面查看当前所有的监控采集任务。target

  3. PromQL
    无论是grafana监控的展现和告警的配置,都涉及到PromQL,因此,监控的配置很重要一点是写好PromQL,例如如果我们需要监控mock server的QPS,此处可写成rate(evm_mocker_received_total[1m])

    实践中,经常先在prometheus页面调试PromQL,图像符合预期后再把它填入到Grafana中。

    关于PromQl的详细介绍可以参考promql

与Grafana关联

服务的监控数据能被prometheus采集后,接下来就是用Grafana展现数据。

在Grafana页面创建一个dashboard,dashboard可以理解为监控图表的集合。然后在dashboard中创建一个个监控Panel。
Prometheus+Grafna监控实践_第4张图片

总结

本文介绍了prometheus的框架,然后用一个实例介绍一个监控指标从产生到展现的完整流程,包括:在业务代码中埋点监控指标并暴露接口,部署到k8s中并被prometheus的动态发现,通过grafana展现该指标的监控图。

参考
  1. prometheus-book
  2. prometheus 官方文档

你可能感兴趣的:(python,监控类,kubernetes)