手把手教你搭建监控系统

dark-1850638_1280.jpg

前言

我们为什么要做监控?

就比如马路上边的各种摄像头,它能监控车流量,监控交通故障等。出现故障可以第一时间确定发生地点。当然,在我们这里领域里,监控也是起着同样的作用。它也能帮助我们监控业务流量,业务健康状态,服务器状态等等,一套成熟的监控体系将会给我们运维、开发人员带来极大便利性。

本文将介绍如何搭建一套目前企业较为流行的持久化监控系统,将使用Influxdb作为prometheus持久化存储。

主要架构:Kubernetes+Prometheus+Influxdb+Grafana+Prometheus-alert

架构图如下:

prometheus.png

环境介绍

  • 操作系统:Centos7.6
  • Kubernetes: v1.20.5
  • Helm: v3.5.4
  • Prometheus: v2.19.0
  • Influxdb: v1.8.0
  • Grafana: v6.7.1

Prometheus和Grafana是部署到k8s上面。Influxdb是使用单独的机器部署。

一、安装Influxdb

Influxdb部署在服务器上:192.168.241.143

1、下载安装包

wget https://dl.influxdata.com/influxdb/releases/influxdb-1.8.0.x86_64.rpm

2、安装

yum -y localinstall influxdb-1.8.0.x86_64.rpm

3、启动Influxdb

systemctl start influxdb
systemctl enable influxdb

安装后, 在/usr/bin下面有如下文件

# influx (按两下tab键)
influx          influxd         influx_inspect  influx_stress   influx_tsm

-------
influxd          Influxdb服务器
influx           Influxdb命令行客户端
influx_inspect   查看工具
influx_stress    压力测试工具
influx_tsm       数据库转换工具(将数据库从b1或bz1格式转换为tsm1格式)

在 /var/lib/influxdb/下面会有如下文件夹

# ls /var/lib/influxdb/
data  meta

4、创建http接口用于普罗米修斯

192.168.241.143是我的Influxdb地址

curl -XPOST http://192.168.241.143:8086/query --data-urlencode "q=CREATE DATABASE prometheus"

二、准备Prometheus的chart

Prometheus使用的是Helm方式部署到k8s里面。

下载地址:

1、先将chart克隆到本地。

git clone https://github.com/zyiqian/charts.git

ls charts
prometheus  prometheus-k8s-values.yaml  README.md

2、创建一个prometheus的命名空间

kubectl create namespace monitoring

三、准备remote_storage_adapter

对于业务比较大的环境Local storage是绝对满足不了的,那么就要用remote storage了。

Prometheus的remote storage需要借助adapter实现,adapter会提供write url和read url给Prometheus,这样Prometheus获取到数据后就会先写到本地然后再调用write url写到远端。

1、还需要下载一个可执行文件remote_storage_adapter。

GitHub地址:https://github.com/prometheus/prometheus/blob/main/documentation/examples/remote_storage/remote_storage_adapter/README.md

需要安装一个go环境build。我已经build好了,下载下面的地址可以直接用。

wget https://github.com/zyiqian/charts/blob/main/prometheus/remote_storage_adapter
chmod +x remote_storage_adapter

2、现在我们启动一个remote_storage_adapter来对接Influxdb和prometheus。

./remote_storage_adapter --influxdb-url=http://192.168.241.143:8086/ --influxdb.database="prometheus" --influxdb.retention-policy=autogen

如果想获取相应的帮助可以使用:./remote_storage_adapter -h来获取相应帮助(修改绑定的端口,Influxdb的设置等..)

将remote_storage_adapter注册为系统服务

cat>/lib/systemd/system/remote_storage_adapter.service<<EOF
[Service]
Restart=on-failure
WorkingDirectory=/root/
ExecStart=/root/remote_storage_adapter --influxdb-url=http://192.168.241.143:8086/ --influxdb.database="prometheus" --influxdb.retention-policy=autogen
[Install]
WantedBy=multi-user.target
EOF

chown 644 /lib/systemd/system/remote_storage_adapter.service
systemctl daemon-reload
systemctl enable remote_storage_adapter
systemctl start remote_storage_adapter
systemctl status remote_storage_adapter

3、修改prometheus chart里面的values文件

找到prometheus-k8s-values.yaml里面remoteWrite和remoteRead。

将地址替换成自己Influxdb的地址.

修改service的type为NodePort的类型

cd prometheus
vim prometheus-k8s-values.yaml
........
remoteWrite:
    - url: "http://192.168.241.143:8086/api/v1/prom/write?db=prometheus"
  ## https://prometheus.io/docs/prometheus/latest/configuration/configuration/#remote_read
  ##
  remoteRead:
    - url: "http://192.168.241.143:8086/api/v1/prom/read?db=prometheus"

..........

servicePort: 9090
    sessionAffinity: None
    type: NodePort

5、启动prometheus

进入刚刚 clone 的charts

cd /charts
helm upgrade --install -f prometheus-k8s-values.yaml --namespace monitoring prometheus ./prometheus

查看pod

# kubectl get pods -n monitoring
NAME                                            READY   STATUS    RESTARTS   AGE
prometheus-alertmanager-6755f85f9b-sh4n8        2/2     Running   0          122m
prometheus-kube-state-metrics-95d956569-rpp64   1/1     Running   0          122m
prometheus-node-exporter-fdjvr                  1/1     Running   0          122m
prometheus-node-exporter-s7bjr                  1/1     Running   0          122m
prometheus-node-exporter-tctzx                  1/1     Running   0          122m
prometheus-server-7dffdd7f6b-sghlv              2/2     Running   0          122m

6、将prometheus的服务端口代理到本地

下面操作是在Windows CMD中执行

>kubectl.exe get svc -n monitoring
NAME                            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
prometheus-alertmanager         ClusterIP   10.233.42.87    <none>        80/TCP     2m56s
prometheus-kube-state-metrics   ClusterIP   10.233.56.122   <none>        8080/TCP   2m56s
prometheus-node-exporter        ClusterIP   None            <none>        9100/TCP   2m56s
prometheus-server               ClusterIP   10.233.22.16    <none>        80/TCP     2m56s

>kubectl.exe port-forward svc/prometheus-server -n monitoring 80
Forwarding from 127.0.0.1:80 -> 9090
Forwarding from [::1]:80 -> 9090

查看svc

# kubectl get svc -n monitoring
NAME                            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
prometheus-alertmanager         ClusterIP   10.233.42.87    <none>        80/TCP           4h1m
prometheus-kube-state-metrics   ClusterIP   10.233.56.122   <none>        8080/TCP         4h1m
prometheus-node-exporter        ClusterIP   None            <none>        9100/TCP         4h1m
prometheus-server               NodePort    10.233.22.16    <none>        9090:30056/TCP   4h1m

7、在浏览器中访问

nodeIP+port

http://192.168.241.133:30056

Untitled.png

8、查看Influxdb

# influx
Connected to http://localhost:8086 version 1.8.0
influxdb shell version: 1.8.0
> show databases;
name: databases
name
----
prometheus
_internal
> use prometheus
Using database prometheus
> SHOW MEASUREMENTS;
name: measurements
name
----
ALERTS
ALERTS_FOR_STATE
aggregator_openapi_v2_regeneration_count
........

四、安装Grafana

参考文档:https://blog.z0ukun.com/?p=2358

前面我们使用 Prometheus 采集了 Kubernetes 集群中的一些监控数据指标,Prometheus 的图表功能相对较弱,所以一般情况下我们会通过第三方工具grafana来展示这些数据。

1、安装NFS服务

NFS服务用于持久化Grafana的数据。nfs服务器部署与Influxdb在同一台服务器。注意,生产环境不推荐这样做。

yum install -y  nfs-utils rpcbind

启动服务

注意:先启动rpc服务,再启动nfs服务。
systemctl start rpcbind    #先启动rpc服务
systemctl enable rpcbind   #设置开机启动
systemctl start nfs-server #启动nfs服务
systemctl enable nfs-server

配置共享文件目录,编辑配置文件

mkdir /data/public
vi /etc/exports
/data/public *(rw,sync,no_root_squash)

systemctl reload nfs

使用showmount命令查看nfs服务器共享信息

showmount -e 192.168.241.143
Export list for 192.168.241.143:
/data/public *

需要在每台node节点和master节点上安装nfs-utils

yum install nfs-utils -y

否则启动pod的时候会报以下错误

# kubectl get pods -n grafana
NAME                      READY   STATUS              RESTARTS   AGE
grafana-59f68b896-rsgp2   0/1     ContainerCreating   0          84s
grafana-chown-fkgst       0/1     ContainerCreating   0          84s

# kubectl describe pod grafana-59f68b896-rsgp2 -n grafana
.......
Events:
  Type     Reason       Age                            From               Message
  ----     ------       ----                           ----               -------
  Normal   Scheduled    95s                            default-scheduler  Successfully assigned grafana/grafana-59f68b896-rsgp2 to node2
  Warning  FailedMount  <invalid> (x8 over <invalid>)  kubelet            MountVolume.SetUp failed for volume "grafana" : mount failed: exit status 32
Mounting command: mount
Mounting arguments: -t nfs 192.168.241.143:/data/public /var/lib/kubelet/pods/2cf96c6d-49cb-405b-8861-57147969acf3/volumes/kubernetes.io~nfs/grafana
Output: mount: wrong fs type, bad option, bad superblock on 192.168.241.143:/data/public,
       missing codepage or helper program, or other error
       (for several filesystems (e.g. nfs, cifs) you might
       need a /sbin/mount.<type> helper program)

       In some cases useful info is found in syslog - try
       dmesg | tail or so.

2、把grafana文件clone下来

根据自己的需求修改配置文件。

git clone https://github.com/zyiqian/grafana.git

ls
grafana-chown-job.yaml  grafana-deploy.yaml  grafana-svc.yaml  grafana-volume.yaml

  • grafana-deploy.yaml:里面两个比较重要的环境变量GF_SECURITY_ADMIN_USER和GF_SECURITY_ADMIN_PASSWORD,用来配置 grafana 的管理员用户和密码。
  • grafana-volume.yaml :主要做数据的持久化。挂载的nfs。需要修改nfs为自己的nfs服务器。
  • grafana-svc.yaml :主要是对外暴露 grafana 这个服务。
  • grafana-chown-job.yaml :主要是对/var/lib/grafana目录的权限更改问题。

3、创建grafana命名空间

kubectl create namespace grafana

4、部署

ls 
grafana-chown-job.yaml  grafana-deploy.yaml  grafana-svc.yaml  grafana-volume.yaml

kubectl apply -f .

5、查看pod

# kubectl get pods -n grafana
NAME                      READY   STATUS      RESTARTS   AGE
grafana-59f68b896-ch5q9   1/1     Running     0          63m
grafana-chown-qsrh4       0/1     Completed   0          63m

如果不是running状态可以使用describe和logs命令查看是什么原因。。

6、查看svc

# kubectl get svc -n grafana
NAME      TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
grafana   NodePort   10.233.18.36   <none>        3000:32214/TCP   64m

7、浏览器访问

node IP + port

例如: 192.168.241.133:32214

使用grafana-deploy.yaml 里面设置的 admin admin321登录

8、创建数据源

刚登录进去需要create a data source.

选择prometheus.

Untitled 1.png

URL为上面prometheus service的url.

Untitled 2.png

9、导入dashboard

模板下载:https://grafana.com/grafana/dashboards

Untitled 3.png

可以使用id:13105 的方式导入,也可以使用json file的方式导

Untitled 4.png
Untitled 5.png

导入之后就可以看到各个node的状态信息了。

Untitled 6.png

顶部可以选择时间段。

Untitled 7.png

测试

测试数据是否做了持久化存储。

卸载prometheus。

# helm uninstall prometheus -n monitoring

确定全部pod已经移除。

# kubectl get pods -n monitoring
No resources found in monitoring namespace.

重新部署prometheus.

# cd /data/prometheus/
# helm upgrade --install -f prometheus-k8s-values.yaml --namespace monitoring prometheus ./prometheus

查看pod

# kubectl get pods -n monitoring
NAME                                            READY   STATUS    RESTARTS   AGE
prometheus-alertmanager-6755f85f9b-nstxf        2/2     Running   0          43s
prometheus-kube-state-metrics-95d956569-jd9bm   1/1     Running   0          43s
prometheus-node-exporter-5ldwc                  1/1     Running   0          43s
prometheus-node-exporter-l5qlx                  1/1     Running   0          43s
prometheus-node-exporter-pwfth                  1/1     Running   0          43s
prometheus-server-7dffdd7f6b-hnvdk              2/2     Running   0          43s

查看svc

# kubectl get svc -n monitoring
NAME                            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
prometheus-alertmanager         ClusterIP   10.233.18.217   <none>        80/TCP           117s
prometheus-kube-state-metrics   ClusterIP   10.233.20.130   <none>        8080/TCP         117s
prometheus-node-exporter        ClusterIP   None            <none>        9100/TCP         117s
prometheus-server               NodePort    10.233.11.102   <none>        9090:30462/TCP   117s

然后在浏览器上访问并查询。

可以看到以下有空出来的一部分。那就是刚刚卸载pod的那一个时间段。前面的数据还是可以继续展示出来的。

Untitled 8.png

重新在grafana data source上设置下url的port

Untitled 9.png

save & test

Untitled 10.png

再去dashboard上面看。把时间段调大写,就可以看到历史的监控数据了。说明我们的数据持久化是完成部署了。

下面间隔很大是因为我用的是VM本地测试用的。

Untitled 11.png

部署Prometheus-Alert

地址:https://github.com/feiyu563/PrometheusAlert

PrometheusAlert是开源的运维告警中心消息转发系统,我们可以通过它将收到的这些消息发送到钉钉,微信,email。

Untitled 12.png

1、将chart下载到本地

git clone https://github.com/zyiqian/charts.git
cd charts/prometheusalert
ls
Chart.yaml  config  README.md  templates  values.yaml

2、修改values.yaml文件

# Default values for prometheusalert.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

replicaCount: 1

image:
  repository: feiyu563/prometheus-alert
  tag: "latest"
  pullPolicy: IfNotPresent

nameOverride: ""
fullnameOverride: ""

service:
  type: ClusterIP
  port: 80

ingress:
  enabled: false
  annotations: {}
    # kubernetes.io/ingress.class: nginx
  # kubernetes.io/tls-acme: "true"
  hosts:
    - host: prometheus-alert.local
      paths: ["/"]

  tls: []

resources:
  limits:
    cpu: 1000m
    memory: 1024Mi
  requests:
    cpu: 100m
    memory: 128Mi

nodeSelector: {}

tolerations: []

affinity: {}

3、修改config/app.conf文件

#是否开启钉钉告警通道,可同时开始多个通道0为关闭,1为开启
open-dingding=1
#默认钉钉机器人地址
ddurl=https://oapi.dingtalk.com/robot/send?access_token=1111111sssssss1
#是否开启 @所有人(0为关闭,1为开启)
dd_isatall=0

4、部署

cd charts/prometheusalert
helm install -n monitoring .

查看pod

# kubectl get pods -n monitoring
NAME                                            READY   STATUS    RESTARTS   AGE
grafana-94c76556b-frksh                         1/1     Running   0          1h
prometheus-alert-7f64cbb99c-rssw2               1/1     Running   0          18s
prometheus-alertmanager-6755f85f9b-nstxf        2/2     Running   0          1h
prometheus-kube-state-metrics-95d956569-jd9bm   1/1     Running   0          1h
prometheus-node-exporter-5ldwc                  1/1     Running   0          1h
prometheus-node-exporter-l5qlx                  1/1     Running   0          1h
prometheus-node-exporter-pwfth                  1/1     Running   0          1h
prometheus-server-7dffdd7f6b-hnvdk              2/2     Running   0          1h

$kubectl get svc -n monitoring
NAME                                      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
k8s-grafana                         ClusterIP   12.80.41.192    <none>        80/TCP     1h
prometheus-alert                          ClusterIP   12.80.128.117   <none>        80/TCP     30s

5、Prometheus 接入配置

在 Prometheus Alertmanager 中启用 Webhook

编辑prometheus-k8s-values.yaml,找到以下内容

........
alertmanagerFiles:
  alertmanager.yml:
    global: {}
    # slack_api_url: ''
    route:
      receiver: "web.hook.prometheusalert"
      group_by: ["alertname"]
      group_wait: 10s
      group_interval: 5m
      repeat_interval: 2h
      routes:
        - receiver: "page"
          group_wait: 10s
          group_by: ['page']
          repeat_interval: 8h
          group_interval: 5m
          match_re:
            severity: "page"
    receivers:
      - name: 'web.hook.prometheusalert'
        webhook_configs:
          - url: 'http://[prometheusalert_url]/prometheus/alert'
           # 如果使用ClusterIP的方式的话 [prometheusalert_url]就是prometheus-alert.monitoring.svc.cluster.local
      - name: 'page'
        webhook_configs:
          - url: 'http://prometheus-alert.monitoring.svc.cluster.local/prometheusalert?type=dd&tpl=prometheus-dd&ddurl=https://oapi.dingtalk.com/robot/send?access_token=031db3xxxxxxxxxxxx'

.....
prometheus.yml:
    rule_files:
      - /etc/config/recording_rules.yml
      - /etc/config/alerting_rules.yml
    ## Below two files are DEPRECATED will be removed from this default values file
      - /etc/config/rules
      - /etc/config/alerts
    scrape_configs:
            - job_name: 'node-exporter'
        scrape_interval: 5s
        scrape_timeout: 5s
        metrics_path: /metrics
        scheme: http
        static_configs:
          - targets:
              # jenkins-agent
              - "192.168.241.114:9100"
            labels:
              env: infrastructure

6、修改完成后重新部署prometheus

cd charts
helm upgrade --install -f prometheus-k8s-values.yaml --namespace monitoring prometheus ./prometheus

7、访问prometheus-alert web

$ kubectl port-forward svc/k8s-prometheus-alert -n monitoring 80
Forwarding from 127.0.0.1:80 -> 8080
Forwarding from [::1]:80 -> 8080
Untitled 12.png

[图片上传失败...(image-7c1c1d-1629065813017)]

用户名名密码默认是admin

如果配置好钉钉之后就可以尝试下告警测试

Untitled 13.png

钉钉群将受到如下信息:

Untitled 14.png

这里可以设置它的告警模板

Untitled 15.png
{{ $var := .externalURL}}{{ range $k,$v:=.alerts }}
{{if eq $v.status "resolved"}}
## [Prometheus恢复信息]
##### 告警级别:{{$v.labels.severity}}
###### 开始时间:{{GetCSTtime $v.startsAt}}
###### 结束时间:{{GetCSTtime $v.endsAt}}
###### 故障主机IP:{{$v.labels.instance}}
##### 【Summary】 
##### {{$v.annotations.summary}}
##### 【Description】 
##### {{$v.annotations.description}}
{{else}}
## [Prometheus告警信息]
#### [{{$v.labels.alertname}}]
##### 告警级别:{{$v.labels.severity}}
###### 开始时间:{{GetCSTtime $v.startsAt}}
###### 故障主机IP:{{$v.labels.instance}}
##### 【Summary】 
##### {{$v.annotations.summary}}
##### 【Description】 
##### {{$v.annotations.description}}
{{end}}
{{ end }}

下面的JSON可以在日志中找,如果触发告警的话会在日志里面打印的

官方文档:https://github.com/feiyu563/PrometheusAlert/blob/master/doc/readme/customtpl.md

Untitled 16.png
kubectl logs k8s-prometheus-alert-7f64cbb99c-rssw2 -n monitoring

找到类似这样的json格式

Untitled 17.png

然后将它复制出来使用json转换下,复制过去

Untitled 18.png

点击模板测试

Untitled 19.png

到这里,整套的监控体系就搭建完成了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,490评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,581评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,830评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,957评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,974评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,754评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,464评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,357评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,847评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,995评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,137评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,819评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,482评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,023评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,149评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,409评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,086评论 2 355

推荐阅读更多精彩内容