Prometheus

metrics Server 提供核心监控指标,比如Node节点的CPU和内存使用率,其他的监控交由 Prometheus 组件完成

简介

官网:https://prometheus.io/docs/introduction/overview/
github:https://github.com/prometheus

prometheus是基于go语言开发的一套开源的监控、报警和时间序列数据库的组合,是由SoundCloud公司开发的
开源监控系统,prometheus是CNCF(Cloud Native Computing Foundation,云原生计算基金会)继kubernetes 之后毕业的第二个项目,prometheus在容器和微服务领域中得到了广泛的应用,其特点主要如下:

- 使用 key-value 的多维度格式保存数据
- 数据不使用 MySQL 这样的传统数据库,而是使用时序数据库,目前是使用的 TSDB
- 支持第三方 dashboard 实现更高的图形界面,如 grafana(Grafana 2.5.0版本及以上)
- 功能组件化
- 不需要依赖存储,数据可以本地保存也可以远程保存
- 服务自动化发现
- 强大的数据查询语句功(PromQL:Prometheus Query Language)

TSDB

TSDB:Time Series Database,时间序列数据库,简称时序数据库

什么是时序数据库?顾名思义,就是存储与时间相关的数据,该数据是在时间上分布的一系列值

时序数据库被广泛应用于物联网和运维监控系统

这个网站可以查看各种时序数据库的排名:

小而精,性能高,数据量较小(亿级): InfluxDB
简单,数据量不大(千万级),有联合查询、关系型数据库基础:timescales
数据量较大,大数据服务基础,分布式集群需求: opentsdb、KairosDB
分布式集群需求,olap实时在线分析,资源较充足:druid
性能极致追求,数据冷热差异大:Beringei
兼顾检索加载,分布式聚合计算: elsaticsearch
如果你兼具索引和时间序列的需求。那么Druid和Elasticsearch是最好的选择。其性能都不差,同时满足检索和时间序列的特性,并且都是高可用容错架构。

阿里云版TSDB,文档写的还不错:https://help.aliyun.com/product/54825.html

Prometheus内置了TSDB,目前是V3.0版本,是一个独立维护的TSDB开源项目;在单机上,每秒可处理数百万个样本

Prometheus TSDB数据存储格式:

  • 以每2小时为一个时间窗口,并存储为一个单独的block
  • block会压缩、合并历史数据块,随着压缩合并,其block数量会减少
  • block的大小并不固定,但最小会保存两个小时的数据

P137

PromQL

https://songjiayang.gitbooks.io/prometheus/content/promql/summary.html

PromQL:Prometheus Query Language,是 Prometheus 自己开发的数据查询 DSL 语言,语言表现力非常丰富,内置函数很多,在日常数据可视化以及rule 告警中都会使用到它

系统架构

prometheus server:主服务,接受外部http请求,收集、存储与查询数据等
prometheus targets: 静态收集的目标服务数据
service discovery:动态发现服务
prometheus alerting:报警通知
push gateway:数据收集代理服务器(类似于zabbix proxy)
data visualization and export: 数据可视化与数据导出(访问客户端)

安装

三种安装方式:docker、二进制、operator

https://prometheus.io/download/ #官方二进制下载及安装,prometheus server的监听端口为9090
https://prometheus.io/docs/prometheus/latest/installation/ #docker镜像直接启动
https://github.com/coreos/kube-prometheus #operator部署

一般不使用docker安装,推荐operator,但是operator安装会隐藏很多细节,所以要先学习二进制安装

https://github.com/prometheus/prometheus/releases/download/v2.25.2/prometheus-2.25.2.linux-amd64.tar.gz
https://github.com/prometheus/alertmanager/releases/download/v0.21.0/alertmanager-0.21.0.linux-amd64.tar.gz
https://github.com/prometheus/blackbox_exporter/releases/download/v0.18.0/blackbox_exporter-0.18.0.linux-amd64.tar.gz
https://github.com/prometheus/consul_exporter/releases/download/v0.7.1/consul_exporter-0.7.1.linux-amd64.tar.gz
https://github.com/prometheus/graphite_exporter/releases/download/v0.9.0/graphite_exporter-0.9.0.linux-amd64.tar.gz
https://github.com/prometheus/haproxy_exporter/releases/download/v0.12.0/haproxy_exporter-0.12.0.linux-amd64.tar.gz
https://github.com/prometheus/memcached_exporter/releases/download/v0.8.0/memcached_exporter-0.8.0.linux-amd64.tar.gz
https://github.com/prometheus/mysqld_exporter/releases/download/v0.12.1/mysqld_exporter-0.12.1.linux-amd64.tar.gz
https://github.com/prometheus/node_exporter/releases/download/v1.1.2/node_exporter-1.1.2.linux-amd64.tar.gz
https://github.com/prometheus/pushgateway/releases/download/v1.4.0/pushgateway-1.4.0.linux-amd64.tar.gz
https://github.com/prometheus/statsd_exporter/releases/download/v0.20.0/statsd_exporter-0.20.0.linux-amd64.tar.gz

prometheus server

[root@k8s-master src]$tar zxf prometheus-2.25.2.linux-amd64.tar.gz
[root@k8s-master src]$mv prometheus-2.25.2.linux-amd64 /usr/local/prometheus
[root@k8s-master src]$cd /usr/local/prometheus/

# service启动文件
[root@k8s-master prometheus]$vim /lib/systemd/system/prometheus.service
[Unit]
Description=Prometheus Server
Documentation=https://prometheus.io/docs/introduction/overview/
After=network.target
[Service]
Restart=on-failure
WorkingDirectory=/usr/local/prometheus/
ExecStart=/usr/local/prometheus/prometheus --
config.file=/usr/local/prometheus/prometheus.yml
[Install]
WantedBy=multi-user.target

[root@k8s-master prometheus]$systemctl daemon-reload
[root@k8s-master prometheus]$systemctl start prometheus.service

node exporter

收集各k8s node节点上的监控指标数据,监听端口为9100

node exporter 和 metrics server

原理都是一样的,都是从node的kublete获取数据,但是node exporter 从本机的kubelet获取数据,metrics server 从所有node的kubelet获取数据,所以 node exporter 需要在每个node都部署一份,而metrics server只部署一个就可以

安装:

在每个node都执行以下安装步骤:

$tar zxf node_exporter-1.1.2.linux-amd64.tar.gz
$mv node_exporter-1.1.2.linux-amd64 /usr/local/node_exporter
$cd /usr/local/node_exporter/

$vim /etc/systemd/system/node-exporter.service
[Unit]
Description=Prometheus Node Exporter
After=network.target
[Service]
ExecStart=/usr/local/node_exporter/node_exporter
[Install]
WantedBy=multi-user.target

$systemctl daemon-reload 
$systemctl start node-exporter.service 

$ss -ntlp | grep 9100
LISTEN   0   32768   *:9100   *:*   users:(("node_exporter",pid=115111,fd=3)) 

与 prometheus 集成:

在prometheus server中添加一个job:

[root@k8s-master prometheus]$pwd
/usr/local/prometheus              
[root@k8s-master prometheus]$grep -v "#" prometheus.yml | grep -v "^$"
global:
alerting:
  alertmanagers:
  - static_configs:
    - targets:
rule_files:
scrape_configs:
  - job_name: 'prometheus'
    static_configs:
    - targets: ['localhost:9090']
  - job_name: 'promethues-node'		# job名称
    metrics_path: '/metrics'		# 默认就是 /metrics
    static_configs:
     - targets: ['10.0.1.31:9100', '10.0.1.32:9100', '10.0.1.33:9100']	# 被采集的node

重启 prometheus ,等一会然后观察监控情况:

haproxy exporter

除了 node_exporter,官方还提供了监控haproxy的exporter

  1. 需要将其部署在haproxy服务所在的节点

    tar xvf haproxy_exporter-0.12.0.linux-amd64.tar.gz
  2. prometheus添加haproxy数据采集

    - job_name: "prometheus-haproxy"
      static_configs:
        - targets: ["192.168.7.108:9101"]
  3. grafana添加模板

    367 2428

其他 exporter

如果官方没有提供监控相应服务的exporter,需要使用第三方或自己开发

https://github.com/zhangguanzhang/harbor_exporter
https://github.com/nginxinc/nginx-prometheus-exporter/

Grafana

调用prometheus的数据,进行更专业的可视化

cAdvisor

https://www.oschina.net/p/cadvisor

cAdvisor是由谷歌开源的 docker容器性能分析工具,cAdvisor可以对节点机器上的资源及容器进行实时监控和性能数据采集,包括CPU使用情况、内存使用情况、网络吞吐量及文件系统使用情况,cAdvisor不仅可以搜集一台机器上所有运行的容器信息,还提供基础查询界面和http接口,方便其他组件如prometheus进行数据抓取

k8s1.12之前cadvisor集成在node节点的上kubelet服务中,从1.12版本开始分离为两个组件,因此需要在node节点单独部署cadvisor

官方github给出部署方法,可是需要pull国外的镜像

# cadvisor镜像准备
$docker load -i cadvisor_v0.36.0.tar.gz
$docker tag gcr.io/google_containers/cadvisor:v0.36.0 harbor.ljk.local/k8s/cadvisor:v0.36.0
$docker push harbor.ljk.local/k8s/cadvisor:v0.36.0 

# 在每个节点 启动cadvisor容器
VERSION=v0.36.0
sudo docker run \
  --volume=/:/rootfs:ro \
  --volume=/var/run:/var/run:ro \
  --volume=/sys:/sys:ro \
  --volume=/var/lib/docker/:/var/lib/docker:ro \
  --volume=/dev/disk/:/dev/disk:ro \
  --publish=8080:8080 \
  --detach=true \
  --name=cadvisor \
  --privileged \
  --device=/dev/kmsg \
harbor.ljk.local/k8s/cadvisor:${VERSION}

prometheus采集cadvisor数据

[root@k8s-master prometheus]$grep -v "#" prometheus.yml | grep -v "^$"
global:
alerting:
  alertmanagers:
  - static_configs:
    - targets:
rule_files:
scrape_configs:
  - job_name: 'prometheus'
    static_configs:
    - targets: ['localhost:9090']
  - job_name: 'promethues-node'
    metrics_path: '/metrics'
    static_configs:
     - targets: ['10.0.1.31:9100', '10.0.1.32:9100', '10.0.1.33:9100']
  - job_name: 'promethues-containers'
    metrics_path: '/metrics'
    static_configs:
     - targets: ['10.0.1.32:8080', '10.0.1.33:8080']	# cadvisor采集的node

grafana添加pod监控模板

395 893 容器模板ID

prometheus报警设置

prometheus触发一条告警的过程:

prometheus-->触发阈值-->超出持续时间-->alertmanager-->分组|抑制|静默-->媒体类型-->邮件|钉钉|微信等

分组(group): 将类似性质的警报合并为单个通知
静默(silences): 是一种简单的特定时间静音的机制,例如:服务器要升级维护可以先设置这个时间段告警静默
抑制(inhibition): 当警报发出后,停止重复发送由此警报引发的其他警报即合并一个故障引起的多个报警事件,可以消除冗余告警

安装 alertmanager

[root@k8s-master src]$tar zxf alertmanager-0.21.0.linux-amd64.tar.gz 
[root@k8s-master src]$mv alertmanager-0.21.0.linux-amd64 /usr/local/alertmanager
[root@k8s-master src]$cd /usr/local/alertmanager/

配置 alertmanager

官方配置文档:https://prometheus.io/docs/alerting/configuration/

[root@k8s-master alertmanager]$cat alertmanager.yml 
global:
  resolve_timeout: 5m
  smtp_smarthost: "smtp.qq.com:465"
  smtp_from: "441757636@qq.com"
  smtp_auth_username: "441757636@qq.com"
  smtp_auth_password: "udwthuyxjstcdhcj"	# 授权码随便写的
  smtp_hello: "@qq.com"
  smtp_require_tls: false
route: #设置报警的分发策略
  group_by: ["alertname"] #采用哪个标签来作为分组依据
  group_wait: 10s #组告警等待时间。也就是告警产生后等待10s,如果有同组告警一起发出
  group_interval: 10s #两组告警的间隔时间
  repeat_interval: 2m #重复告警的间隔时间,减少相同邮件的发送频率
  receiver: "web.hook" #设置接收人,这个接收人在下面会有定义
receivers:	# 定义接收人
  - name: "web.hook"	# 定义接收人:web.hook,这里定义为接收人是一个邮箱
    #webhook_configs:
    #- url: 'http://127.0.0.1:5001/'
    email_configs:
      - to: "2973707860@qq.com"
inhibit_rules: #禁止的规则
  - source_match: #源匹配级别
      severity: "critical"
    target_match:
      severity: "warning"
    equal: ["alertname", "dev", "instance"]

启动 alertmanager

# 二进制启动
$./alertmanager --config.file=./alertmanager.yml

# service启动
$vim /lib/systemd/system/alertmanager.service
[Unit]
Description=Prometheus Server
Documentation=https://prometheus.io/docs/introduction/overview/
After=network.target
[Service]
Restart=on-failure
WorkingDirectory=/usr/local/prometheus/
ExecStart=/usr/local/prometheus/prometheus --config.file=/usr/local/prometheus/prometheus.yml
[Install]
WantedBy=multi-user.target

$lsof -i:9093		# 监听9093端口
COMMAND     PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
alertmana 53151 root    9u  IPv6 195688      0t0  TCP *:9093 (LISTEN)

报警规则文件示例

groups:					
  - name:				# 警报规则组的名称
    rules:
      - alert:			# 警报规则的名称
        expr:			# 使用PromQL表达式完成的警报触发条件,用于计算是否有满足触发条件
        for:			# 触发报警条件,等一段时间(pending)再报警
        labels:			# 自定义标签,允许自行定义标签附加在警报上
        annotations:	# 设置有关警报的一组描述信息,其中包括自定义的标签,以及expr计算后的值
[root@k8s-master prometheus]$pwd
/usr/local/prometheus
[root@k8s-master prometheus]$vim rule.yml
groups:
  - name: linux_pod.rules
    rules:
      - alert: Pod_all_cpu_usage
        expr: (sum by(name)(rate(container_cpu_usage_seconds_total{image!=""}[5m]))*100) > 75
        for: 5m
        labels:
          severity: critical
          service: pods
        annotations:
          description: 容器 {{ $labels.name }} CPU 资源利用率大于 75% , (current value is {{ $value }})
          summary: Dev CPU 负载告警
      - alert: Pod_all_memory_usage
        expr: sort_desc(avg by(name)(irate(container_memory_usage_bytes{name!=""}[5m]))*100) > 1024*10^3*2
        for: 10m
        labels:
          severity: critical
        annotations:
          description: 容器 {{ $labels.name }} Memory 资源利用率大于 2G , (current value is {{ $value }})
          summary: Dev Memory 负载告警
      - alert: Pod_all_network_receive_usage
        expr: sum by (name)(irate(container_network_receive_bytes_total{container_name="POD"}[1m])) > 1024*1024*50
        for: 10m
        labels:
          severity: critical
        annotations:
          description: 容器 {{ $labels.name }} network_receive 资源利用率大于 50M , (current value is {{ $value }})

配置prometheus

$cat prometheus.yml 
...
# Alertmanager configuration
alerting:
  alertmanagers:
    - static_configs:
        - targets:
            - 10.0.1.31:9093 #alertmanager地址

# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
  # - "first_rules.yml"
  - "/usr/local/prometheus/rule.yml" #指定规则文件

...

# 验证报警规则
[root@k8s-master prometheus]$./promtool check rules ./rule.yml
Checking ./rule.yml
  SUCCESS: 3 rules found
# 重启prometheus
[root@k8s-master prometheus]$systemctl restart prometheus