聊聊监控
为什么要监控
- 监视应用程序的当前状态是预测问题和发现生产环境中瓶颈的最有效方法之一。
- 监控是整个产品周期中最重要的一环,及时预警减少故障影响免扩大,而且能根据历史数据追溯问题。
- 对系统不间断实时监控
- 实时反馈系统当前状态
- 保证业务持续性运行
怎么来监控
监控工具
- 适合临时性分析性能及排查故障。少量的服务器。
- 目前业内有很多不错的开源产品可供选择,利用开源产品很容易能做到这一点。
- free
- vmstat
- df
- top
- ss
- iftop
- …
监控系统
- Zabbix 不适用容器
- Open-Falcon 小米开源 功能强大 非容器
- Prometheus 适用容器
监控方案 | 告警 | 特点 | 适用 |
---|---|---|---|
Zabbix | Y | 大量定制工作 | 大部分的互联网公司 |
open-falcon | Y | 功能模块分解比较细,显得更复杂 | 系统和应用监控 |
Prometheus+Grafana | Y | 扩展性好,容器,应用 | 主机全方面监控 |
开源监控系统基本流程
- 数据采集:对监控数据采集
- 数据存储:将监控数据持久化存储,用于历时查询
- 数据分析:数据按需处理,例如阈值对比、聚合
- 数据展示:Web页面展示
- 监控告警:电话,邮件,微信,短信
要监控什么
- 可以从其他监控产品公司了解到要监控什么。
- 可参考的网站 https://www.jiankongbao.com
准备工作
- 熟悉被监控对象
- 整理监控指标
- 告警阈值定义
- 故障处理流程
Prometheus 监控范畴
- Prometheus 最擅长 api监控、应用监控
- Prometheus 不擅长 日志监控、安全监控
- Prometheus 需要数据源传来数据
Prometheus 概述
Prometheus 介绍及特点
Prometheus 是什么
- Prometheus(普罗米修斯)是一个最初在SoundCloud上构建的监控系统。自2012年成为社区开源项目,拥有非常活跃的开发人员和用户社区。为强调开源及独立维护,Prometheus于2016年加入云原生云计算基金会(CNCF),成为继Kubernetes之后的第二个托管项目。
- Prometheus是由SoundCloud开发的开源监控报警系统和时序列数据库。从字面上理解,Prometheus由两个部分组成,一个是监控报警系统,另一个是自带的时序数据库(TSDB)
- 官方网站:
1 | https://prometheus.io |
Prometheus 特点
- 多维数据模型:由度量名称(metric名称)和键/值对标识的时间序列数据
- PromSQL:一种灵活的查询语言,可以利用多维数据完成复杂的查询
- 不依赖分布式存储,单个服务器节点可直接工作,数据被存储在本地磁盘上
- 基于HTTP的pull方式采集时间序列数据
- 推送时间序列数据通过PushGateway组件支持
- 通过服务发现或静态配置发现目标
- 多种图形和仪表板支持
Prometheus 组成及架构
Prometheus 架构图
- 定时任务和短任务,他们会向Pushgateway传送数据,主动push,Prometheus Server 会定时拉取(pull) Pushgateway 里面的数据
- jobs/Exporters 长期任务,jobs采集项目提供的metrics接口指标,Exporters是已经制造好的监控,是官方提供的现成的采集方法,它负责采集数据,Prometheus Server来定时拉取
- Prometheus Server 的 Retrieval 模块负责定时拉取数据,存储时间序列数据(TSDB)
- 服务发现功能,动态的发现监控对象
- 提供查询接口 http server
- 数据展现除了 Prometheus 自带的 webui,还可以通过 grafana 等组件查询 Prometheus 监控数据
- PromQL 为 Prometheus 提供的查询语法,PromQL 模块通过解析语法树,调用存储模块,查询获取监控数据
- Prometheus 将告警推送到 alertmanger,然后通过 alertmanger 对告警进行处 理并执行相应动作,有多钟告警类型,微信、邮件、钉钉(需要第三方服务支持)
Prometheus 组成
- Prometheus Server:收集指标和存储时间序列数据,并提供查询接口
- ClientLibrary:客户端库,为各种语言提供客户端工具,让用户自己编写暴露metrics
- Push Gateway:短期存储指标数据。主要用于临时性的任务
- Exporters:采集已有的第三方服务监控指标并暴露metrics
- Alertmanager:告警
- Web UI:简单的Web控制台
Prometheus 监控指标数据模型
监控指标 数据模型
- Prometheus将所有数据存储为时间序列;具有相同度量名称以及标签属于同一个指标。
- 每个时间序列都由度量标准名称和一组键值对(也称为标签)唯一标识
- 时间序列格式:
1 | 度量标准名称{标签(健值对),标签2(健值对),...} 值 |
1 | 1. 指标格式分为两个部分:一份是指标名称,另一个是指标标签。 |
监控指标 数据类型
- Counter:递增的计数器
- Gauge:可以任意变化的数值
- Histogram:对一段时间范围内数据进行采样,并对所有数值求和与统计数量
- Summary:与Histogram类似
1 | 1. 数据类型是提现在客户端的,在暴露数据的时候要指定数据类型 |
作业和实例
监控目标的两个概念
- 实例:可以抓取的目标称为实例(Instances), 比如监控的某一台服务器,它就是一个实例
- 作业:具有相同目标的实例集合称为作业(Job), 类型一样的实例的集合。
- 在配置文件里面定义,是监控目标的概念术语
1 | scrape_configs: |
Prometheus 数据采集
- Prometheus 通过 HTTP 接口的方式从各种客户端获取数据,这些客户端必须符合 Prometheus 监控数据格式,通常由两种方式。
- 一是侵入式埋点监控,通过在客户端集成,如果 kubernetes API 直接通过引入 Prometheus go client,提供/metrics 接口查询 kubernetes API 各种指标,
- 另一种是通过 exporter 方式,在外部将原来各种中间件的监控支持转化为 Prometheus 的监控数据格式,如 redis exporter 将 reids 指标转化为 Prometheus 能够识别的 HTTP 请求。
- Prometheus 并没有采用 json 的数据格式,而是采用 text/plain 纯文本的方式 ,这是它的特殊之处。
- HTTP 返回 Header 和 Body 如上图所示,指标前面两行#是注释,标识指标的含义和类型。指标和指标的值 通过空格分割,开发者通常不需要自己拼接这种个数的数据, Prometheus 提供了各种语言的 SDK 支持。
Prometheus exporter
- Prometheus 为了支持各种中间件以及第三方的监控提供了 exporter,大家可以把它理解成监控适配器, 将不同指标类型和格式的数据统一转化为 Prometheus 能够识别的指标类型。
- 譬如 Node exporter 主要通过读取 linux 的/proc 以及/sys 目录下的系统文件获取操作系统运行状态
- reids exporter 通过 reids 命令行获取指标,mysql exporter 通过读取数据库监控表获取 mysql 的性能数据。 他们将这些异构的数据转化为标准的 Prometheus 格式,并提供 HTTP 查询接口。
Prometheus 数据存储
- Prometheus 提供了两种数据持久化方式:一种是本地存储,通过 Prometheus 自带的tsdb(时序数据库),将数据保存到本地磁盘,为了性能考虑,建议使用 SSD。
- 但本地存储的容量毕竟有限,建议不要保存超过一个月的数据。
- Prometheus 本地存储经过多年改进,自Prometheus2.0 后提供的V3版本tsdb性能已经非常高,可以支持单机每秒 1000w 个指标的收集。
- Prometheus 本地数据存储能力一直为大家诟病,但 Prometheus 本地存储设计的初衷就是为了监控数据的查询。
- Facebook 发现85%的查询是针对 26 小时内的数据。所以 Prometheus 本地时序数据库的设计更多考虑的是高性能而非分布式大容量。
- 另一种是远端存储,适用于大量历史监控数据的存储和查询。通过中间层的适配器的转化,Prometheus 将数据保存到远端存储。
- 适配器实现 Prometheus 存储的 remote write 和 remote read 接口并把数据转化为 远端存储支持的数据格式。
- 目前,远端存储主要包括 OpenTSDB、InfluxDB、Elasticsearch、M3db 等,其中 M3db 是目前非常受欢迎的后端存储。
Prometheus 部署
Prometheus 二进制部署
二进制部署:
1 | https://prometheus.io/docs/prometheus/latest/getting_started/ |
1 | # 下载安装包 |
配置监控本机
1 | [root@k8s-master2 prometheus]# cat prometheus.yml |
启动参数
1 | [root@k8s-master2 prometheus]# ./prometheus --help |
启动服务
1 | [root@k8s-master2 prometheus]# ./prometheus --config.file="prometheus.yml" |
1 | # 查看页面 |
1 | alert: 管理告警规则 |
配置系统服务管理
systemd服务管理配置文件
1 | [root@k8s-master2 ~]# cd /usr/lib/systemd/system |
1 | [root@k8s-master2 system]# systemctl start prometheus |
Prometheus Docker部署
Docker部署:
1 | https://prometheus.io/docs/prometheus/latest/installation/ |
1 | # 使用刚才二进制部署的配置文件挂载到容器中 |
1 | # 容器放在后台运行 |
访问本机的监控指标
1 | http://47.240.13.206:9090/metrics |
Prometheus 配置文件与核心功能
全局配置文件介绍
1 | # 官方说明 |
1 | global: |
配置采集目标 scrape_configs
1 | 参考: |
1 | # 作业 |
重新标记 relabel_configs
- relabel_configs :允许在采集之前对任何目标及其标签进行修改
- 重新标签的意义? 优化标签
- 重命名标签名
- 删除标签
- 过滤目标
relabel_configs 配置选项
1 | # 源标签 |
实例,查看一组服务器的cpu使用率
根据标签聚合
1 | # 用户和系统CPU花费的时间 |
增加一组服务器机房标签
1 | # 比如通过idc区分机房 |
通过聚合函数 + 标签查询数据
1 | # 就可以聚合所有idc=bj标签的实例的cpu数据,然后在相加得到总数 |
重命名标签
1 | # 修改job_name的值 |
1 | # 把job修改成idc |
根据标签过滤目标
1 | # <relabel_action>确定要采取的重新签名行动: |
1 | # drop 过滤匹配的标签,如果有这个标签,就不采集这个数据 |
1 | # keep 过滤匹配的标签,如果有这个标签,可以采集到数据 |
删除标签
1 | labeldrop: 将regex与所有标签名称匹配。匹配的任何标签都将从标签集中删除。 |
1 | # 查询你到的数据将不会再有jop标签 |
1 | # 测试的配置信息 |
基于文件的服务发现
1 | # 注释下我们的监控配置 |
1 | # 通过服务发现的形式 加入 |
1 | # 创建目录和yml文件,*.yml可以匹配所有的yml文件 |
1 | # 检查语法并热加载 |
监控案例
监控 Linux 服务器
- node_exporter:用于*NIX系统监控,使用Go语言编写的收集器。
1 | 使用文档:https://prometheus.io/docs/guides/node-exporter/ |
下载解压
1 | # 在被监控的linux主机 下载 node_exporter |
配置系统服务
1 | [root@k8s-node2 node_exporter]# vim /usr/lib/systemd/system/node_exporter.service |
查看暴露的接口
1 | # node_exporter服务会暴露metrics |
配置prometheus监控该实例
1 | # 配置一个新的job,并使用服务发现 |
1 | [root@k8s-master2 prometheus]# vim sd_config/node.yml |
总结
1 | # 增加一个node_exporter监控linux服务器: |
PromSQL 获取CPU,内存,硬盘使用率
1 | CPU使用率: |
CPU使用率
1 | 100 - 服务器所有cpu的空闲率 = cpu的使用率 |
内存使用率
1 | # 剩余内存的统计 = 剩余内存free + 缓存buff/cache |
磁盘使用率
1 | # 使用正则排除不想统计的分区 |
PromSQL 获取系统服务运行状态
1 | 使用systemd收集器,需要再服务启动时候增加参数 |
1 |
|
1 | node_systemd_unit_state{name=“docker.service”} # 只查询docker服务 |
1 | node_systemd_unit_state{instance="172.31.228.53:9100",job="node",name="docker.service"} |
Grafana 与 Prometheus 集成
- Grafana是一个开源的度量分析和可视化系统
- 它本身不存储数据,只会展示数据库里面的数据
- 官网资料
1 | https://grafana.com/grafana/download |
Grafana 安装
1 | # 容器安装 |
1 | # web 默认用户名和密码 admin/admin 进去自己修改 |
Grafana 添加数据源
Grafana 可视化展示Linux资源使用率
自己添加数据
使用 grafana dashboard
1 | # 别人绘制好的 我们拿来用 |
监控 Docker 服务器 与 Grafana 可视化
- cAdvisor(Container Advisor)用于收集正在运行的容器资源使用和性能信息。
- 和 node_exporter 一样暴露接口地址
- 官方资料:
1 | https://github.com/google/cadvisor |
部署 cAdvisor
1 | # 部署镜像在本地 |
1 | # 访问接口 ip:8080 |
cAdvisor 对接 prometheus
1 | [root@k8s-master2 ~]# vim /usr/local/prometheus/prometheus.yml |
Grafana 数据展示
1 | # 采集的都是容器的资源指标 |
1 | # 再启动一个 nginx 容器 |
监控 MySQL 服务器与 Grafana 可视化
- mysql_exporter:用于收集MySQL性能信息
- 官方资料
1 | https://github.com/prometheus/mysqld_exporter |
下载 mysql_exporter
1 | # 需要在要被监控的mysql服务主机上下载部署 |
配置连接本地实例
1 | [root@k8s-node2 mysqld_exporter]# mysql |
启动 mysqld_exporter 服务
1 | ./mysqld_exporter --config.my-cnf=.my.cnf |
配置 prometheus 监控mysqld实例
1 | [root@k8s-master2 prometheus]# vim prometheus.yml |
Grafana 数据展示
1 | https://grafana.com/dashboards/7362 |
小总结
1 | 1. 不管是监控node资源 还是 mysql服务,都需要先下载对应的 exporter |
报警神器 AlertManager
部署 AlertManager
- 官网资料
1 | 地址1:https://prometheus.io/download/ |
1 | [root@k8s-master2 opt]# wget https://github.com/prometheus/alertmanager/releases/download/v0.20.0/alertmanager-0.20.0.linux-amd64.tar.gz |
1 | 管理-报警媒介类型-Email |
配置 Alertmanager
1 | [root@k8s-master2 alertmanager-0.20.0.linux-amd64]# vim alertmanager.yml |
1 | # 检查语法 |
启动 alertmanager
1 | [root@k8s-master2 alertmanager-0.20.0.linux-amd64]# ./alertmanager --config.file=alertmanager.yml |
配置 Prometheus 与 Alertmanager 通信
1 | # Alertmanager configuration |
在 Prometheus 中创建告警规则
1 | [root@k8s-master2 prometheus]# mkdir rules |
1 | # 重新加载配置 启动 |
验证告警
1 | # 我们已经配置了告警规则,而且有一个mysql的服务我们设置了错误状态 等待告警发送过来 |
再来关闭docker的客户端监控
1 | [root@k8s-master2 alertmanager-0.20.0.linux-amd64]# docker ps |
1 | # 新触发了一个告警 |
告警方式支持
1 | https://prometheus.io/docs/alerting/configuration/ |
告警状态
告警分配
1 | 1. 告警分配 到指定接收组 |
告警收敛(分组,抑制,静默)
1 | 分组(group): 将类似性质的警报分类为单个通知 |
分组
1 | # 10台服务器 如果都发生故障 通过分组 只发送一条通知 |
抑制
1 | 1. 一个告警产生,其他告警无需再发 |
1 | [root@k8s-master2 alertmanager-0.20.0.linux-amd64]# vim /opt/alertmanager-0.20.0.linux-amd64/alertmanager.yml |
1 | # 磁盘 80%的使用率 warning |
静默
1 | 1. 比如服务升级,一个时间内不用监控告警,可以配置静默减少,报警邮件 |
- 按照标签匹配,在一段时间内(维护时间),不设定告警邮件的发送
Prometheus一条告警怎么触发的 ?
报警处理流程如下:
- Prometheus Server 监控目标主机上暴露的http接口(这里假设接口A),通过上述Promethes配置的’scrape_interval’定义的时间间隔,定期采集目标主机上监控数据。
- 当接口A不可用的时候,Server端会持续的尝试从接口中取数据,直到”scrape_timeout”时间后停止尝试。这时候把接口的状态变为“DOWN”。
- Prometheus同时根据配置的”evaluation_interval”的时间间隔,定期(默认1min)的对Alert Rule进行评估;当到达评估周期的时候,发现接口A为DOWN,即UP=0为真,激活Alert,进入“PENDING”状态,并记录当前active的时间;
- 当下一个alert rule的评估周期到来的时候,发现UP=0继续为真,然后判断警报Active的时间是否已经超出rule里的‘for’ 持续时间,如果未超出,则进入下一个评估周期;如果时间超出,则alert的状态变为“FIRING”;同时调用Alertmanager接口,发送相关报警数据。
- AlertManager收到报警数据后,会将警报信息进行分组,然后根据alertmanager配置的“group_wait”时间先进行等待。等wait时间过后再发送报警信息。
- 属于同一个Alert Group的警报,在等待的过程中可能进入新的alert,如果之前的报警已经成功发出,那么间隔“group_interval”的时间间隔后再重新发送报警信息。比如配置的是邮件报警,那么同属一个group的报警信息会汇总在一个邮件里进行发送。
- 如果Alert Group里的警报一直没发生变化并且已经成功发送,等待‘repeat_interval’时间间隔之后再重复发送相同的报警邮件;如果之前的警报没有成功发送,则相当于触发第6条条件,则需要等待group_interval时间间隔后重复发送。
同时最后至于警报信息具体发给谁,满足什么样的条件下指定警报接收人,设置不同报警发送频率,这里有alertmanager的route路由规则进行配置。
1 | 1. 采集数据 |
编写告警规则案例
1 | # cpu使用率 要对所有的分区做统计 |
1 | # 当前值: {{ value }} |
1 | # 加上cpu和内存 |