1 监控简介
亚马逊副总裁、CTO 沃纳·沃格斯(Werner Voegls)说过:“You build it, you run it, you monitor it.”(你构建了它,你运行它,你就有责任监控它。)
1.1 监控概述
系统层监控:
CPU、内存、网卡、磁盘利用率、带宽利用率、延迟、丢包率、交换机、路由器、防火墙等基础设施监控
web 监控:
打开速度、URL 打开状态码、API 接口可用性
业务监控:
订单交易量、活跃用户量、支付量
中间件监控:
数据库、redis、kafka、MQ、API 等
1.2 监控规划
通过 zabbix 代理去收集不同监控资源,然后将多个采集项由 proxy 传给 zabbix server
监控本身是不会处理任何业务上的故障,而是对服务的运行状态进行监控,最主要的功能:
- 数据采集,手动设置数据采集项
- 存储采集数据,存储值数据库还是说什么地方
- 数据展示
- 监控通知告警
1.3 监控方案
开源监控软件:cacti、nagios、zabbix、smokeping、open-falcon、prometheus、商业监控等。
1.3.1 Cacti
https://github.com/Cacti/cacti
Cacti 是基于 LAMP 平台展现的网络流量监测及分析工具,通过 SNMP 技术或自定义脚本从目标设备/主机获取监控指标信息;其次进行数据存储,调用模板将数据存到数据库,使用 rrdtool 存储和更新数据,通过 rrdtool 绘制结果图形;最后进行数据展现,通过 Web 方式将监控结果呈现出来,常用于在数据中心监控网络设备。
1.3.2 Nagios
Nagios 用来监视系统和网络的开源应用软件,利用其众多的插件实现对本机和远端服务的监控,当被监控对象发生异常时,会及时向管理员告警,提供一批预设好的监控插件,用户可以之间调用,也可以自定义 Shell 脚本来监控服务,适合各企业的业务监控,可通过 Web 页面显示对象状态、日志、告警信息,分层告警机制及自定义监控相对薄弱。
1.3.3 SmokePing
https://oss.oetiker.ch/smokeping/
http://blogs.studylinux.net/?p=794
Smokeping 是一款用于网络性能监测的开源监控软件,主要用于对 IDC 的网络状况,网络质量,稳定性等做检测,通过 rrdtool 制图方式,图形化地展示网络的时延情况,进而能够清楚的判断出网络的即时通信情况。
1.3.4 Open-falcon
https://github.com/XiaoMi/open-falcon
小米公司开源出来的监控软件 open-falcon(鹰隼),监控能力和性能较强。
1.3.5 Nightingale 夜莺
一款经过大规模生产环境验证的、分布式高性能的运维监控系统,由滴滴基于 open-falcon 二次开发后开源出来的分布式监控系统。
1.3.6 zabbix
目前使用较多的开源监控软件,可横向扩展、自定义监控项、支持多种监控方式、可监控网络与服务等。
1.3.7 Prometheus
Prometheus 是基于 go 语言开发的一套开源的监控、报警和时间序列数据库的组合,是由 SoundCloud 公司开发的开源监控系统,Prometheus 于 2016 年加入 CNCF(Cloud Native Computing Foundation,云原生计算基金会), 2018 年 8 月 9 日 prometheus 成为 CNCF 基金会继 kubernetes 之后毕业的第二个项目,prometheus 在容器和微服务领域中得到了广泛的应用,其特点主要如下:
使用 key-value 的多维度格式保存数据
数据不使用 MySQL 这样的传统数据库,而是使用时序数据库,目前是使用的 TSDB, https://www.aliyun.com/product/hitsdb #阿里云 TSDB 简介
支持第三方 dashboard 实现更高的图形界面,如 grafana(Grafana 2.5.0 版本及以上) 功能组件化
不需要依赖存储,数据可以本地保存也可以远程保存
服务自动化发现
强大的数据查询语句功(PromQL,Prometheus Query Language)
支持不同语言开发的客户端
官方和社区推出很多 exporter #https://prometheus.io/docs/instrumenting/exporters/
2 prometheus 简介与安装
2.1 组件介绍
prometheus server:主服务,接受外部 http 请求,收集、存储与查询数据等
prometheus targets: 静态收集的目标服务数据
service discovery:动态发现服务prometheus alerting:报警通知
push gateway:数据收集代理服务器(类似于 zabbix proxy)
data visualization and export: 数据可视化与数据导出(访问客户端)
Prometheus 结构图
Prometheus web UI 或 Grafana 通过 api 请求连接到 Prometheus 的接口上,然后通过 PromQL 语句查询想要获取的数据,查询到对应的数据之后再返回对应的显示,数据是放到本地的
Prometheus 内部的话有以下几个组件:
- Prometheus Server(核心组件):
- Prometheus 的核心,server 会从应用上去抓取数据,app 也会给 Prometheus 提供数据,所以 Prometheus 也会有一个数据的消息格式,包括 Prometheus 的一些采集方法,这个就相当于是我们的 sdk ,也就是说 Prometheus 是提供的 sdk 和我们的语言是有一定关系的,比如说我们的应用开发语言可能是 php、java、go、这个时候 sdk 都有不同语言的 sdk
- SDK(第三方应用开发):
- 对于采集来说,如上图的 app ,我们提供的 sdk 其实在开发应用的时候要把 sdk 嵌入到我们的应用中去,但是比如说我们要去监控一个操作系统,那不可能说针对操作系统来重新开发吧,所以这个时候在 Prometheus 中提供了 exporter ,然后调用 os 的接口不管是系统命令还是将 os 上的文件数据通过 os 接口去暴露给 Prometheus
-
exporter:如果我们的系统是一个第三方的组件,没有办法对他进行二次开发,然后通过 exporter 给我们的第三方系统进行通信,这里的通信的话其实依赖于第三方组件提供的一些接口,我们来采集数据如 mysql、redis 等
-
我们也都知道 http 响应其实都是文本,所以我们也可以根据他的数据格式我们自己去写库
-
Push Gateway(外部服务访问):
- Prometheus 是从 push Gateway 上去拉取数据的,但是 push Gateway 的数据一般用在外部网络不允许进去 Prometheus 的时候,我们可以把 push Gateway 部署在外面,从一些应用上,然后将消息推送到 push Gateway 上,这就是 push 模式
-
一般用在网络的限制,app 运行一次就结束的情况下的任务
-
Pushgateway 是 Prometheus 生态中一个重要工具,使用它的原因主要是:
-
Prometheus 采用 pull 模式,可能由于不在一个子网或者防火墙原因,导致 Prometheus 无法直接拉取各个 target 数据。
- 在监控业务数据的时候,需要将不同数据汇总, 由 Prometheus 统一收集。
由于以上原因,不得不使用 pushgateway,但在使用之前,有必要了解一下它的一些弊端:
- 将多个节点数据汇总到 pushgateway, 如果 pushgateway 挂了,受影响比多个 target 大。
- Prometheus 拉取状态
up
只针对 pushgateway, 无法做到对每个节点有效。 - Pushgateway 可以持久化推送给它的所有监控数据。
因此,即使你的监控已经下线,prometheus 还会拉取到旧的监控数据,需要手动清理 pushgateway 不要的数据。
-
PromQL(数据查询语句):
- 普罗米修斯将数据采集完成以后呢会存储到自己的 db 中(DB 是一个时序的数据库),最终我们拿到这些数据后可以进行查询,就会有一个 web 展示
-
查询语言是通过 Prometheus 提供的 PromQL 的引擎,那么对于 TSDB 我们也想产生一些告警,所以在 Prometheus server 内部的话还有一个规则引擎(RuleEngine),当然我们也需要给 RuleEngine 规则配置,比如在那些情况下产生告警,那规则的话我们是有一些配置,是通过配置文件的方式进行提供
-
在 Prometheus 中的配置文件主要是 json 和 yaml 格式,在配置文件中的话一般都是对规则的配置,当然 Prometheus server 也可能会有些配置,对于 Prometheus 的话还需要监控 agent ,也可以通过 yaml 文件来进行配置
-
在 Prometheus 中告警会去查询 TSDB ,如果产生告警的话,会把告警在存储到 TSDB,然后还会将告警发送出去,对外发送的话也是提供的是 http aip ,类似于 webhooXk,那我们也可以开发个告警接收系统配置给 Prometheus ,然后当产生告警以后会把告警发生给我们的 app
-
后期有了 srcdata 之后我们可以通过 grafana 进行数据展示,当然 Prometheus 自己也提供了 API 我们也可以自己开发和调用到我们的 web 页面上
-
Service discovery Prometheus 服务发现获取监控数据:
- 如 K8S 也提供了服务器发现功能,openstack 等,主动抓取数据并将数据存储至 TSDB 中,Prometheus 本身就是一个 TSDB 的数据库,会将数据存储在本地,我们可以部署多个,部署多个的话数据不共享我们就可以单独存储至一个存储服务器中,如 ceph、nfs 等分部署存储
- alert manager(监控告警):
- 在 Prometheus 中产生的告警是没有规则,而是每一个规则产生以后就会立即往外发送,那这个时候告警数量相对来说比较多,或者说我们的应用挂了以后告警就发送不出去了,这时候 Prometheus 就提供了一个 alert manager,我们可以通过配置 Prometheus 将告警发送给 alert manager 。
-
当然我们可以部署多个 alert manager 来避免单点失败,这时候 Prometheus 会将告警发送给多个 alert manager 上,在由 alert manager 对外进行通知,我们可以将 app 放到后面 webhook 也提供了通知,也就会调用我的 http api(需要自己开发)
-
alert manager 也提供了其他方式如邮件方式,可以将告警信息直接发送给邮件服务器,当然也有第三方的插件
-
exporter:
- 抓取 API 获取到监控对象的监控数据,将数据抓取过来存放到 TSDB ,TSDB 的数据放入到本地磁盘,然后再通过 http server 提供 API
- metrics:
- 指标数据,就是我们监控数据的通称,Prometheus server 能够直接到被监控节点上拉取数据
但是这种逻辑存在下面问题:
- 如果规则引擎(rule engine) 产生了一个告警都发送给了两个 alert manager ,那两个 alert manager 给我们通知的时候就会产生两次,当然这个是我们 alert manager 要去避免的,所以 alert manager 的逻辑有以下几个
- alert manager 高可用避免单点失败
- 但是 alert manager 实现高可用之后,那么消息在通知的时候会是两个或更多,当然 alert manager 要进行消息的抑制也就是说已经有一个 alert manager 发送了消息,其他的 alert manager 就不用发送了
- rule engine 的消息都是一条一条的,告警数量比较多,然后再 alert manager 会有一个等待的时间,alert manager 等待了一段时间之后将这段时间的告警统一按照分组来发送,也就是我们的告警分组
- 而且有些 alert manager 的告警我们可以不用关注,或者说如果产生了某一个告警另外其他一样类型的告警就不想 alert manager 发送了,比如说我们的操作系统挂了,那我们这个操作系统相关的应用就不用关注了,这个就可以配置 alert manager 的告警静默处理的功能
- alert manager 提供了对外第三方的应用发送,所以 alert manager 也有告警发送功能
- 总结 alert manager 功能:
- 高可用
- 消息抑制
- 告警分组
- 静默处理
- 告警发送
2.2 Prometheus 应用场景
Prometheus 并非所有场景都能使用,我们都知道 Prometheus 采集数据是通过 pull 方式进行采集,需要定期轮询采集 agent 节点上的数据信息,那轮询的时间是有一个延时的,所以在 Prometheus 中不适合百分之百精确的数据监控应用场景。
换句话说就是如果需要监控数据的百分之百 Prometheus 是不适合的
Prometheus 应用场景:
- Prometheus 可以记录任何纯数据的时序数据
- 通过 Prometheus 的服务发现功能,常用于以机器为中心的监控,面向高动态的服务体系架构来监控
- 不适合 100% 准确性的要求,如请求计费的场景
- 通过指标名称进行汇总,一些相关的应用数据可以通过标签的名称进行区分来进行汇总
2.2.1 Prometheus 数据模型和 TSDB
想要了解 Prometheus 数据模型的话我们就需要介绍一下 TSDB
TSDB 时序数据库:
- 在存储数据的时候都有一个属性叫时间,
- 在每个时间点上每个对应的数据是什么。时间可以理解为数据的名称,对应的数据是什么可以理解为数据的值。
-
数据名称:
组成方式,数据名称其实是由两部分组成:
- 指标名称
- 标签(key=value)
- 数据值:
在 Prometheus 中数据值只有一个(
float64
),也就说 Prometheus 中只能够存储 float64 类型 -
TSDB 数据存储:
- 对于每一个时间点,如上图中的 t1 时间点并对应 web 系统上的
request_total{path="/"}
/ 路径的请求数量,request_total{path="/auth/login"}
这些 RUL 都有统计结果,假如在t1 时间点 request_total{path="/"}
请求了 100 次,那这个时候数据名称中的指标名称就是request_total
,标签就是path=/
值就是 100,而request_total{path="/auth/login"}
请求 10 次,也就是说在 t1 这个时间点,我们的数据值可以是很多同时发生的数据 - 可能在 t2 时间点 Prometheus 又进行采集了一次,这个时候
request_total{path="/"}
请求可能变成了 200,request_total{path="/auth/login"}
就变成了 20,这就是时序数据库
- 对于每一个时间点,如上图中的 t1 时间点并对应 web 系统上的
- 我们都知道 Prometheus 中的数据值都是一个 float64 类型,所以 Prometheus 只适合数据值是一个浮点类型的数据存储
-
在 Prometheus 面向服务中,我们可以通过自定义 tag 给一些监控属性、属性值来对数据进行汇总
2.3 Prometheus 安装
Prometheus 安装可以通过多种方式进行安装
2.3.1 通过容器启动
https://prometheus.io/docs/prometheus/latest/installation/ #docker 镜像直接启动
# docker pull prom/prometheus:v2.31.1
# docker run -it -d --restart=always -p 9090 prom/prometheus:v2.31.1
2.3.2 在线安装
# apt search prometheus
# apt-cache madison prometheus
prometheus | 2.15.2+ds-2 | http://mirrors.tuna.tsinghua.edu.cn/ubuntu focal/universe amd64
# apt install prometheus
2.3.3 operator 部署
官方提供的一个快捷部署方式,通过 yaml 文件快捷部署
https://github.com/coreos/kube-prometheus #operator 部署
# git clone https://github.com/prometheus-operator/kube-prometheus.git
# cd kube-prometheus/
# kubectl apply -f manifests/setup
# kubectl apply -f manifests/
2.3.4 官方二进制部署
https://prometheus.io/download/
因为 Prometheus 本身也会产生大量数据。所以通过二进制部署的方式我们可以将数据本身存储在对应的 ceph 或磁盘上,而且二进制部署相对来说性能会更好一些,而且通过二进制不熟的话配置文件改起来相对方便、数据存储也会方便一些
Prometheus 部署之后默认收集本机的数据,如果其他的 node 也需要实现监控的话就需要安装 exporter ,node-exporter 用于收集宿主机的指标数据如 磁盘、网络、内存、cpu 等,与 zabbix-agent 功能类似,但是如果说我们的主机上跑了一堆容器那么我们的 node-exporter 就不能够实现采集
2.3.4.1 二进制安装 server 端
server 端起来之后会监听 9090 端口
1.创建目录下载安装包
root@server:~# mkdir /apps
root@server:~# cd /apps/
root@server:/apps# wget https://github.com/prometheus/prometheus/releases/download/v2.31.1/prometheus-2.31.1.linux-amd64.tar.gz
root@ubuntu:/apps# tar xf prometheus-2.30.3.linux-amd64.tar.gz
2.解压完了之后可以看到对应的文件
root@server:/apps# ll prometheus-2.30.3.linux-amd64
total 185592
drwxr-xr-x 4 3434 3434 4096 Oct 6 00:43 ./
drwxr-xr-x 3 root root 4096 Nov 15 15:43 ../
drwxr-xr-x 2 3434 3434 4096 Oct 6 00:39 console_libraries/
drwxr-xr-x 2 3434 3434 4096 Oct 6 00:39 consoles/
-rw-r--r-- 1 3434 3434 11357 Oct 6 00:39 LICENSE
-rw-r--r-- 1 3434 3434 3646 Oct 6 00:39 NOTICE
-rwxr-xr-x 1 3434 3434 100357256 Oct 6 00:14 prometheus* # Prometheus 执行程序
-rw-r--r-- 1 3434 3434 934 Oct 6 00:39 prometheus.yml # Prometheus 配置文件
-rwxr-xr-x 1 3434 3434 89643838 Oct 6 00:17 promtool* # Prometheus yaml 文件语法检查工具
3.创建软连接,这样的好处是后期 Prometheus 升级或者版本变化也好 service 文件不用修改
root@server:/apps# ln -sv /apps/prometheus-2.30.3.linux-amd64 /apps/prometheus
'/apps/prometheus' -> '/apps/prometheus-2.30.3.linux-amd64'
4.启动 Prometheus
root@server:/apps/prometheus# ./prometheus
但是现在 Prometheus 还是一个前台启动,所以我们需要通过编写 service 文件将其放到后台启动
2.3.4.1.1 编写 service 文件
1.编写 service
root@server:~# vim /etc/systemd/system/prometheus.service
[Unit]
Description=Prometheus Server
Documentation=https://prometheus.io/docs/introduction/overview/ After=network.target
[Service]
Restart=on-failure
WorkingDirectory=/apps/prometheus/
ExecStart=/apps/prometheus/prometheus --config.file=/apps/prometheus/prometheus.yml
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
2.设置为开机自启动
root@server:~# systemctl daemon-reload
root@server:~# systemctl enable --now prometheus.service
# 查看当前 Prometheus 状态已经运行
root@ubuntu:~# systemctl status prometheus.service
● prometheus.service - Prometheus Server
Loaded: loaded (/etc/systemd/system/prometheus.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2021-11-15 15:54:07 CST; 2min 54s ago
Docs: https://prometheus.io/docs/introduction/overview/
Main PID: 1845 (prometheus)
Tasks: 8 (limit: 2290)
CGroup: /system.slice/prometheus.service
└─1845 /apps/prometheus/prometheus --config.file=/apps/prometheus/prometheus.yml
# 能够停止 Prometheus
root@ubuntu:~# systemctl stop prometheus.service
# 重启
root@ubuntu:~# systemctl restart prometheus.service
3.Prometheus 启动之后会在本地生成一个 data 目录,当然也可以在启动的时候通过 --storage.tsdb.path=
参数指定 Prometheus 的数据目录
# 这个目录是 Prometheus 的监控数据目录
root@server:/apps/prometheus# ll data/
total 28
drwxr-xr-x 4 root root 4096 Nov 15 15:58 ./
drwxr-xr-x 5 3434 3434 4096 Nov 15 15:48 ../
drwxr-xr-x 2 root root 4096 Nov 15 16:00 chunks_head/
-rw-r--r-- 1 root root 0 Nov 15 15:58 lock
-rw-r--r-- 1 root root 20001 Nov 15 15:59 queries.active
drwxr-xr-x 2 root root 4096 Nov 15 15:58 wal/
2.3.4.1.2 浏览器访问
http://10.0.0.139:9090/classic/graph
实现访问
默认 Prometheus 启动之后就会有一些监控指标,这些指标可以通过下面的 API 接口查询,因为在 Prometheus中我们需要通过 metrics 获取的监控指标进行监控数据的查询
http://10.0.0.139:9090/metrics
2.3.4.1.3 promQL 语句初体验
我们都知道在 Prometheus 中想查看监控指标的话需要通过 promQL 语句进行查询如下图,我在 metrics 中查询到的 process_max_fds
监控指标
1.比如这里我对当前进程打开的文件描述符的最大数量进行查询
2.通过 Prometheus 进行查询获取到对应数据
3.也可以通过点击 Graph
查看图形
server 端部署好之后就需要让他来监控数据了,这时候就需要安装 exporter ,所以接下来需要在我们的 node 节点上部署 node-exporter
2.3.4.2 二进制部署 node-exporter
node-exporter 起来之后会监听 9100 端口,这里我分别在两台 node 节点上部署一个 node-exporter,下面的操作可重复,这里我就写了一遍
1.创建目录并下载压缩包
root@node:~# mkdir /apps
root@node:~# cd /apps/
root@node:/apps# wget https://github.com/prometheus/node_exporter/releases/download/v1.2.2/node_exporter-1.2.2.linux-amd64.tar.gz
2.解压
root@node:/apps# tar xf node_exporter-1.2.2.linux-amd64.tar.gz
root@node:/apps# ll node_exporter-1.2.2.linux-amd64
total 18088
drwxr-xr-x 2 3434 3434 4096 Aug 6 21:50 ./
drwxr-xr-x 3 root root 4096 Nov 15 16:59 ../
-rw-r--r-- 1 3434 3434 11357 Aug 6 21:49 LICENSE
-rwxr-xr-x 1 3434 3434 18494215 Aug 6 21:45 node_exporter* # 主程序
-rw-r--r-- 1 3434 3434 463 Aug 6 21:49 NOTICE
3.创建软连接
root@node:/apps# ln -sv /apps/node_exporter-1.2.2.linux-amd64 /apps/node_exporter
2.3.4.2.1 编写 service 文件
1.编写 service 文件
root@node:/apps# vim /etc/systemd/system/node-exporter.service
[Unit]
Description=Prometheus Node Exporter
After=network.target
[Service]
ExecStart=/apps/node_exporter/node_exporter
[Install]
WantedBy=multi-user.target
2.启动测试
root@node:/apps# systemctl daemon-reload
root@node:/apps# systemctl enable --now node-exporter.service
# 查看状态
root@ubuntu:/apps# systemctl status node-exporter.service
● node-exporter.service - Prometheus Node Exporter
Loaded: loaded (/etc/systemd/system/node-exporter.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2021-11-15 17:10:56 CST; 25s ago
Main PID: 1956 (node_exporter)
Tasks: 4 (limit: 1080)
CGroup: /system.slice/node-exporter.service
└─1956 /apps/node_exporter/node_exporter
# 停止重启服务
root@ubuntu:/apps# systemctl stop node-exporter.service
root@ubuntu:/apps# systemctl restart node-exporter.service
3.查看端口 9100 开启
root@node:/apps# ss -ntl| grep 9100
LISTEN 0 128 *:9100 *:*
2.3.4.2.2 浏览器访问
http://10.0.0.138:9100/metrics
可以看到其实就是一个 metrics 接口。然后自动获取的就是当前 node 资源的监控信息
node-exporter 起来之后我们就可以收集这些数据,这是就需要配置 Prometheus-server 的配置文件,得让 Prometheus 知道我们得 node 节点地址才行