Loading

Prometheus+Grafana+K8S

 

 

 

 

 

 

Prometheus+Grafana+K8S

 

 

 

 

 

 

 

 

 

作者

刘畅

时间

2021-07-06

 

 

 

 

 

实验环境: Centos7.5

主机名

IP

软件

controlnode

172.16.1.120

dockerprometheusgrafanaansiableconsul、alertmanager、prometheus-webhook-dingtalk

slavenode1

172.16.1.121

node-exportermysql-exporterdockermysqlcadvisor

slavenode2

172.16.1.122

node-exporter

k8s-admin

172.16.1.70

k8s主节点

k8s-node1

172.16.1.71

k8s从节点1

k8s-node2

172.16.1.72

k8s从节点2

 

 

 

目录

1 Prometheus的基本使用1

1.1 Prometheus介绍1

1.2 Prometheus组件与架构1

1.3 Prometheus部署2

1.4 Prometheus配置文件3

2 Prometheus监控案例7

2.1 如何监控服务7

2.2 Grafana部署7

2.3 监控Linux服务器9

2.4 监控systemd服务运行状态12

2.5 监控docker服务13

2.6 监控mysql服务17

3 Prometheus自动化监控20

3.1 Prometheus服务发现20

3.2 基于文件的服务发现20

3.3 基于Consul的服务发现21

3.4 Ansible+Consul实现主机自动监控24

3.5 监控kubernetes28

4 PromQL常用语句33

4.1 瞬时向量与范围向量查询33

4.2 常用操作符34

4.3 常用函数36

5 Prometheus标签管理36

5.1 标签的作用36

5.2 Metadata标签36

5.3 自定义标签36

5.4 重新标记标签37

6 Alertmanager告警40

6.1 部署Alertmanager40

6.2 配置PrometheusAlertmanager通信41

6.3 编写告警规则41

6.4 alertmanager钉钉告警43

6.5 告警触发流程51

7 Grafana可视化展示53

7.1 制作grafana导航栏53

7.2 自定义图标56

7.3 查看制作的图表59

 


1 Prometheus的基本使用

1.1 Prometheus介绍

Prometheus(普罗米修斯)是一个最初在SoundCloud上构建的监控系统。自2012年成为社区开源项目,拥有非常活跃的开发人员和用户社区。为强调开源及独立维护,Prometheus2016年加入云原生云计算基金会(CNCF),成为继Kubernetes之后的第二个托管项目。

 

Prometheus官方网站:https://prometheus.io

GitHub项目地址:https://github.com/prometheus

 

Prometheus 特点:

1) 多维数据模型: 由度量名称和键值对标识的时间序列数据

2) PromQL: 一种灵活的查询语言,可以利用多维数据完成复杂的查询

3) 不依赖分布式存储,单个服务器节点可直接工作

4) 基于HTTPpull方式采集时间序列数据

5) 推送时间序列数据通过PushGateway组件支持

6) 通过服务发现或静态配置发现目标

7) 多种图形模式及仪表盘支持(grafana)

1.2 Prometheus组件与架构

wps1 

1) Prometheus Server: 收集指标和存储时间序列数据,并提供查询接口

2) ClientLibrary: 客户端库

3) Push Gateway: 短期存储指标数据。主要用于临时性的任务

4) Exporters: 采集已有的第三方服务监控指标并暴露metrics

5) Alertmanager: 告警

6) Web UI: 简单的Web控制台

1.3 Prometheus部署

172.16.1.120节点上操作

1 二进制部署

官方文档: https://prometheus.io/docs/prometheus/latest/getting_started/

(1) 下载二进制包

下载地址: https://github.com/prometheus/prometheus/releases/download/v2.28.1/prometheus-2.28.1.linux-amd64.tar.gz

 

(2) 部署

# tar -xzf prometheus-2.28.1.linux-amd64.tar.gz

# mv prometheus-2.28.1.linux-amd64 /usr/local/prometheus

 

(3) 加入systemd管理

# vim /usr/lib/systemd/system/prometheus.service

[Unit]

Description=prometheus

[Service]

ExecStart=/usr/local/prometheus/prometheus --config.file=/usr/local/prometheus/prometheus.yml --storage.tsdb.path=/usr/local/prometheus/data

ExecReload=/bin/kill -HUP $MAINPID

KillMode=process

Restart=on-failure

[Install]

WantedBy=multi-user.target

 

# systemctl daemon-reload

# systemctl start prometheus

# systemctl enable prometheus

 

(4) 访问

http://172.16.1.120:9090/

wps2 

 

2 docker 部署

官方文档: https://prometheus.io/docs/prometheus/latest/installation/

(1) 部署

1) 将二进制安装包中的prometheus.yml配置文件上传到/opt/prometheus/config目录下

# mkdir -p /opt/prometheus/config

# cp -a /usr/local/prometheus/prometheus.yml /opt/prometheus/config/

2) 授权prometheus TSDB存储目录

# mkdir -p /opt/prometheus/data && chown -R 65534.64434 /opt/prometheus/data

3) 启动

# docker run -d \

-p 9090:9090 \

--restart=always \

--name=prometheus \

-v /opt/prometheus/config:/etc/prometheus \

-v /opt/prometheus/data:/prometheus \

prom/prometheus

 

(2) 访问

http://172.16.1.120:9090

1.4 Prometheus配置文件

参考文档: https://prometheus.io/docs/prometheus/latest/configuration/configuration/

1 prometheus命令常用参数

# /usr/local/prometheus/prometheus --help

1) --config.file=prometheus.yml# 指定配置文件

2) --web.listen-address=0.0.0.0:9090# 监听地址和端口

3) --log.level=info # 日志级别

4) --alertmanager.timeout=10s # 报警组件的超时时间

5) --storage.tsdb.path=./data/ # 数据目录,默认在当前目录的data目录下

6) --storage.tsdb.retention.time=15d # 数据保存时间,默认15

 

2 prometheus.yml默认配置

# cat /usr/local/prometheus/prometheus.yml

wps3

 

3 prometheus参数说明

wps4 

 

(1) global: 全局配置

scrape_interval: 15s # 采集数据时间间隔,默认1分钟

evaluation_interval: 15s # 评估告警规则时间间隔,默认1分钟

scrape_timeout: 10s # 采集数据超时时间,默认10

 

(2) rule_files: 告警规则

 

(3) scrape_configs:  # 配置被监控端,称为target,每个targetjob_name分组管理,又分为静态配置和服务发现。

 

(4) alerting:告警配置

 

(5) remote_write:  remote_read: # 从远程数据库读写

 

4 prometheus被监控项配置说明

wps5 

 

scrape_configs:

  - job_name: 'prometheus'

    # metrics_path defaults to '/metrics'

    # scheme defaults to 'http'.

    static_configs:

    - targets: ['localhost:9090']

targets(目标) # 被监控端

Instances(实例)# 每个被监控端称为实例

job(作业)# 具有相同目标的实例集合称为作业,也可以当作组

 

5 监控指标数据模型

1) Prometheus将所有数据存储为时间序列;

2) 具有相同度量名称以及标签属于同一个指标;

3) 每个时间序列都由度量标准名称和一组键值对(称为标签)唯一标识,通过标签查询指定指标。

4) 指标格式:  <metric name>{<label name>=<label value>,...}

2 Prometheus监控案例

2.1 如何监控服务

如果要想监控服务,前提是能获取被监控端指标数据,并且这个数据格式必须遵循Prometheus数据模型,这样才能识别和采集,一般使用exporter提供监控指标数据。

wps6 

exporter列表: https://prometheus.io/docs/instrumenting/exporters

2.2 Grafana部署

172.16.1.120节点上操作

1 Grafana介绍

Grafana是一个开源的度量分析和可视化系统。

Grafana只用于展示数据,数据源需要你根据提供数据的服务选择。

 

2 二进制部署

官方文档: https://grafana.com/grafana/download

(1) 下载二进制文件

https://dl.grafana.com/oss/release/grafana-7.5.9.linux-amd64.tar.gz

 

(2) 部署

# tar -zxf grafana-7.5.9.linux-amd64.tar.gz

# mv grafana-7.5.9 /usr/local/grafana

 

(3) grafana加入systemd管理

# vim /usr/lib/systemd/system/grafana.service

[Unit]

Description=grafana

[Service]

ExecStart=/usr/local/grafana/bin/grafana-server -homepath=/usr/local/grafana

ExecReload=/bin/kill -HUP $MAINPID

KillMode=process

Restart=on-failure

[Install]

WantedBy=multi-user.target

 

# systemctl daemon-reload

# systemctl start prometheus

# systemctl enable prometheus

 

(4) 访问

http://172.16.1.120:3000/

用户名/密码: admin/admin,第一次需要重置密码。

wps7 

 

3 docker部署

官方文档: https://grafana.com/docs/grafana/latest/installation/docker/

(1) 部署

1) 创建grafana本地存储目录并授权

# mkdir -p /opt/grafana/

# chown -R 472.472 /opt/grafana/

2) 启动

# docker run -d \

--name grafana \

-p 3000:3000 \

-v /opt/grafana:/var/lib/grafana \

--restart=always \

grafana/grafana:7.5.9

 

(2) 访问

http://172.16.1.120:3000/

 

4 连接prometheus

wps8 

2.3 监控Linux服务器

172.16.1.121122节点上操作

1 说明

node_exporter用于监控Linux系统的指标采集器。

常用指标CPU、内存、硬盘、网络流量、文件描述符、系统负载、系统服务。

数据接口: http://IP:9100

使用文档: https://prometheus.io/docs/guides/node-exporter/

GitHub:   https://github.com/prometheus/node_exporter

 

2 下载node-exporter

https://github.com/prometheus/node_exporter/releases/download/v1.1.2/node_exporter-1.1.2.linux-amd64.tar.gz

 

3 部署

# tar -xzf node_exporter-1.1.2.linux-amd64.tar.gz

# mv node_exporter-1.1.2.linux-amd64/ /usr/local/node_exporter/

 

4 node_exporter加入systemd管理

(1) 启用node_exporterHTTP认证

1) 生成加密密码

# yum install httpd-tools -y

# htpasswd -nBC 12 '' | tr -d ':\n'

New password: 123456

Re-type new password: 123456

$2y$12$k/dJzjEoHfhgOWNr/3UsY.iKtsdiE3uhXjGu4fVTzefPTkYOOH.Ka

2) 配置认证文件

# vim /usr/local/node_exporter/config.yml

basic_auth_users:

  prometheus: $2y$12$k/dJzjEoHfhgOWNr/3UsY.iKtsdiE3uhXjGu4fVTzefPTkYOOH.Ka

 

(2) 启动服务

# vim /usr/lib/systemd/system/node_exporter.service

[Unit]

Description=node_exporter

[Service]

ExecStart=/usr/local/node_exporter/node_exporter --web.config=/usr/local/node_exporter/config.yml

ExecReload=/bin/kill -HUP $MAINPID

KillMode=process

Restart=on-failure

[Install]

WantedBy=multi-user.target

 

# systemctl daemon-reload

# systemctl start node_exporter

# systemctl enable node_exporter

 

(3) 访问node_exportermetric需要密码验证

http://172.16.1.121:9100/metrics

wps9 

 

5 prometheus.yml文件中添加被监控端

172.16.1.120节点上操作

(1) 添加配置

# vim /usr/local/prometheus/prometheus.yml

……

wps10

 

(2) 验证配置是否正确

# /usr/local/prometheus/promtool check config /usr/local/prometheus/prometheus.yml

Checking /usr/local/prometheus/prometheus.yml

  SUCCESS: 0 rule files found

 

(3) 重启prometheus

# systemctl restart prometheus.service

 

6 prometheus ui界面查看target

wps11 

 

 

 

7 使用grafana展示node_exporter数据指标

仪表盘ID: 9276

wps12 

 

wps13 

2.4 监控systemd服务运行状态

172.16.1.121122节点上操作

1 将监控加入到node_exporter.service

# vim /usr/lib/systemd/system/node_exporter.service

[Unit]

Description=node_exporter

[Service]

ExecStart=/usr/local/node_exporter/node_exporter --web.config=/usr/local/node_exporter/config.yml --collector.systemd --collector.systemd.unit-include=(docker|sshd|nginx).service

ExecReload=/bin/kill -HUP $MAINPID

KillMode=process

Restart=on-failure

[Install]

WantedBy=multi-user.target

 

# systemctl daemon-reload

# systemctl restart node_exporter.service

 

2 收集数据

wps14 

2.5 监控docker服务

1 部署cadvisor

172.16.1.121节点上操作

(1) 说明

cAdvisor(Container Advisor): 用于收集正在运行的容器资源使用和性能信息。

项目地址: https://github.com/google/cadvisor

 

(2) 部署

# docker run -d \

--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 \

--restart=always \

google/cadvisor:latest

 

2 加入到prometheus.yml配置文件

172.16.1.120节点上操作

(1) 修改配置

# vim /usr/local/prometheus/prometheus.yml

wps15

 

(2) 重启prometheus

# /usr/local/prometheus/promtool check config /usr/local/prometheus/prometheus.yml

# systemctl restart prometheus.service

 

(3) prometheus UI上查看注册的docker监控实例

wps16 

 

3 添加docker监控图表

(1) 仪表盘模板ID: 193

wps17 

 

(2) 修改模板变量,实现只对docker实例进行监控

wps18 

变量:

label_values(up,instance)

 

.*8080

 

 

 

 

 

 

 

 

 

 

 

 

 

(3) 在图表中添加变量

所有图表按如下实例进行操作

wps19 

图表: 

count(container_last_seen{image!="",instance="$Node"})

 

 

 

 

 

 

 

 

 

 

 

 

(4 查看仪表盘

wps20 

2.6 监控mysql服务

172.16.1.121节点上操作

1 部署mysql

# docker run -d --name db --restart=always -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7

# docker exec -it db bash

root@4afdf5d50e76:/# mysql -uroot -p123456

mysql> grant PROCESS, REPLICATION CLIENT, SELECT ON *.* to 'exporter'@'%' identified by '123456';

mysql> exit

root@4afdf5d50e76:/# exit

 

2 部署mysqld_exporter

(1) 说明

mysql_exporter用于收集MySQL性能信息,监听端口是9104

项目地址: https://github.com/prometheus/mysqld_exporter

 

(2) 下载包

https://github.com/prometheus/mysqld_exporter/releases/download/v0.13.0/mysqld_exporter-0.13.0.linux-amd64.tar.gz

 

(3) 部署

# tar -xzf mysqld_exporter-0.13.0.linux-amd64.tar.gz

# mv mysqld_exporter-0.13.0.linux-amd64/ /usr/local/mysqld_exporter/

 

# vim /usr/lib/systemd/system/mysqld_exporter.service

[Unit]

Description=mysqld_exporter

[Service]

ExecStart=/usr/local/mysqld_exporter/mysqld_exporter --web.config.file=/usr/local/mysqld_exporter/config.yml --config.my-cnf=/usr/local/mysqld_exporter/.my.cnf

ExecReload=/bin/kill -HUP $MAINPID

KillMode=process

Restart=on-failure

[Install]

WantedBy=multi-user.target

 

# cp -a /usr/local/node_exporter/config.yml /usr/local/mysqld_exporter/

 

# cat /usr/local/mysqld_exporter/.my.cnf

[client]

user=exporter

password=123456

 

# systemctl daemon-reload

# systemctl restart mysqld_exporter.service

# systemctl enable mysqld_exporter.service

 

(4) 加入到prometheus.yml文件中

172.16.1.120节点上操作

# vim /usr/local/prometheus/prometheus.yml

wps21

 

# /usr/local/prometheus/promtool check config /usr/local/prometheus/prometheus.yml

# systemctl restart prometheus.service

 

(5) 查看prometheus UI中注册的实例

 

wps22 

 

3 添加mysql监控图表

(1) 仪表盘id使用7362

wps23 

 

(2) 查看图表

wps24 

3 Prometheus自动化监控

3.1 Prometheus服务发现

(1) Prometheus添加被监控端支持两种方式

1) 静态配置: 手动配置

2) 服务发现: 动态发现需要监控的Target实例

 

(2) 支持服务发现的来源

1) azure_sd_configs

2) consul_sd_configs

3) dns_sd_configs

4) ec2_sd_configs

5) openstack_sd_configs

6) file_sd_configs

7) gce_sd_configs

8) kubernetes_sd_configs

9) marathon_sd_configs

10) nerve_sd_configs

11) serverset_sd_configs

12) triton_sd_configs

3.2 基于文件的服务发现

172.16.1.120节点上进行操作

1 启用基于文件的服务发现

# vim /usr/local/prometheus/prometheus.yml

wps25

 

# mkdir -p /usr/local/prometheus/sd_config/

# vim /usr/local/prometheus/sd_config/file_sd.yml

- targets: ['172.16.1.121:9100', '172.16.1.122:9100']

 

# /usr/local/prometheus/promtool check config /usr/local/prometheus/prometheus.yml

 

# systemctl restart prometheus.service

 

2 prometheus UI上查看注册的实例

wps26 

3.3 基于Consul的服务发现

1 Consul说明

Consul是一个分布式的服务发现和键/值存储系统。

wps27 

 

2 部署Consul

172.16.1.120节点上操作

# docker run -d --name consul -p 8500:8500 --restart=always consul

 

# 访问consulUI

http://172.16.1.120:8500/

wps28 

 

3 Consul注册服务

172.16.1.120节点上操作

(1) 注册172.16.1.121主机

curl -X PUT -d '{"id": "172.16.1.121","name": "Linux-Server","address": "172.16.1.121","port": 9100,"tags": ["slavenode1"],"checks": [{"http": "http://172.16.1.121:9100","interval": "5s"}]}' http://172.16.1.120:8500/v1/agent/service/register

 

(2) 注册172.16.1.122主机

curl -X PUT -d '{"id": "172.16.1.122","name": "Linux-Server","address": "172.16.1.122","port": 9100,"tags": ["slavenode2"],"checks": [{"http": "http://172.16.1.122:9100","interval": "5s"}]}' http://172.16.1.120:8500/v1/agent/service/register

 

(3) 参数说明

id    # 自定义被监控实例id,可以理解为prometheus中的instance,唯一

name  # 定义的监控组,可以理解为prometheus中的job

tags # 自定义标签,可以根据项目名设置

address# 被监控实例的ip

port  # 被监控实例的端口号

checks# 检查被监控实例的状态

http://172.16.1.120:8500/v1/agent/service/register  # 注册中心访问地址

 

(4) consul UI中查看注册上的被监控实例信息

wps29 

wps30 

说明: 由于node_exporter设置了http验证,所以状态检查不通过,但是node_exporterip及端口号已经注册上来了,所以不影响prometheus读取数据。

 

补充: consul中取消注册主机的方法

Usage:

curl --request PUT http://<Consul_IP>:8500/v1/agent/service/deregister/<instance_id>

 

:

# curl --request PUT http://172.16.1.120:8500/v1/agent/service/deregister/172.16.1.121

# consul中取消已经注册上的被监控实例,则prometheus中相应监控的实例也会去除。

 

4 修改prometheus.yml文件

172.16.1.120节点上操作

# vim /usr/local/prometheus/prometheus.yml

wps31

 

# systemctl restart prometheus.service

 

5 prometheus UI中查看目标实例

wps32 

3.4 Ansible+Consul实现主机自动监控

172.16.1.120节点上操作

# pwd

/root/ansible

 

1 安装ansible

# yum install ansible -y

 

# 取消ansible主机验证

# vim /etc/ansible/ansible.cfg

host_key_checking = False

 

2 ansible配置

# tree /root/ansible

/root/ansible

├── config.yml# node_exporterhttp验证配置

├── consul-register.sh# consul注册node_exporter脚本

├── hosts# ansible主机清单

├── node_exporter-1.1.2.linux-amd64.tar.gz# node_exporter压缩包

├── node_exporter.service# node_exporter 启动服务

└── playbook.yaml# ansible playbook文件

0 directories, 6 files

 

(1) # cat config.yml

basic_auth_users:

  prometheus: $2y$12$k/dJzjEoHfhgOWNr/3UsY.iKtsdiE3uhXjGu4fVTzefPTkYOOH.Ka

 

(2) cat consul-register.sh

#!/bin/bash

instance_id=$1

service_name=$2

ip=$3

port=$4

consul_server=$5

 

curl -X PUT -d '{"id": "'"$instance_id"'","name": "'"$service_name"'","address": "'"$ip"'","port": '"$port"',"tags": ["'"$service_name"'"],"checks": [{"http": "http://'"$ip"':'"$port"'","interval": "5s"}]}' ${consul_server}

 

(3) cat hosts

[LinuxServers]

172.16.1.121 ansible_ssh_user=root ansible_ssh_pass='123456' name=slavenode1

172.16.1.122 ansible_ssh_user=root ansible_ssh_pass='123456' name=slavenode2

 

(4) cat node_exporter.service

[Unit]

Description=node_exporter

[Service]

ExecStart=/usr/local/node_exporter/node_exporter --web.config=/usr/local/node_exporter/config.yml --collector.systemd --collector.systemd.unit-include=(docker|sshd|nginx).service

ExecReload=/bin/kill -HUP $MAINPID

KillMode=process

Restart=on-failure

[Install]

WantedBy=multi-user.target

 

(5) cat playbook.yaml

- hosts: LinuxServers

  gather_facts: no

  vars:

    server_port: 9100

    consul_server: http://172.16.1.120:8500/v1/agent/service/register

 

  tasks:

  - name: 推送二进制文件

    unarchive: src=node_exporter-1.1.2.linux-amd64.tar.gz dest=/usr/local

  - name: 重命名

    shell: |

         cd /usr/local/

         if [ ! -d "node_exporter" ];then

           mv node_exporter-1.1.2.linux-amd64/ node_exporter/

         fi

  - name: 推送配置文件

    copy: src=config.yml dest=/usr/local/node_exporter

    notify:

      - restart node_exporter

  - name: 拷贝systemd文件

    copy: src=node_exporter.service dest=/usr/lib/systemd/system

    notify:

      - restart node_exporter

  - name: 启动服务

    systemd: name=node_exporter state=started enabled=yes daemon_reload=yes

  - name: 推送注册脚本

    copy: src=consul-register.sh dest=/usr/local/bin/

  - name: 注册当前节点

    # 服务名 实例名 IP 端口

    shell: /bin/bash /usr/local/bin/consul-register.sh {{ name }} {{ group_names[0] }} {{ inventory_hostname }} {{ server_port }} {{ consul_server }}

 

  handlers:

    - name: restart node_exporter

      service: name=node_exporter state=restarted

 

3 执行ansible

# ansible-playbook -i hosts playbook.yaml

wps33 

 

4 consul UI中查看注册上来的主机

wps34 

 

5 配置prometheus.yml

# vim /usr/local/prometheus/prometheus.yml

wps35

 

# systemctl restart prometheus.service

 

6 prometheus UI中查看目标实例

wps36 

3.5 监控kubernetes

1 监控说明

(1) 监控指标

Kubernetes本身监控: Node资源利用率、Node数量、Pods数量(Node)、资源对象状态

Pod监控: Pod数量(项目)、容器资源利用率、应用程序

监控指标

具体实现

举例

Node资源利用率

node-exporter

节点CPU,内存利用率

Pod资源利用率

cAdvisor

容器CPU,内存利用率

K8S资源对象状态

kube-state-metrics

PodDeploymentService

 

(2) 监控架构

服务发现类型

描述

node

发现集群中的节点,默认地址为kubeletehttp端口

service

发现所有Service及端口为目标

pod

发现所有pod为目标

endpoints

Service列表中的Endpoint发现Pod为目标

ingress

发现Ingress路径为目标

官方文档: 

https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kubernetes_sd_config

wps37 

 

2 k8s集群上部署rbac授权及kube-state-metrics

172.16.1.70节点上操作

(1) k8s RBAC授权

# kubectl apply -f rbac.yaml

 

(2) 获取Token并保存到文件

# kubectl get ServiceAccount prometheus -n kube-system -o yaml

……

secrets:

- name: prometheus-token-55pdv

 

# kubectl describe secret prometheus-token-55pdv -n kube-system >token.k8s

wps38 

清理上面的token文件,只保留"token:"以下的内容,并将该文件scp172.16.1.120节点的/opt/monitor/prometheus/目录下。

 

[root@controlnode ~]# mkdir -p /opt/monitor/prometheus/

[root@k8s-admin k8s-prometheus]# scp -p token.k8s root@172.16.1.120:/opt/monitor/prometheus/

 

(3) 部署kube-state-metrics

# kubectl apply -f kube-state-metrics.yaml

 

3 prometheus.yml文件中创建Jobkubeconfig_sd_configs

172.16.1.120节点上操作

(1) 上传配置好的prometheus.yml文件到/usr/local/prometheus/目录下。

 

(2) 修改prometheus.yml配置文件中k8s api-server的地址为现k8s集群api-server地址。

[root@k8s-admin k8s-prometheus]# kubectl get ep

NAME       ENDPOINTS          AGE

kubernetes   172.16.1.70:6443     77d

 

(3) 打通prometheus应用所在controlnode节点和k8s-admink8s-nod1k8s-node2节点的pod路由

,否则在prometheus中名为"kubernetes-service-endpoints"job会挂掉。

[root@controlnode ~]# route add -net 10.244.0.0/16 gw 172.16.1.70 dev eth1

[root@controlnode ~]# route add -net 10.244.0.0/16 gw 172.16.1.71 dev eth1

[root@controlnode ~]# route add -net 10.244.0.0/16 gw 172.16.1.72 dev eth1

 

(4) 重启prometheus

# systemctl restart prometheus.service

 

(5) prometheus UI中查看注册的target instance

wps39 

wps40 

 

4 grafana导入仪表盘

172.16.1.120节点上操作

(1) 导入K8S集群资源监控模板

wps41 

wps42 

 

(2) 导入K8S资源对象状态监控模板

wps43 

wps44 

4 PromQL常用语句

PromSQL文档:

https://yunlzheng.gitbook.io/prometheus-book/parti-prometheus-ji-chu/promql/prometheus-query-language

prometheus UI上操作

PromQL(Prometheus Query Language)Prometheus自己开发的数据查询DSL语言,语言表现力

非常丰富,支持条件查询、操作符,并且内建了大量内置函数,供我们针对监控数据的各种维度进行查询。

4.1 瞬时向量与范围向量查询

官方文档: https://prometheus.io/docs/prometheus/latest/querying/examples/

1 目标实例状态

up

wps45 

 

2 查询指标最新样本(称为瞬时向量)

node_cpu_seconds_total

 

可以通过附加一组标签来进一步过滤这些时间序列:

node_cpu_seconds_total{instance="172.16.1.121:9100",job="Linux Server",mode="system"}

wps46 

 

3 查询指标近5分钟样本(称为范围向量,时间单位为s,m,h,d,w,y)

node_cpu_seconds_total{cpu="0",instance="172.16.1.121:9100",job="Linux Server",mode="system"}[5m]

wps47 

4.2 常用操作符

官方文档: https://prometheus.io/docs/prometheus/latest/querying/operators/ 

类型

操作符

示例

比较操作符

等于

!= 不等于

大于

小于

>= 大于等于

<= 小于等于

示例1

算术操作符

+ 加法

- 减法

* 乘法

/ 除法

示例2

正则匹配操作符

=~ 正则表达式匹配

!~ 正则表达式匹配结果取反

示例3

聚合操作符

sum (在维度上求和)

max (在维度上求最大值)

min (在维度上求最小值)

avg (在维度上求平均值)

count (统计样本数量)

示例4

逻辑操作符

and

or  

示例5

示例1

node_cpu_seconds_total{job="Linux Server",mode="iowait"}

node_cpu_seconds_total{job="Linux Server",mode=~"user|system"}

node_cpu_seconds_total{job="Linux Server",mode=~"user|system",cpu!="0"}

 

示例2

CPU使用率:

100 - (avg(irate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance) * 100)

 

内存使用率:

100 - (node_memory_MemFree_bytes+node_memory_Cached_bytes+node_memory_Buffers_bytes) / node_memory_MemTotal_bytes * 100

 

示例3

磁盘使用率:

100 - (node_filesystem_free_bytes{mountpoint="/",fstype=~"ext4|xfs"} / node_filesystem_size_bytes{mountpoint="/",fstype=~"ext4|xfs"} * 100)

 

示例4

所有实例CPU system使用率总和:

sum(node_cpu_seconds_total{job="Linux Server",mode="system"})

 

所有实例CPU system变化速率平均值:

avg(irate(node_cpu_seconds_total{job="Linux Server",mode="system"}[5m]))

 

统计CPU数量:

count(node_cpu_seconds_total{job="Linux Server",mode="system"})

 

示例5

大于10并且小于50:

prometheus_http_requests_total > 10 and prometheus_http_requests_total < 50

大于10或者小于50:

prometheus_http_requests_total > 10 or prometheus_http_requests_total < 50

4.3 常用函数

官方文档: https://prometheus.io/docs/querying/functions/

irate(): 计算指标在一定时间间隔内的变化速率。

示例:

irate(node_cpu_seconds_total{job="Linux Server",mode="system"}[5m])

wps48 

5 Prometheus标签管理

172.16.1.120节点上操作

5.1 标签的作用

Prometheus中存储的数据为时间序列,是由Metric的名字和一系列的标签(键值对)唯一标识的,

不同的标签代表不同的时间序列,即通过指定标签查询指定数据。

5.2 Metadata标签

Prometheus所有的Target实例中,都包含一些默认的Metadata标签信息。可以通过

Prometheus UITargets页面中查看这些实例的Metadata标签的内容。

__address__# 当前Target实例的访问地址<host>:<port>

__metrics_path__# 采集目标服务访问地址的访问路径

__scheme__# 采集目标服务访问地址的HTTP SchemeHTTP或者HTTPS

 

wps49 

 

上面这些标签将会告诉Prometheus如何从该Target实例中获取监控数据。除了这些默认的标签

以外,我们还可以为Target添加自定义的标签。

5.3 自定义标签

1 修改prometheus.yml文件

# vim /usr/local/prometheus/prometheus.yml

wps50

 

2 重启prometheus

# systemctl restart prometheus.service

 

3 prometheus UI中查看新增的标签

wps51 

5.4 重新标记标签

1 为什么要重新标记标签

(1) 重新标记标签的目的是为了更好的标识监控指标。

 

(2) 在两个阶段可以重新标记

1) relabel_configs# 在采集之前

准备抓取指标数据时,可以使用relabel_configs添加一些标签、也可以只采集特定目标或过滤目标。

2) metric_relabel_configs# 在存储之前

已经抓取到指标数据时,可以使用metric_relabel_configs做最后的重新标记和过滤。 

wps52 

 

(3) 重新标记标签的一般途径

动态生成新标签、过滤采集的Target、删除不需要或者敏感标签、添加新标签

 

(4) action重新标记标签动作

1) replace# 默认,通过regex匹配source_label的值,使用replacement来引用表达式

匹配的分组,分组使用$1,$2...引用,标签值。

2) keep# 删除regex与连接不匹配的目标 source_labels,标签值

3) drop# 删除regex与连接匹配的目标 source_labels,标签值

4) labeldrop# 删除regex匹配的标签,标签名称

5) labelkeep# 删除regex不匹配的标签,标签名称

6) labelmap# 匹配regex所有标签名称,并将捕获的内容分组,用第一个分组内容作为

新的标签名。

 

2 重命名标签

在采集标签之前对已有的标签重新标记,动态添加新的标签

(1) 修改prometheus.yml文件

# vim /usr/local/prometheus/prometheus.yml

wps53

 

(2) 重启prometheus

# systemctl restart prometheus.service

 

(3) prometheus UI中查看

wps54 

 

3 过滤Target

在采集标签之前,删除采集的target

(1) 修改prometheus.yml文件

# vim /usr/local/prometheus/prometheus.yml

wps55

 

(2) 重启prometheus

# systemctl restart prometheus.service

 

(3) prometheus UI中查看

wps56 

 

4 删除标签

删除不需要或者敏感的标签

在收集标签之前删除标签

(1) 修改prometheus.yml文件

# vim /usr/local/prometheus/prometheus.yml

wps57

 

(2) 重启prometheus

# systemctl restart prometheus.service

 

(3) prometheus UI中查看

wps58 

6 Alertmanager告警

172.16.1.120节点上操作

6.1 部署Alertmanager

官方文档: https://github.com/prometheus/alertmanager

1 安装包下载

下载地址: 

https://github.com/prometheus/alertmanager/releases/download/v0.22.2/alertmanager-0.22.2.linux-amd64.tar.gz

 

2 alertmanager加入到systemd

# tar -xzf alertmanager-0.22.2.linux-amd64.tar.gz

# mv alertmanager-0.22.2.linux-amd64/ /usr/local/alertmanager/

 

# vim /usr/lib/systemd/system/alertmanager.service

[Unit]

Description=grafana

[Service]

ExecStart=/usr/local/alertmanager/alertmanager --config.file=/usr/local/alertmanager/alertmanager.yml

ExecReload=/bin/kill -HUP $MAINPID

KillMode=process

Restart=on-failure

[Install]

WantedBy=multi-user.target

 

# systemctl daemon-reload

# systemctl start alertmanager.service

# systemctl enable alertmanager.service

 

# netstat -tunlp | grep alertmanager

wps59 

6.2 配置PrometheusAlertmanager通信

wps60 

 

1 配置prometheus.yml

# vim /usr/local/prometheus/prometheus.yml

wps61

 

2 重启prometheus

# systemctl restart prometheus.service

6.3 编写告警规则

1 配置prometheus.yml

# vim /usr/local/prometheus/prometheus.yml

wps62

 

# mkdir -p /usr/local/prometheus/rules

 

2 编写rule规则

(1) 监控实例状态

# cat /usr/local/prometheus/rules/general.yml

groups:

- name: general.rules       # 告警规则组名称

  rules:

  - alert: InstanceDown     # 告警规则名称,alertname

    expr: up == 0           # 基于PromQL的触发条件

    for: 2m                 # 规则触发持续多长时间发送告警

    labels:                 # 自定义标签

      severity: critical    # 告警级别,warning

    annotations:            # 告警附加信息

      summary: "Instance {{ $labels.instance }} 停止工作"

      description: "{{ $labels.instance }}: job {{ $labels.job }} 已经停止5分钟以上."

 

(2) 监控cpu、内存、磁盘使用率

# cat /usr/local/prometheus/rules/node.yml

groups:

- name: node.rules

  rules:

  - alert: NodeFilesystemUsage

    expr: 100 - (node_filesystem_free_bytes{fstype=~"ext4|xfs"} / node_filesystem_size_bytes{fstype=~"ext4|xfs"} * 100) > 80

    for: 2m

    labels:

      severity: warning

    annotations:

      summary: "{{$labels.instance}}: {{$labels.mountpoint }} 分区使用过高"

      description: "{{$labels.instance}}: {{$labels.mountpoint }} 分区使用大于 80% (当前值: {{ $value }})"

  - alert: NodeMemoryUsage

    expr: 100 - (node_memory_MemFree_bytes+node_memory_Cached_bytes+node_memory_Buffers_bytes) / node_memory_MemTotal_bytes * 100 > 80

    for: 2m

    labels:

      severity: warning

    annotations:

      summary: "{{$labels.instance}}: 内存使用过高"

      description: "{{$labels.instance}}: 内存使用大于 80% (当前值: {{ $value }})"

  - alert: NodeCPUUsage

    expr: 100 - (avg(irate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance) * 100) > 80

    for: 2m

    labels:

      severity: warning

    annotations:

      summary: "{{$labels.instance}}: CPU使用过高"

      description: "{{$labels.instance}}: CPU使用大于 80% (当前值: {{ $value }})"

 

3 重启prometheus

# systemctl restart prometheus.service

 

4 prometheus UI中查看告警规则

wps63 

# 没有触发任何警告

wps64 

6.4 alertmanager钉钉告警

参考文档: https://github.com/timonwong/prometheus-webhook-dingtalk

 

1 安装prometheus-webhook-dingtalk插件(二进制)

# wget \

https://github.com/timonwong/prometheus-webhook-dingtalk/releases/download/v1.4.0/prometheus-webhook-dingtalk-1.4.0.linux-amd64.tar.gz

# tar -xzf prometheus-webhook-dingtalk-1.4.0.linux-amd64.tar.gz

# mv prometheus-webhook-dingtalk-1.4.0.linux-amd64/ /usr/local/prometheus-webhook-dingtalk/

 

2 钉钉创建机器人并获取tokensecret(加签)

点击钉钉右上角加号(+) >>> 选择"发起群聊" >>> 选择"项目群" >>> 填写"群名称" 

>>> 点击"创建" >>> 点击"群设置" >>> 选择"智能群助手" >>> 选择"添加机器人"

>>> 选择"自定义"机器人 >>> 点击"添加" >>> 后续如下截图

wps65 

加签: SEC530dfec7dcde0c8c31c98196fedf9c8c7ae767336ce3267bf8f6e94df78131bf

 

wps66 

webhook:

https://oapi.dingtalk.com/robot/send?access_token=a9285933068d63b3612d4f3caf2da1cfc85fc7ebf09ae04ce38955f76bec597f

 

3 配置prometheus-webhook-dingtalk

(1) 配置config.yml

# cd /usr/local/prometheus-webhook-dingtalk/

# cp -a config.example.yml config.yml

# vim config.yml

## Request timeout

timeout: 10s

 

## Customizable templates path

templates:

  - /usr/local/prometheus-webhook-dingtalk/template.tmpl

 

## Targets, previously was known as "profiles"

targets:

  webhook1:

    url: https://oapi.dingtalk.com/robot/send?access_token=a9285933068d63b3612d4f3caf2da1cfc85fc7ebf09ae04ce38955f76bec597f

    secret: SEC530dfec7dcde0c8c31c98196fedf9c8c7ae767336ce3267bf8f6e94df78131bf

    mention:

      all: true

(2) 配置告警模板template.tmpl

{{ define "__subject" }}[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .GroupLabels.SortedPairs.Values | join " " }} {{ if gt (len .CommonLabels) (len .GroupLabels) }}({{ with .CommonLabels.Remove .GroupLabels.Names }}{{ .Values | join " " }}{{ end }}){{ end }}{{ end }}

{{ define "__alertmanagerURL" }}{{ .ExternalURL }}/d/9CWBz0bik/k8sji-qun-shou-ye?orgId=1 {{ end }}

 

{{ define "__text_alert_list" }}{{ range . }}

**Labels**

{{ range .Labels.SortedPairs }}> - {{ .Name }}: {{ .Value | markdown | html }}

{{ end }}

**Annotations**

{{ range .Annotations.SortedPairs }}> - {{ .Name }}: {{ .Value | markdown | html }}

{{ end }}

**Source:** [{{ .GeneratorURL }}]({{ .GeneratorURL }})

{{ end }}{{ end }}

 

{{ define "default.__text_alert_list" }}{{ range . }}

---

**告警级别:** {{ .Labels.severity | upper }}

 

**触发时间:** {{ dateInZone "2006.01.02 15:04:05" (.StartsAt) "Asia/Shanghai" }}

 

**事件信息:**

{{ range .Annotations.SortedPairs }}> - {{ .Name }}: {{ .Value | markdown | html }}   

 

{{ end }}{{ end }}

{{ end }}

 

{{ define "default.__text_alertresolve_list" }}{{ range . }}

---

**告警级别:** {{ .Labels.severity | upper }}

 

**触发时间:** {{ dateInZone "2006.01.02 15:04:05" (.StartsAt) "Asia/Shanghai" }}

 

**结束时间:** {{ dateInZone "2006.01.02 15:04:05" (.EndsAt) "Asia/Shanghai" }}

 

**事件信息:**

{{ range .Annotations.SortedPairs }}> - {{ .Name }}: {{ .Value | markdown | html }}   

 

{{ end }}{{ end }}

{{ end }}

 

{{/* Default */}}

{{ define "default.title" }}{{ template "__subject" . }}{{ end }}

{{ define "default.content" }}#### \[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}\] **[{{ index .GroupLabels "alertname" }}]({{ template "__alertmanagerURL" . }})**

 

{{ if gt (len .Alerts.Firing) 0 -}}

![警报 图标](http://wx4.sinaimg.cn/large/006APoFYly1g0ggpt1aq3j306o06o3yt.jpg)

 

**=====侦测到故障=====**

{{ template "default.__text_alert_list" .Alerts.Firing }}

{{- end }}

 

{{ if gt (len .Alerts.Resolved) 0 -}}

![警报 图标](https://i01piccdn.sogoucdn.com/2dbf8a9d48e921e7)

 

**=====故障已修复=====**

{{ template "default.__text_alertresolve_list" .Alerts.Resolved }}

{{- end }}

{{- end }}

 

{{/* Legacy */}}

{{ define "legacy.title" }}{{ template "__subject" . }}{{ end }}

{{ define "legacy.content" }}#### \[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}\] **[{{ index .GroupLabels "alertname" }}]({{ template "__alertmanagerURL" . }})**

{{ template "__text_alert_list" .Alerts.Firing }}

{{- end }}

 

{{/* Following names for compatibility */}}

{{ define "ding.link.title" }}{{ template "default.title" . }}{{ end }}

{{ define "ding.link.content" }}{{ template "default.content" . }}{{ end }}

 

补充: template.tmpl中包含了"/d/9CWBz0bik/k8sji-qun-shou-ye?orgId=1,这正是 grafana url。因为 alertmanager --web.external-url

 

(3) prometheus-webhook-dingtalk加入到systemd管理

# vim /usr/lib/systemd/system/prometheus-webhook-dingtalk.service

[Unit]

Description=prometheus-webhook-dingtalk-1.4.0

 

[Service]

ExecStart=/usr/local/prometheus-webhook-dingtalk/prometheus-webhook-dingtalk --config.file=/usr/local/prometheus-webhook-dingtalk/config.yml --web.enable-ui

ExecReload=/bin/kill -HUP $MAINPID

KillMode=process

Restart=on-failure

 

[Install]

WantedBy=multi-user.target

 

# systemctl daemon-reload

# systemctl restart prometheus-webhook-dingtalk.service

# systemctl enable prometheus-webhook-dingtalk.service

# netstat -tunlp | grep prometheus-web

wps67 

 

(4) 访问http://172.16.1.120:8060/ui/进行模板验证

wps68 

 

4 将钉钉接入Prometheus AlertManager WebHook

# vim /usr/local/alertmanager/alertmanager.yml

global:

  resolve_timeout: 1m     # 1分钟检查一次状态是否恢复

route:                    # 配置路由树

  group_by: ['alertname'] # 根据告警规则名进行分组

  group_wait: 15s         # 组告警等待时间,也就是告警产生后等待10s,如果有同组告警一起发出

  group_interval: 15s     # 两组告警的间隔时间

  repeat_interval: 1h     # 重复告警的间隔时间,减少相同告警的发送频率

  receiver: 'web.hook'    # 配置告警消息接受者信息

receivers:

- name: 'web.hook'        # 告警接受者

  webhook_configs:

  - send_resolved: true   # 告警被解决之后通知

    url: 'http://172.16.1.120:8060/dingtalk/webhook1/send'  # 钉钉告警插件地址

 

inhibit_rules:              # 抑制规则配置,当存在与另一组匹配的警报()时,抑制规则将禁用与一组匹配的警报(目标)

  - source_match:

      severity: 'critical'  # 指定告警级别

    target_match:

      severity: 'warning'   # 指定抑制告警级别

    equal: ['alertname', 'instance']

 

#####################

# 1 例如收到一条告警

# alertname=down level=critical instance=172.16.1.120:9100 job=Linux Server

# 2 进入抑制处理流程

# 3 判断告警带 level=critical 这个标签

# 4 抑制带有 level=warning 标签的告警

# 5 这两条规则必须满足相同的标签 alertname=down instance=172.16.1.120:9100

# 6 不发送告警

# ##################

 

# systemctl restart alertmanager.service

 

5 测试

(1) 停掉172.16.1.121实例

查看prometheus Alerts界面,发现触发了告警,告警处于PENDING状态。

wps69 

 

(2) 等待大概4分钟左右,钉钉收到告警邮件

wps70 

 

(3) 恢复172.16.1.121实例后,钉钉收到恢复告警邮件

wps71 

 

6 补充: 使用源码安装

(1) 安装依赖

1) 安装Go

官方文档: https://golang.org/doc/install#install

# wget https://golang.org/dl/go1.16.6.linux-amd64.tar.gz

# rm -rf /usr/local/go && tar -C /usr/local -xzf go1.16.6.linux-amd64.tar.gz

# echo 'export PATH=/usr/local/go/bin:$PATH' >> /etc/profile

# source /etc/profile

# go version

2) 安装Nodejs

官方文档: https://github.com/nodejs/help/wiki/Installation

# wget https://nodejs.org/dist/v14.17.3/node-v14.17.3-linux-x64.tar.xz

# tar -xJf node-v14.17.3-linux-x64.tar.xz

# mv node-v14.17.3-linux-x64/ /usr/local/nodejs/

# echo 'export PATH=/usr/local/nodejs/bin:$PATH' >> /etc/profile

# source /etc/profile

# node -v

v14.17.3

# npx -v

6.14.13

# npm version

wps72 

3) 安装Yarn

官方文档: https://yarnpkg.com/getting-started/install

# npm install -g yarn

# yarn -v

1.22.10

 

(2) 下载源码并编译

# git clone https://github.com/timonwong/prometheus-webhook-dingtalk.git

# cd prometheus-webhook-dingtalk/

# make build

 

(4) 配置

# mkdir -p /usr/local/prometheus-webhook-dingtalk/

# cp -a prometheus-webhook-dingtalk /usr/local/prometheus-webhook-dingtalk/

# vim /usr/local/prometheus-webhook-dingtalk/config.yml

# vim /usr/local/prometheus-webhook-dingtalk/template.tmpl

# vim /usr/lib/systemd/system/prometheus-webhook-dingtalk.service

6.5 告警触发流程

(1) 告警状态说明

Inactive# 这里什么都没有发生。

Pending# 已触发阈值,但未满足告警持续时间。

Firing# 已触发阈值且满足告警持续时间,警报发送给接受者。

wps73 

 

(2) 告警收敛

分组(group)# 将类似性质的警报分类为单个通知

抑制(Inhibition)# 当警报发出后,停止重复发送由此警报引发的其他警报

静默(Silences)# 是一种简单的特定时间静音提醒的机制

wps74 

 

(3) 告警流程

wps75 

 

prometheus处理告警时间:

1) 指标采集间隔时长(scrape_interval: 15s)

2) 根据告警规则对采集指标评估的间隔时长(evaluation_interval: 15s)

3) 告警持续等待时间,在告警规则内自定义时长(for: 2m)

 

AlertManger处理告警时间: 

1) 分组等待时长(group_wait: 15s)

2) 告警发送间隔时长(group_interval: 15s)

 

(4) altermanager静默设置

wps76 

7 Grafana可视化展示

7.1 制作grafana导航栏

1 创建一个名为linux_dashboard的表盘

wps77 

 

2 添加变量

wps78 

 

(1) 添加分组变量

wps79 

 

 

 

(2) 添加Target实例变量

wps80 

 

3 查看添加的导航栏

wps81 

 

 

 

7.2 自定义图标

以下图表的制作只提供参考之用,具体可以参考官网做好的模板

1 stat(单个统计)

(1) 统计cpu个数

wps82 

count(node_cpu_seconds_total{instance=~"$node", mode='system'})

wps83 

wps84 

 

(2) 统计内存总量

wps85 

node_memory_MemTotal_bytes{instance=~"$node"}

 

wps86 

wps87 

 

2 gauge(百分比,1分钟cpu使用率)

 

wps88 

100 - (avg(irate(node_cpu_seconds_total{instance=~"$node",mode="idle"}[1m])) * 100)

 

wps89 

 

wps90 

7.3 查看制作的图表

wps91 

posted @ 2021-07-14 19:01  云起时。  阅读(551)  评论(0编辑  收藏  举报