请启用 Javascript 以查看内容

Kubernetes 1.19 安装 Prometheus-Oprator

 ·   ·  ☕ 12 分钟  ·  ✍ CNSRE

文章链接

简介

Prometheus 介绍

Prometheus 是一套开源的监控 & 报警 & 时间序列数据库的组合,起始是由 SoundCloud 公司开发的。成立于 2012 年,之后许多公司和组织接受和采用 prometheus,他们便将它独立成开源项目,并且有公司来运作.该项目有非常活跃的社区和开发人员,目前是独立的开源项目,任何公司都可以使用它,2016 年,Prometheus 加入了云计算基金会,成为 kubernetes 之后的第二个托管项目.google SRE 的书内也曾提到跟他们 BorgMon 监控系统相似的实现是 Prometheus。现在最常见的 Kubernetes 容器管理系统中,通常会搭配 Prometheus 进行监控。

Kubernetes Operator 介绍

Prometheus-operator 已经改名为 Kube-promethues

Kubernetes 的支持下,管理和伸缩 Web 应用、移动应用后端以及 API 服务都变得比较简单了。其原因是这些应用一般都是无状态的,所以 Deployment 这样的基础 Kubernetes API 对象就可以在无需附加操作的情况下,对应用进行伸缩和故障恢复了。

而对于数据库、缓存或者监控系统等有状态应用的管理,就是个挑战了。这些系统需要应用领域的知识,来正确的进行伸缩和升级,当数据丢失或不可用的时候,要进行有效的重新配置。我们希望这些应用相关的运维技能可以编码到软件之中,从而借助 Kubernetes` 的能力,正确的运行和管理复杂应用。

Operator 这种软件,使用 TPR (第三方资源,现在已经升级为 CRD) 机制对 Kubernetes API 进行扩展,将特定应用的知识融入其中,让用户可以创建、配置和管理应用。和 Kubernetes 的内置资源一样,Operator 操作的不是一个单实例应用,而是集群范围内的多实例。

Prometheus Operator 介绍

KubernetesPrometheus OperatorKubernetes 服务和 Prometheus 实例的部署和管理提供了简单的监控定义。

安装完毕后,Prometheus Operator 提供了以下功能:

  • 创建/毁坏: 在 Kubernetes namespace 中更容易启动一个 Prometheus 实例,一个特定的应用程序或团队更容易使用Operator。
  • 简单配置: 配置 Prometheus 的基础东西,比如在 Kubernetes 的本地资源 versions, persistence, retention policies, 和 replicas。
  • Target Services 通过标签: 基于常见的 Kubernetes label 查询,自动生成监控 target 配置;不需要学习 Prometheus 特定的配置语言。

架构

Prometheus

为一个监控系统, Prometheus 项目的作用和工作方式,其实可以用如下所示的一张官方示意图来解释:
cnsre运维博客|Linux系统运维|自动化运维|云计算|运维监控
可以看到, Prometheus 项目工作的核心,是使用 Pull (抓取)的方式去搜集被监控对象的 Metrics 数据(监控指标数据),然后,再把这些数据保存在一个 TSDB (时间序列数据库,比如 OpenTSDB、InfluxDB 等)当中,以便后续可以按照时间进行检索。有了这套核心监控机制, Prometheus 剩下的组件就是用来配合这套机制的运行。比如 Pushgateway ,可以允许被监控对象以 Push 的方式向 Prometheus 推送 Metrics 数据。而 Alertmanager ,则可以根据 Metrics 信息灵活地设置报警。当然, Prometheus 最受用户欢迎的功能,还是通过 Grafana 对外暴露出的、可以灵活配置的监控数据可视化界面。

Prometheus Operator

cnsre运维博客|Linux系统运维|自动化运维|云计算|运维监控

  • Operator: Operator 资源会根据自定义资源(Custom Resource Definition / CRDs)来部署和管理 Prometheus Server ,同时监控这些自定义资源事件的变化来做相应的处理,是整个系统的控制中心。

  • Prometheus: Prometheus 资源是声明性地描述 Prometheus 部署的期望状态。

  • Prometheus Server: Operator 根据自定义资源 Prometheus 类型中定义的内容而部署的 Prometheus Server 集群,这些自定义资源可以看作是用来管理 Prometheus Server 集群的 StatefulSets 资源。

  • ServiceMonitor: ServiceMonitor 也是一个自定义资源,它描述了一组被 Prometheus 监控的 targets 列表。该资源通过 Labels 来选取对应的 Service Endpoint ,让 Prometheus Server 通过选取的 Service 来获取 Metrics 信息。

  • Service: Service 资源主要用来对应 Kubernetes 集群中的 Metrics Server Pod ,来提供给 ServiceMonitor 选取让 Prometheus Server 来获取信息。简单的说就是 Prometheus Node Exporter ServiceMysql Exporter Service 等等。

  • Alertmanager: Alertmanager 也是一个自定义资源类型,由 Operator 根据资源描述内容来部署 Alertmanager 集群

安装前须知

在k8s中部署Prometheus监控的方法

通常在k8s中部署 prometheus 监控可以采取的方法有以下三种

  • 通过yaml手动部署
  • operator部署
  • 通过helm chart部署

kube-prometheus 兼容说明

kube-prometheus stack Kubernetes 1.18 Kubernetes 1.19 Kubernetes 1.20 Kubernetes 1.21
release-0.5
release-0.6
release-0.7
release-0.8
HEAD

环境参数

系统参数:
Kube-promethues 版本: 0.7.0
Kubernetes 版本: v1.19.5
项目 Github 地址: https://github.com/coreos/kube-prometheus

拉取 kube-prometheus 0.7

先从 Github 上将源码拉取下来,利用源码项目已经写好的 kubernetes 的 yaml 文件进行一系列集成镜像的安装,如 grafana 、prometheus 等等。

1
wget  https://github.com/prometheus-operator/kube-prometheus/archive/refs/tags/v0.7.0.zip

解压

1
cd kube-prometheus-0.7.0/

yaml 文件分类

由于它的文件都存放在项目源码的 manifests 文件夹下,所以需要进入其中进行启动这些 kubernetes 应用 yaml 文件。又由于这些文件堆放在一起,不利于分类启动,所以这里将它们分类。

进入源码的 manifests 文件夹:

1
cd manifests/

创建文件夹并且将 yaml 文件分类:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 创建文件夹
mkdir -p node-exporter alertmanager grafana kube-state-metrics prometheus serviceMonitor adapter

# 移动 yaml 文件,进行分类到各个文件夹下
mv *-serviceMonitor* serviceMonitor/
mv grafana-* grafana/
mv kube-state-metrics-* kube-state-metrics/
mv alertmanager-* alertmanager/
mv node-exporter-* node-exporter/
mv prometheus-adapter* adapter/
mv prometheus-* prometheus/

基本目录结构如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
[root@master kube-prometheus-0.7.0]# tree  manifests/
manifests/
|-- adapter
|   |-- prometheus-adapter-apiService.yaml
|   |-- prometheus-adapter-clusterRoleAggregatedMetricsReader.yaml
|   |-- prometheus-adapter-clusterRoleBindingDelegator.yaml
|   |-- prometheus-adapter-clusterRoleBinding.yaml
|   |-- prometheus-adapter-clusterRoleServerResources.yaml
|   |-- prometheus-adapter-clusterRole.yaml
|   |-- prometheus-adapter-configMap.yaml
|   |-- prometheus-adapter-deployment.yaml
|   |-- prometheus-adapter-roleBindingAuthReader.yaml
|   |-- prometheus-adapter-serviceAccount.yaml
|   `-- prometheus-adapter-service.yaml
|-- alertmanager
|   |-- alertmanager-alertmanager.yaml
|   |-- alertmanager-secret.yaml
|   |-- alertmanager-serviceAccount.yaml
|   `-- alertmanager-service.yaml
|-- grafana
|   |-- grafana-dashboardDatasources.yaml
|   |-- grafana-dashboardDefinitions.yaml
|   |-- grafana-dashboardSources.yaml
|   |-- grafana-deployment.yaml
|   |-- grafana-serviceAccount.yaml
|   `-- grafana-service.yaml
|-- kube-state-metrics
|   |-- kube-state-metrics-clusterRoleBinding.yaml
|   |-- kube-state-metrics-clusterRole.yaml
|   |-- kube-state-metrics-deployment.yaml
|   |-- kube-state-metrics-serviceAccount.yaml
|   `-- kube-state-metrics-service.yaml
|-- node-exporter
|   |-- node-exporter-clusterRoleBinding.yaml
|   |-- node-exporter-clusterRole.yaml
|   |-- node-exporter-daemonset.yaml
|   |-- node-exporter-serviceAccount.yaml
|   `-- node-exporter-service.yaml
|-- prometheus
|   |-- prometheus-clusterRoleBinding.yaml
|   |-- prometheus-clusterRole.yaml
|   |-- prometheus-prometheus.yaml
|   |-- prometheus-roleBindingConfig.yaml
|   |-- prometheus-roleBindingSpecificNamespaces.yaml
|   |-- prometheus-roleConfig.yaml
|   |-- prometheus-roleSpecificNamespaces.yaml
|   |-- prometheus-rules.yaml
|   |-- prometheus-serviceAccount.yaml
|   `-- prometheus-service.yaml
|-- serviceMonitor
|   |-- alertmanager-serviceMonitor.yaml
|   |-- grafana-serviceMonitor.yaml
|   |-- kube-state-metrics-serviceMonitor.yaml
|   |-- node-exporter-serviceMonitor.yaml
|   |-- prometheus-adapter-serviceMonitor.yaml
|   |-- prometheus-operator-serviceMonitor.yaml
|   |-- prometheus-serviceMonitorApiserver.yaml
|   |-- prometheus-serviceMonitorCoreDNS.yaml
|   |-- prometheus-serviceMonitorKubeControllerManager.yaml
|   |-- prometheus-serviceMonitorKubelet.yaml
|   |-- prometheus-serviceMonitorKubeScheduler.yaml
|   `-- prometheus-serviceMonitor.yaml
`-- setup
    |-- 0namespace-namespace.yaml
    |-- prometheus-operator-0alertmanagerConfigCustomResourceDefinition.yaml
    |-- prometheus-operator-0alertmanagerCustomResourceDefinition.yaml
    |-- prometheus-operator-0podmonitorCustomResourceDefinition.yaml
    |-- prometheus-operator-0probeCustomResourceDefinition.yaml
    |-- prometheus-operator-0prometheusCustomResourceDefinition.yaml
    |-- prometheus-operator-0prometheusruleCustomResourceDefinition.yaml
    |-- prometheus-operator-0servicemonitorCustomResourceDefinition.yaml
    |-- prometheus-operator-0thanosrulerCustomResourceDefinition.yaml
    |-- prometheus-operator-clusterRoleBinding.yaml
    |-- prometheus-operator-clusterRole.yaml
    |-- prometheus-operator-deployment.yaml
    |-- prometheus-operator-serviceAccount.yaml
    `-- prometheus-operator-service.yaml

修改 Service 端口设置

修改 prometheus-service.yaml 文件

1
vim prometheus/prometheus-service.yaml

修改 prometheus Service 端口类型为 NodePort,设置 NodePort 端口为 30100:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
apiVersion: v1
kind: Service
metadata:
  labels:
    prometheus: k8s
  name: prometheus-k8s
  namespace: monitoring
spec:
  type: NodePort     # 增加配置
  ports:
  - name: web
    port: 9090
    targetPort: web
    nodePort: 30100  # 增加配置
  selector:
    app: prometheus
    prometheus: k8s
  sessionAffinity: ClientIP

修改 Grafana Service

修改 grafana-service.yaml 文件:

1
vim grafana/grafana-service.yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
apiVersion: v1
kind: Service
metadata:
  labels:
    app: grafana
  name: grafana
  namespace: monitoring
spec:
  type: NodePort     # 增加配置
  ports:
  - name: http
    port: 3000
    targetPort: http
    nodePort: 30101  # 增加配置
  selector:
    app: grafana

安装Prometheus Operator

所有文件都在 manifests 目录下执行。

安装 Operator

1
kubectl apply -f setup/

查看 Pod,等 pod 创建起来在进行下一步:

1
2
3
[root@master manifests]# kubectl get pods -n monitoring
NAME                                   READY   STATUS    RESTARTS   AGE
prometheus-operator-7649c7454f-q5f2r   2/2     Running   0          50s

这会创建一个名为 monitoring 的命名空间,以及相关的 CRD 资源对象声明和 Prometheus Operator 控制器。前面中我们介绍过 CRDOperator 的使用,当我们声明完 CRD 过后,就可以来自定义资源清单了,但是要让我们声明的自定义资源对象生效就需要安装对应的 Operator 控制器,这里我们都已经安装了,所以接下来就可以来用 CRD 创建真正的自定义资源对象了。其实在 manifests 目录下面的就是我们要去创建的 PrometheusAlertmanager 以及各种监控对象的资源清单。

安装其它组件

没有特殊的定制需求我们可以直接一键安装:

1
2
3
4
5
6
7
kubectl apply -f adapter/
kubectl apply -f alertmanager/
kubectl apply -f node-exporter/
kubectl apply -f kube-state-metrics/
kubectl apply -f grafana/
kubectl apply -f prometheus/
kubectl apply -f serviceMonitor/

查看 Pod 状态:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
[root@master manifests]# kubectl  get  pods -n  monitoring 
NAME                                   READY   STATUS    RESTARTS   AGE
alertmanager-main-0                    2/2     Running   0          16m
alertmanager-main-1                    2/2     Running   0          16m
alertmanager-main-2                    2/2     Running   0          16m
grafana-6f777cf998-sv4mz               1/1     Running   0          16m
kube-state-metrics-587bfd4f97-mhj94    3/3     Running   0          16m
node-exporter-cgbl2                    2/2     Running   0          16m
node-exporter-k9fqg                    2/2     Running   0          16m
prometheus-adapter-69b8496df6-954s6    1/1     Running   0          16m
prometheus-k8s-0                       2/2     Running   0          16m
prometheus-k8s-1                       2/2     Running   0          16m
prometheus-operator-7649c7454f-q5f2r   2/2     Running   0          16m

查看 Prometheus & Grafana

查看 Prometheus

打开地址:http://node_ip:30100 查看 Prometheus 采集的目标,看其各个采集服务状态有没有错误。
cnsre运维博客|Linux系统运维|自动化运维|云计算|运维监控
cnsre运维博客|Linux系统运维|自动化运维|云计算|运维监控

查看 Grafana

打开地址:http://node_ip:30101 查看 Grafana 图表,看其 Kubernetes 集群是否能正常显示。
默认用户名:admin
默认密码:admin
cnsre运维博客|Linux系统运维|自动化运维|云计算|运维监控

查看仪表盘:
cnsre运维博客|Linux系统运维|自动化运维|云计算|运维监控
cnsre运维博客|Linux系统运维|自动化运维|云计算|运维监控

微信报警

获取企业 ID 等信息

配置前参数说明:

获取企业微信的对外接口
企业微信的 secret_api
企业信息ID corp_id

wechat_api_url:
企业微信对外接口 https://qyapi.weixin.qq.com/cgi-bin/
api_secret: 应用管理–应用–你的应用
agent_id: 应用管理–应用–你的应用
corp_id: 我的企业– 企业信息–下拉至最下–企业ID
to_party: 通讯录–组–部门ID
to_user: 通讯录–组–部门ID–选中接收告警的人–账号

登录企业微信–应用管理–应用–下拉到最下面点击 创建应用
cnsre运维博客|Linux系统运维|自动化运维|云计算|运维监控
需要记着 AgentIdSecret
cnsre运维博客|Linux系统运维|自动化运维|云计算|运维监控
点击 我的企业– 企业信息–下拉至最下–企业ID
cnsre运维博客|Linux系统运维|自动化运维|云计算|运维监控
通讯录–组–部门ID
cnsre运维博客|Linux系统运维|自动化运维|云计算|运维监控

将对应秘钥填入yaml

配置 alertmanager.yaml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
cd alertmanager/
cat <<EOF > alertmanager.yaml    
global:
  resolve_timeout: 5m  
receivers:
- name: wechat
  wechat_configs:
  - agent_id: "1000005"
    api_secret: _UCBVsNYTQwY75TFKQ4V6jj2YQKsyxxxxx
    corp_id: ww022bebbed74fxxxx
    send_resolved: true
    to_user: xuewenlong
route:
  group_by:
  - job
  group_interval: 5m
  group_wait: 30s
  receiver: wechat
  repeat_interval: 1h
  routes:
  - match:
      alertname: Watchdog
    receiver: wechat
templates:
- /etc/alertmanager/config/wechat.tmpl
EOF      

个性化配置报警模板,网上有很多例子

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
cat <<EOF > wechat.tmpl  
{{ define "wechat.default.message" }}
{{- if gt (len .Alerts.Firing) 0 -}}
{{- range $index, $alert := .Alerts -}}
{{- if eq $index 0 }}
==========异常告警==========
告警类型: {{ $alert.Labels.alertname }}
告警级别: {{ $alert.Labels.severity }}
告警详情: {{ $alert.Annotations.message }}{{ $alert.Annotations.description}};{{$alert.Annotations.summary}}
故障时间: {{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
{{- if gt (len $alert.Labels.instance) 0 }}
实例信息: {{ $alert.Labels.instance }}
{{- end }}
{{- if gt (len $alert.Labels.namespace) 0 }}
命名空间: {{ $alert.Labels.namespace }}
{{- end }}
{{- if gt (len $alert.Labels.node) 0 }}
节点信息: {{ $alert.Labels.node }}
{{- end }}
{{- if gt (len $alert.Labels.pod) 0 }}
实例名称: {{ $alert.Labels.pod }}
{{- end }}
============END============
{{- end }}
{{- end }}
{{- end }}
{{- if gt (len .Alerts.Resolved) 0 -}}
{{- range $index, $alert := .Alerts -}}
{{- if eq $index 0 }}
==========异常恢复==========
告警类型: {{ $alert.Labels.alertname }}
告警级别: {{ $alert.Labels.severity }}
告警详情: {{ $alert.Annotations.message }}{{ $alert.Annotations.description}};{{$alert.Annotations.summary}}
故障时间: {{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
恢复时间: {{ ($alert.EndsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
{{- if gt (len $alert.Labels.instance) 0 }}
实例信息: {{ $alert.Labels.instance }}
{{- end }}
{{- if gt (len $alert.Labels.namespace) 0 }}
命名空间: {{ $alert.Labels.namespace }}
{{- end }}
{{- if gt (len $alert.Labels.node) 0 }}
节点信息: {{ $alert.Labels.node }}
{{- end }}
{{- if gt (len $alert.Labels.pod) 0 }}
实例名称: {{ $alert.Labels.pod }}
{{- end }}
============END============
{{- end }}
{{- end }}
{{- end }}
{{- end }}
EOF

部署secret

1
2
kubectl delete secret alertmanager-main -n monitoring
kubectl create secret generic alertmanager-main --from-file=alertmanager.yaml --from-file=wechat.tmpl -n monitoring

查看容器中的配置文件

1
2
3
kubectl exec -it  alertmanager-main-0 -n monitoring /bin/sh
ls /etc/alertmanager/config/
# 如果能看到  alertmanager.yaml  wechat.tmpl 两个文件就证明更新成功了。

验证

更新后就会收到消息
cnsre运维博客|Linux系统运维|自动化运维|云计算|运维监控

自动发现规则

在k8s中会部署非常多的servicepod,如果要一个一个手动的添加监控非常麻烦且不必要,使用自动发现机制。将会减少很多不必要的工作。

创建 yaml 文件

创建prometheus-additional.yaml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
cd prometheus/
cat prometheus-additional.yaml
- job_name: 'kubernetes-service-endpoints'
  kubernetes_sd_configs:
  - role: endpoints
  relabel_configs:
  - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
    action: keep
    regex: true
  - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
    action: replace
    target_label: __scheme__
    regex: (https?)
  - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
    action: replace
    target_label: __metrics_path__
    regex: (.+)
  - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
    action: replace
    target_label: __address__
    regex: ([^:]+)(?::\d+)?;(\d+)
    replacement: $1:$2
  - action: labelmap
    regex: __meta_kubernetes_service_label_(.+)
  - source_labels: [__meta_kubernetes_namespace]
    action: replace
    target_label: kubernetes_namespace
  - source_labels: [__meta_kubernetes_service_name]
    action: replace
    target_label: kubernetes_name

要想自动被发现,只需要在 service 的配置清单中加上 annotations: prometheus.io/scrape=true

创建 secret

然后用这个文件创建一个 secret

1
kubectl -n monitoring create secret generic additional-config --from-file=prometheus-additional.yaml

修改 prometheus 配置清单

prometheus 的配置清单中添加以下配置:

1
2
3
  additionalScrapeConfigs:
    name: additional-config
    key: prometheus-additional.yaml

具体如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
cat prometheus-prometheus.yaml
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
  labels:
    app.kubernetes.io/component: prometheus
    app.kubernetes.io/name: prometheus
    app.kubernetes.io/part-of: kube-prometheus
    app.kubernetes.io/version: 2.26.0
    prometheus: k8s
  name: k8s
  namespace: monitoring
spec:
  alerting:
    alertmanagers:
    - apiVersion: v2
      name: alertmanager-main
      namespace: monitoring
      port: web
  externalLabels: {}
  image: quay.io/prometheus/prometheus:v2.26.0
  nodeSelector:
    kubernetes.io/os: linux
  podMetadata:
    labels:
      app.kubernetes.io/component: prometheus
      app.kubernetes.io/name: prometheus
      app.kubernetes.io/part-of: kube-prometheus
      app.kubernetes.io/version: 2.26.0
  podMonitorNamespaceSelector: {}
  podMonitorSelector: {}
  probeNamespaceSelector: {}
  probeSelector: {}
  replicas: 2
  resources:
    requests:
      memory: 400Mi
  ruleSelector:
    matchLabels:
      prometheus: k8s
      role: alert-rules
  securityContext:
    fsGroup: 2000
    runAsNonRoot: true
    runAsUser: 1000
  additionalScrapeConfigs:            # 添加内容
    name: additional-configs          # 添加内容
    key: prometheus-additional.yaml   # 添加内容
  serviceAccountName: prometheus-k8s
  serviceMonitorNamespaceSelector: {}
  serviceMonitorSelector: {}
  version: 2.26.0

然后更新 prometheus 的配置

1
kubectl apply -f prometheus-prometheus.yaml 

修改 clusterrole 权限

Prometheus 绑定了一个名为 prometheus-k8sServiceAccount 对象,而这个对象绑定的是一个名为 prometheus-k8sClusterRoleprometheus-clusterRole.yaml
需要让他有 Service 或者 Podlist 权限

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
cat prometheus-clusterRole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: prometheus-k8s
rules:
- apiGroups:
  - ""
  resources:
  - nodes/metrics
  - configmaps
  verbs:
  - get
- apiGroups:
  - ""
  resources:
  - nodes
  - pods
  - services
  - endpoints
  - nodes/proxy
  verbs:
  - get
  - list
  - watch
- nonResourceURLs:
  - /metrics
  verbs:
  - get

更新 clusterrole

1
kubectl apply -f prometheus-clusterRole.yaml

等待一段时间可以发现自动发现成功
cnsre运维博客|Linux系统运维|自动化运维|云计算|运维监控

配置自动发现,首先 annotations 里需要配置 prometheus.io/scrape=true ,其次你的应用要有 exporter 去收集信息。

1
2
3
4
  annotations:
    prometheus.io/scrape: 'true'    # 添加内容
    prometheus.io/path: '/metrics'  # 添加内容
    prometheus.io/port: '80'        # 添加内容

比如 Nginx 配置:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
apiVersion: apps/v1     
kind: Deployment        
metadata:               
  name: nginx-deployment  
  labels:       
    app: nginx  
  annotations:
    prometheus.io/scrape: 'true'
    prometheus.io/path: '/metrics'
    prometheus.io/port: '80'
spec:           
  replicas: 2   
  selector:         
    matchLabels: 
      app: nginx
  minReadySeconds: 1
  progressDeadlineSeconds: 60
  revisionHistoryLimit: 2
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  template:         
    metadata:   
      labels:   
        app: nginx
      annotations:
        prometheus.io/scrape: 'true'
        prometheus.io/path: '/metrics'
        prometheus.io/port: '80'
    spec:          
      containers:      
      - name: nginx   
        image: wenlongxue/nginx:waynex-ce995b8    
        imagePullPolicy: Always         
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "100Mi"
            cpu: "100m"
          limits: 
            memory: "100Mi" 
            cpu: "100m"
        readinessProbe:
          httpGet:
            path: /index.html
            port: 80
          periodSeconds: 5
          timeoutSeconds: 3
          successThreshold: 1
          failureThreshold: 30       
---
apiVersion: v1
kind: Service
metadata:      
  name: nginx-service 
  labels:       
    app: nginx  
  annotations:
    prometheus.io/scrape: 'true'    # 添加内容
    prometheus.io/path: '/metrics'  # 添加内容
    prometheus.io/port: '80'        # 添加内容
spec:       
  selector: 
    app: nginx
  ports:
  - name: nginx-port 
    protocol: TCP      
    port: 80           
    nodePort: 30081  
    targetPort: 80     
  type: NodePort       

钉钉告警

配置 prometheus-operate 钉钉告警

创建 webhook 的配置文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# vim dingTalk-webhook-configmap.yml
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: monitoring
  name: dingtalk-webhook-config
data:
  config.yml: |
    # Request timeout
    timeout: 5s

    ## Customizable templates path
    templates:
    - /etc/prometheus-webhook-dingtalk/templates/*.tmpl

    ## You can also override default template using `default_message`
    ## The following example to use the 'legacy' template from v0.3.0
    # default_message:
    #   title: '{{ template "legacy.title" . }}'
    #   text: '{{ template "legacy.content" . }}'

    ## Targets, previously was known as "profiles"
    targets:
      guiji:
        url: https://oapi.dingtalk.com/robot/send?access_token=1a3ed90fefa5d1a8f4d61f063xxxxxxxxxxxxxxxxx
        message:
          title: '{{ template "ding.link.title" . }}'
          text: '{{ template "ding.link.content" . }}'
        mention:
          all: true
          mobiles: ['153xxxxxxxx']    

创建告警模板配置文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# vim dingTalk-webhook-template.yml
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: monitoring
  name: dingtalk-webhook-template
data:
  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 }}/#/alerts?receiver={{ .Receiver }}{{ end }}

    {{ define "__text_alert_list" }}{{ range . }}
    **Labels**
    {{ range .Labels.SortedPairs }}&gt; - {{ .Name }}: {{ .Value | markdown | html }}
    {{ end }}
    **Annotations**
    {{ range .Annotations.SortedPairs }}&gt; - {{ .Name }}: {{ .Value | markdown | html }}
    {{ end }}
    **Source:** [{{ .GeneratorURL }}]({{ .GeneratorURL }})
    {{ end }}{{ end }}

    {{ define "default.__text_alert_list" }}{{ range . }}
    ---
    **告警级别:** {{ .Labels.severity | upper }}

    **运营团队:** {{ .Labels.team | upper }}

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

    **事件信息:**
    {{ range .Annotations.SortedPairs }}&gt; - {{ .Name }}: {{ .Value | markdown | html }}

    {{ end }}

    **事件标签:**
    {{ range .Labels.SortedPairs }}{{ if and (ne (.Name) "severity") (ne (.Name) "summary") (ne (.Name) "team") }}&gt; - {{ .Name }}: {{ .Value |     markdown | html }}
    {{ end }}{{ end }}
    {{ end }}
    {{ end }}
    {{ define "default.__text_alertresovle_list" }}{{ range . }}
    ---
    **告警级别:** {{ .Labels.severity | upper }}

    **运营团队:** {{ .Labels.team | upper }}

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

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

    **事件信息:**
    {{ range .Annotations.SortedPairs }}&gt; - {{ .Name }}: {{ .Value | markdown | html }}

    {{ end }}

    **事件标签:**
    {{ range .Labels.SortedPairs }}{{ if and (ne (.Name) "severity") (ne (.Name) "summary") (ne (.Name) "team") }}&gt; - {{ .Name }}: {{ .Value |     markdown | html }}
    {{ end }}{{ 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 -}}

    ![警报 图标](https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3626076420,1196179712&amp;fm=15&amp;gp=0.jpg)
    **====侦测到故障====**
    {{ template "default.__text_alert_list" .Alerts.Firing }}

    {{- end }}

    {{ if gt (len .Alerts.Resolved) 0 -}}
    {{ template "default.__text_alertresovle_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 }}    

创建 webhook 的资源配置清单

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# cat dingTalk-webhook-deployment.yml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: monitoring
  name: dingtalk-webhook
  labels:
    app: dingtalk-webhook
spec:
  selector:
    matchLabels:
      app: dingtalk-webhook
  replicas: 1
  template:
    metadata:
      labels:
        app: dingtalk-webhook
    spec:
      containers:
      - name: dingtalk-webhook
        image: harbor.zsf.com/public/prometheus-webhook-dingtalk
        args:
        - --config.file=/etc/prometheus-webhook-dingtalk/config.yml
        #- --ding.profile=guiji=https://oapi.dingtalk.com/robot/send?access_token=5752a9d10727165d116b883b4e7d312b781a3ed90
        ports:
        - containerPort: 8060
          protocol: TCP
        volumeMounts:
        - mountPath: "/etc/prometheus-webhook-dingtalk"
          name: dingtalk-webhook-confing
          subPath: config.yml
        - mountPath: "/etc/prometheus-webhook-dingtalk/templates"
          name: dingtalk-webhook-template
          subPath: template.tmpl
      volumes:
      - name: dingtalk-webhook-confing
        configMap:
          name: dingtalk-webhook-config
      - name: dingtalk-webhook-template
        configMap:
          name: dingtalk-webhook-template
---
apiVersion: v1
kind: Service
metadata:
  namespace: monitoring
  name: dingtalk-webhook
  labels:
    app: dingtalk-webhook
spec:
  selector:
    app: dingtalk-webhook
  ports:
  - name: http
    port: 8060
    targetPort: 8060
    protocol: TCP

解决ControllerManager、Scheduler监控问题

默认安装后访问 prometheus ,会发现有以下有三个报警:

Watchdog 、KubeControllerManagerDownKubeSchedulerDown

Watchdog 是一个正常的报警,这个告警的作用是:如果 alermanger 或者 prometheus 本身挂掉了就发不出告警了,因此一般会采用另一个监控来监控 prometheus ,或者自定义一个持续不断的告警通知,哪一天这个告警通知不发了,说明监控出现问题了。 prometheus operator 已经考虑了这一点,本身携带一个 watchdog ,作为对自身的监控。

如果需要关闭,删除或注释掉 Watchdog 部分

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
vim kube-prometheus-prometheusRule.yaml
...
  - name: general.rules
    rules:
    - alert: TargetDown
      annotations:
        message: \'xxx\'
      expr: 100 * (count(up == 0) BY (job, namespace, service) / count(up) BY (job, namespace, service)) > 10
      for: 10m
      labels:
        severity: warning
#    - alert: Watchdog
#      annotations:
#        message: |
#          This is an alert meant to ensure that the entire alerting pipeline is functional.
#          This alert is always firing, therefore it should always be firing in Alertmanager
#          and always fire against a receiver. There are integrations with various notification
#          mechanisms that send a notification when this alert is not firing. For example the
#          "DeadMansSnitch" integration in PagerDuty.
#      expr: vector(1)
#      labels:
#        severity: none

其他两个 KubeControllerManagerDownKubeSchedulerDown 需要自定义监控,在这边不详细说。
文章链接

分享

CNSRE
作者
CNSRE
一个📚学习中的👨‍💻SRE运维工程师🚀🚀🚀


目录