簡介
Prometheus 最初是 SoundCloud 建構的開源系統監控和報警工具,是一個獨立的開源項目,于2016年加入了 CNCF 基金會,作為繼 Kubernetes 之後的第二個托管項目。
特征
Prometheus 相比于其他傳統監控工具主要有以下幾個特點:
具有由 metric 名稱和鍵/值對辨別的時間序列資料的多元資料模型
有一個靈活的查詢語言
不依賴分布式存儲,隻和本地磁盤有關
通過 HTTP 的服務拉取時間序列資料
也支援推送的方式來添加時間序列資料
還支援通過服務發現或靜态配置發現目标
多種圖形和儀表闆支援
元件
Prometheus 由多個元件組成,但是其中許多元件是可選的:
Prometheus Server:用于抓取名額、存儲時間序列資料
exporter:暴露名額讓任務來抓
pushgateway:push 的方式将名額資料推送到該網關
alertmanager:處理報警的報警元件
adhoc:用于資料查詢
大多數 Prometheus 元件都是用 Go 編寫的,是以很容易建構和部署為靜态的二進制檔案。
prometheus元件架構圖

如上圖,每個被監控的主機都可以通過專用的
exporter
程式提供輸出監控資料的接口,并等待
Prometheus
伺服器周期性的進行資料抓取。如果存在告警規則,則抓取到資料之後會根據規則進行計算,滿足告警條件則會生成告警,并發送到
Alertmanager
完成告警的彙總和分發。當被監控的目标有主動推送資料的需求時,可以以
Pushgateway
元件進行接收并臨時存儲資料,然後等待
Prometheus
伺服器完成資料的采集。
任何被監控的目标都需要事先納入到監控系統中才能進行時序資料采集、存儲、告警和展示,監控目标可以通過配置資訊以靜态形式指定,也可以讓Prometheus通過服務發現的機制進行動态管理。下面是元件的一些解析:
- 監控代理程式:如node_exporter:收集主機的名額資料,如平均負載、CPU、記憶體、磁盤、網絡等等多個次元的名額資料。
- kubelet(cAdvisor):收集容器名額資料,也是K8S的核心名額收集,每個容器的相關名額資料包括:CPU使用率、限額、檔案系統讀寫限額、記憶體使用率和限額、網絡封包發送、接收、丢棄速率等等。
- API Server:收集API Server的性能名額資料,包括控制隊列的性能、請求速率和延遲時長等等
- etcd:收集etcd存儲叢集的相關名額資料
- kube-state-metrics:該元件可以派生出k8s相關的多個名額資料,主要是資源類型相關的計數器和中繼資料資訊,包括制定類型的對象總數、資源限額、容器狀态以及Pod資源标簽系列等。
Prometheus 能夠 直接 把 Kubernetes API Server 作為 服務 發現 系統 使用 進而 動态 發現 和 監控 叢集 中的 所有 可被 監控 的 對象。 這裡 需要 特别 說明 的 是, Pod 資源 需要 添加 下列 注解 資訊 才 能被 Prometheus 系統 自動 發現 并 抓取 其 内建 的 名額 資料。
- 1) prometheus. io/ scrape: 用于 辨別 是否 需要 被 采集 名額 資料, 布爾 型 值, true 或 false。
- 2) prometheus. io/ path: 抓取 名額 資料 時 使用 的 URL 路徑, 一般 為/ metrics。
- 3) prometheus. io/ port: 抓取 名額 資料 時 使 用的 套 接 字 端口, 如 8080。
另外, 僅 期望 Prometheus 為 後端 生成 自定義 名額 時 僅 部署 Prometheus 伺服器 即可, 它 甚至 也不 需要 資料 持久 功能。 但 若要 配置 完整 功能 的 監控 系統, 管理者 還需 要在 每個 主機 上 部署 node_ exporter、 按 需 部署 其他 特有 類型 的 exporter 以及 Alertmanager。
kube-state-metrics與metric-server的對比
metric-server(或heapster)是一個叢集元件定期通過kubelet來擷取叢集節點的cpu、記憶體使用率這種監控名額,而且它隻保留最新資料且存儲在記憶體中,不負責發送給第三方,你可以通過其他方式把他們發送給存儲後端,如influxdb或雲廠商,他目前的核心作用是:為HPA等元件提供決策名額支援。
kube-state-metrics關注于擷取k8s各種資源對象的最新狀态,如deployment或者daemonset,它在記憶體中保留kubernetes叢集狀态的快照并且在随後的時間裡基于這個快照生成新的名額,而且它也不負責發資料發給第三方。将kube-state-metrics作為單獨的項目,還可以從Prometheus等監控系統通路這些名額。
之是以沒有把kube-state-metrics納入到metric-server的能力中,是因為他們的關注點本質上是不一樣的。metric-server僅僅是擷取、格式化現有資料,寫入特定的存儲,實質上是一個監控系統。而kube-state-metrics是将k8s的運作狀況在記憶體中做了個快照,并且擷取新的名額,但他沒有能力導出這些名額 換個角度講,kube-state-metrics本身是metric-server的一種資料來源,雖然現在沒有這麼做。 另外,像Prometheus這種監控系統,并不會去用metric-server中的資料,他都是自己做名額收集、內建的(Prometheus包含了metric-server的能力),但Prometheus可以監控metric-server本身元件的監控狀态并适時報警,這裡的監控就可以通過kube-state-metrics來實作,如metric-serverpod的運作狀态。
部署前提
檢查ceph叢集狀态
# ceph -s
......
health: HEALTH_OK
檢查kubernetes叢集狀态
# kubectl get nodes
NAME STATUS ROLES AGE VERSION
20.0.0.201 Ready,SchedulingDisabled master 4d9h v1.17.2
20.0.0.202 Ready,SchedulingDisabled master 4d9h v1.17.2
20.0.0.203 Ready,SchedulingDisabled master 4d9h v1.17.2
20.0.0.204 Ready node 4d9h v1.17.2
20.0.0.205 Ready node 4d9h v1.17.2
20.0.0.206 Ready node 4d9h v1.17.2
注:ceph 使用assembly pool,prometheus叢集的名稱空間為assembly
這裡我隻給出具體配置,有關詳細的理論解釋請自行google。
建議:學習本篇之前,先搞通此篇:https://www.cnblogs.com/zisefeizhu/p/12519658.html
部署總述
# pwd
/data/k8s/prometheus
# tree ./
./
├── altermanager
│?? ├── alertmanager-conf.yaml
│?? ├── alertmanager-deployment.yaml
│?? └── alertmanager-svc.yaml
├── ceph-prometheus-storageclass.yaml
├── grafana
│?? ├── grafana-deployment.yaml
│?? ├── grafana-ingressroute.yaml
│?? ├── grafana-pvc.yaml
│?? └── grafana-svc.yaml
├── node-exporter
│?? └── node-exporter.yaml
└── prometheus
├── prometheus-cm.yaml
├── prometheus-deploy.yaml
├── prometheus-ingressroute.yaml
├── prometheus-pvc.yaml
├── prometheus-rbac.yaml
└── prometheus-svc.yaml
4 directories, 15 files
# kubectl get pods -n assembly
NAME READY STATUS RESTARTS AGE
alertmanager-76fd475999-l9pdh 1/1 Running 0 54m
grafana-866bbc647-2kxkk 1/1 Running 0 3h50m
node-exporter-7x5wb 1/1 Running 0 4h2m
node-exporter-8gfsn 1/1 Running 0 4h30m
node-exporter-dsk89 1/1 Running 0 4h30m
node-exporter-jw7ck 1/1 Running 0 4h30m
node-exporter-rcw6c 1/1 Running 0 4h30m
node-exporter-w5sz6 1/1 Running 0 4h30m
prometheus-7d844f7645-x75rp 1/1 Running 0 4h31m
rbd-provisioner-9cf46c856-mvtx5 1/1 Running 15 34h
# kubectl get pvc -n assembly
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
grafana-pvc Bound pvc-8b1550f9-9b7d-4884-b41d-ea10106f9321 5Gi RWO ceph-prometheus 4h46m
prometheus-pvc Bound pvc-3ae3ac53-537f-4641-b626-b74da48db053 10Gi RWO ceph-prometheus 4h31m
部署prometheus
# ll
總用量 4
-rw-r--r-- 1 root root 1018 3月 20 08:33 ceph-prometheus-storageclass.yaml
drwxr-xr-x 2 root root 180 3月 20 20:51 prometheus
# cat ceph-prometheus-storageclass.yaml
##########################################################################
#Author: zisefeizhu
#QQ: 2********0
#Date: 2020-03-20
#FileName: ceph-prometheus-storageclass.yaml
#URL: https://www.cnblogs.com/zisefeizhu/
#Description: The test script
#Copyright (C): 2020 All rights reserved
###########################################################################
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ceph-prometheus
namespace: assembly
annotations:
storageclass.kubernetes.io/is-default-class: "false"
provisioner: ceph.com/rbd
reclaimPolicy: Retain
parameters:
monitors: 20.0.0.205:6789,20.0.0.206:6789,20.0.0.207:6789
adminId: admin
adminSecretName: ceph-admin-secret
adminSecretNamespace: assembly
pool: assembly
fsType: xfs
userId: assembly
userSecretName: ceph-assembly-secret
imageFormat: "2"
imageFeatures: "layering"
# cat prometheus-cm.yaml
##########################################################################
#Author: zisefeizhu
#QQ: 2********0
#Date: 2020-03-20
#FileName: prometheus-cm.yaml
#URL: https://www.cnblogs.com/zisefeizhu/
#Description: The test script
#Copyright (C): 2020 All rights reserved
###########################################################################
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-config
namespace: assembly
data:
prometheus.yml: |
global:
scrape_interval: 15s
scrape_timeout: 15s
alerting:
alertmanagers:
- static_configs:
- targets: ["alertmanager:9093"]
rule_files:
- /etc/prometheus/rules.yaml
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'traefik'
static_configs:
- targets: ['traefik.kube-system.svc.cluster.local:8080']
- job_name: "kubernetes-nodes"
kubernetes_sd_configs:
- role: node
relabel_configs:
- source_labels: [__address__]
regex: '(.*):10250'
replacement: '${1}:9100'
target_label: __address__
action: replace
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
- job_name: 'kubernetes-kubelet'
kubernetes_sd_configs:
- role: node
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecure_skip_verify: true
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
action: replace
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
target_label: __address__
- action: labelmap
regex: __meta_kubernetes_pod_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: kubernetes_namespace
- source_labels: [__meta_kubernetes_pod_name]
action: replace
target_label: kubernetes_pod_name
- job_name: "kubernetes-apiserver"
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: default;kubernetes;https
- job_name: "kubernetes-scheduler"
kubernetes_sd_configs:
- role: endpoints
- 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
rules.yaml: |
groups:
- name: test-rule
rules:
- alert: NodeMemoryUsage
expr: (sum(node_memory_MemTotal_bytes) - sum(node_memory_MemFree_bytes + node_memory_Buffers_bytes+node_memory_Cached_bytes)) / sum(node_memory_MemTotal_bytes) * 100 > 5
for: 2m
labels:
team: node
annotations:
summary: "{{$labels.instance}}: High Memory usage detected"
description: "{{$labels.instance}}: Memory usage is above 80% (current value is: {{ $value }}"
# cat prometheus-deploy.yaml
##########################################################################
#Author: zisefeizhu
#QQ: 2********0
#Date: 2020-03-20
#FileName: prometheus-deploy.yaml
#URL: https://www.cnblogs.com/zisefeizhu/
#Description: The test script
#Copyright (C): 2020 All rights reserved
###########################################################################
apiVersion: apps/v1
kind: Deployment
metadata:
name: prometheus
namespace: assembly
labels:
app: prometheus
spec:
selector:
matchLabels:
app: prometheus
template:
metadata:
labels:
app: prometheus
spec:
imagePullSecrets:
- name: k8s-harbor-login
serviceAccountName: prometheus
containers:
- image: harbor.linux.com/prometheus/prometheus:v2.4.3
name: prometheus
command:
- "/bin/prometheus"
args:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/prometheus"
- "--storage.tsdb.retention=24h"
- "--web.enable-admin-api" # 控制對admin HTTP API的通路,其中包括删除時間序列等功能
- "--web.enable-lifecycle" # 支援熱更新,直接執行localhost:9090/-/reload立即生效
ports:
- containerPort: 9090
protocol: TCP
name: http
volumeMounts:
- mountPath: "/prometheus"
subPath: prometheus
name: data
- mountPath: "/etc/prometheus"
name: config-volume
resources:
requests:
cpu: 100m
memory: 512Mi
limits:
cpu: 100m
memory: 512Mi
securityContext:
runAsUser: 0
volumes:
- name: data
persistentVolumeClaim:
claimName: prometheus-pvc
- configMap:
name: prometheus-config
name: config-volume
nodeSelector: ## 設定node篩選器,在特定label的節點上啟動
prometheus: "true"
# cat prometheus-ingressroute.yaml
##########################################################################
#Author: zisefeizhu
#QQ: 2********0
#Date: 2020-03-20
#FileName: prometheus-ingressroute.yaml
#URL: https://www.cnblogs.com/zisefeizhu/
#Description: The test script
#Copyright (C): 2020 All rights reserved
###########################################################################
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: prometheus
namespace: assembly
spec:
entryPoints:
- web
routes:
- match: Host(`prometheus.linux.com`)
kind: Rule
services:
- name: prometheus
port: 9090
# cat prometheus-pvc.yaml
##########################################################################
#Author: zisefeizhu
#QQ: 2********0
#Date: 2020-03-20
#FileName: prometheus-pvc.yaml
#URL: https://www.cnblogs.com/zisefeizhu/
#Description: The test script
#Copyright (C): 2020 All rights reserved
###########################################################################
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: prometheus-pvc
namespace: assembly
# labels:
# app: gitlab
spec:
storageClassName: ceph-prometheus
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
# cat prometheus-rbac.yaml
##########################################################################
#Author: zisefeizhu
#QQ: 2********0
#Date: 2020-03-20
#FileName: prometheus-rbac.yaml
#URL: https://www.cnblogs.com/zisefeizhu/
#Description: The test script
#Copyright (C): 2020 All rights reserved
###########################################################################
apiVersion: v1
kind: ServiceAccount
metadata:
name: prometheus
namespace: assembly
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: prometheus
rules:
- apiGroups:
- ""
resources:
- nodes
- services
- endpoints
- pods
- nodes/proxy
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- configmaps
- nodes/metrics
verbs:
- get
- nonResourceURLs:
- /metrics
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: prometheus
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prometheus
subjects:
- kind: ServiceAccount
name: prometheus
namespace: assembly
# cat prometheus-svc.yaml
##########################################################################
#Author: zisefeizhu
#QQ: 2********0
#Date: 2020-03-20
#FileName: prometheus-svc.yaml
#URL: https://www.cnblogs.com/zisefeizhu/
#Description: The test script
#Copyright (C): 2020 All rights reserved
###########################################################################
apiVersion: v1
kind: Service
metadata:
name: prometheus
namespace: assembly
labels:
app: prometheus
spec:
selector:
app: prometheus
type: NodePort
ports:
- name: web
port: 9090
targetPort: http
# kubectl get pods -n assembly
NAME READY STATUS RESTARTS AGE
prometheus-7d844f7645-x75rp 1/1 Running 0 4h14m
rbd-provisioner-9cf46c856-mvtx5 1/1 Running 14 34h
部署node-exporter
# cat node-exporter.yaml
##########################################################################
#Author: zisefeizhu
#QQ: 2********0
#Date: 2020-03-20
#FileName: node_exporter.yaml
#URL: https://www.cnblogs.com/zisefeizhu/
#Description: The test script
#Copyright (C): 2020 All rights reserved
###########################################################################
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter
namespace: assembly
labels:
name: node-exporter
spec:
selector:
matchLabels:
name: node-exporter
template:
metadata:
labels:
name: node-exporter
spec:
hostPID: true
hostIPC: true
hostNetwork: true
containers:
- name: node-exporter
image: prom/node-exporter:v0.17.0
ports:
- containerPort: 9100
resources:
requests:
cpu: 0.15
securityContext:
privileged: true
args:
- --path.procfs
- /host/proc
- --path.sysfs
- /host/sys
- --collector.filesystem.ignored-mount-points
- '"^/(sys|proc|dev|host|etc)($|/)"'
volumeMounts:
- name: dev
mountPath: /host/dev
- name: proc
mountPath: /host/proc
- name: sys
mountPath: /host/sys
- name: rootfs
mountPath: /rootfs
tolerations:
- key: "node-role.kubernetes.io/master"
operator: "Exists"
effect: "NoSchedule"
volumes:
- name: proc
hostPath:
path: /proc
- name: dev
hostPath:
path: /dev
- name: sys
hostPath:
path: /sys
- name: rootfs
hostPath:
path: /
# kubectl get pods -n assembly
NAME READY STATUS RESTARTS AGE
node-exporter-7x5wb 1/1 Running 0 3h45m
node-exporter-8gfsn 1/1 Running 0 4h13m
node-exporter-dsk89 1/1 Running 0 4h13m
node-exporter-jw7ck 1/1 Running 0 4h13m
node-exporter-rcw6c 1/1 Running 0 4h13m
node-exporter-w5sz6 1/1 Running 0 4h13m
grafana部署
# cat grafana-deployment.yaml
##########################################################################
#Author: zisefeizhu
#QQ: 2********0
#Date: 2020-03-20
#FileName: grafana-deployment.yaml
#URL: https://www.cnblogs.com/zisefeizhu/
#Description: The test script
#Copyright (C): 2020 All rights reserved
###########################################################################
apiVersion: apps/v1
kind: Deployment
metadata:
name: grafana
namespace: assembly
labels:
app: grafana
spec:
selector:
matchLabels:
app: grafana
revisionHistoryLimit: 10
template:
metadata:
labels:
app: grafana
spec:
containers:
- name: grafana
image: grafana/grafana:6.6.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3000
name: grafana
env:
- name: GF_SECURITY_ADMIN_USER
value: admin
- name: GF_SECURITY_ADMIN_PASSWORD
value: zisefeizhu
readinessProbe:
failureThreshold: 10
httpGet:
path: /api/health
port: 3000
scheme: HTTP
initialDelaySeconds: 60
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 30
livenessProbe:
failureThreshold: 10
httpGet:
path: /api/health
port: 3000
scheme: HTTP
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
volumeMounts:
- mountPath: /var/lib/grafana
subPath: grafana
name: storage
securityContext:
fsGroup: 472
runAsUser: 472
volumes:
- name: storage
persistentVolumeClaim:
claimName: grafana-pvc
nodeSelector: ## 設定node篩選器,在特定label的節點上啟動
grafana: "true"
# cat grafana-ingressroute.yaml
##########################################################################
#Author: zisefeizhu
#QQ: 2********0
#Date: 2020-03-20
#FileName: grafana-ingressroute.yaml
#URL: https://www.cnblogs.com/zisefeizhu/
#Description: The test script
#Copyright (C): 2020 All rights reserved
###########################################################################
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: grafana
namespace: assembly
spec:
entryPoints:
- web
routes:
- match: Host(`grafana.linux.com`)
kind: Rule
services:
- name: grafana
port: 3000
# cat grafana-pvc.yaml
##########################################################################
#Author: zisefeizhu
#QQ: 2********0
#Date: 2020-03-20
#FileName: grafana-pvc.yaml
#URL: https://www.cnblogs.com/zisefeizhu/
#Description: The test script
#Copyright (C): 2020 All rights reserved
###########################################################################
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: grafana-pvc
namespace: assembly
# labels:
# app: gitlab
spec:
storageClassName: ceph-prometheus
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
# cat grafana-svc.yaml
##########################################################################
#Author: zisefeizhu
#QQ: 2********0
#Date: 2020-03-20
#FileName: grafana-svc.yaml
#URL: https://www.cnblogs.com/zisefeizhu/
#Description: The test script
#Copyright (C): 2020 All rights reserved
###########################################################################
apiVersion: v1
kind: Service
metadata:
name: grafana
namespace: assembly
labels:
app: grafana
spec:
type: NodePort
ports:
- port: 3000
selector:
app: grafana
# kubectl get pods -n assembly
NAME READY STATUS RESTARTS AGE
grafana-866bbc647-2kxkk 1/1 Running 0 3h41m
推薦模闆
8919 9276 10000
altermanager部署
# cat alertmanager-conf.yaml
##########################################################################
#Author: zisefeizhu
#QQ: 2********0
#Date: 2020-03-20
#FileName: alertmanager-conf.yaml
#URL: https://www.cnblogs.com/zisefeizhu/
#Description: The test script
#Copyright (C): 2020 All rights reserved
###########################################################################
apiVersion: v1
kind: ConfigMap
metadata:
name: alert-config
namespace: assembly
data:
config.yml: |-
global:
# 在沒有報警的情況下聲明為已解決的時間
resolve_timeout: 5m
# 配置郵件發送資訊
smtp_smarthost: 'smtp.163.com:25'
smtp_from: '[email protected]'
smtp_auth_username: '[email protected]'
smtp_auth_password: 'lkxx3x23' #改成自己的密碼
smtp_hello: '163.com'
smtp_require_tls: false
# 所有報警資訊進入後的根路由,用來設定報警的分發政策
route:
# 這裡的标簽清單是接收到報警資訊後的重新分組标簽,例如,接收到的報警資訊裡面有許多具有 cluster=A 和 alertname=LatncyHigh 這樣的标簽的報警資訊将會批量被聚合到一個分組裡面
group_by: ['alertname', 'cluster']
# 當一個新的報警分組被建立後,需要等待至少group_wait時間來初始化通知,這種方式可以確定您能有足夠的時間為同一分組來擷取多個警報,然後一起觸發這個報警資訊。
group_wait: 30s
# 當第一個報警發送後,等待'group_interval'時間來發送新的一組報警資訊。
group_interval: 30m
# 如果一個報警資訊已經發送成功了,等待'repeat_interval'時間來重新發送他們
repeat_interval: 30m
# 預設的receiver:如果一個報警沒有被一個route比對,則發送給預設的接收器
receiver: default
# 上面所有的屬性都由所有子路由繼承,并且可以在每個子路由上進行覆寫。
routes:
- receiver: email
group_wait: 10s
match:
team: node
receivers:
- name: 'default'
email_configs:
- to: '[email protected]'
send_resolved: true
# cat alertmanager-deployment.yaml
##########################################################################
#Author: zisefeizhu
#QQ: 2********0
#Date: 2020-03-20
#FileName: alertmanager-deployment.yaml
#URL: https://www.cnblogs.com/zisefeizhu/
#Description: The test script
#Copyright (C): 2020 All rights reserved
###########################################################################
apiVersion: apps/v1
kind: Deployment
metadata:
name: alertmanager
namespace: assembly
spec:
selector:
matchLabels:
app: alertmanager
replicas: 1
template:
metadata:
labels:
app: alertmanager
spec:
containers:
- name: alertmanager
image: prom/alertmanager:v0.15.3
imagePullPolicy: IfNotPresent
args:
- "--config.file=/etc/alertmanager/config.yml"
- "--storage.path=/alertmanager/data"
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 100m
memory: 256Mi
volumeMounts:
- name: alert-config
mountPath: /etc/alertmanager
ports:
- name: http
containerPort: 9093
volumes:
- name: alert-config
configMap:
name: alert-config
nodeSelector: ## 設定node篩選器,在特定label的節點上啟動
alter: "true"
# cat alertmanager-svc.yaml
##########################################################################
#Author: zisefeizhu
#QQ: 2********0
#Date: 2020-03-20
#FileName: alertmanager-svc.yaml
#URL: https://www.cnblogs.com/zisefeizhu/
#Description: The test script
#Copyright (C): 2020 All rights reserved
###########################################################################
apiVersion: v1
kind: Service
metadata:
name: alertmanager
namespace: assembly
annotations:
prometheus.io/scrape: "true"
spec:
selector:
app: alertmanager
ports:
- name: http
port: 9093
Prometheus配置檔案說明
# Kubernetes的API SERVER會暴露API服務,Promethues內建了對Kubernetes的自動發現,它有5種模式:Node、Service
# 、Pod、Endpoints、ingress,下面是Prometheus官方給出的對Kubernetes服務發現的執行個體。這裡你會看到大量的relabel_configs,
# 其實你就是把所有的relabel_configs去掉一樣可以對kubernetes做服務發現。relabel_configs僅僅是對采集過來的名額做二次處理,比如
# 要什麼不要什麼以及替換什麼等等。而以__meta_開頭的這些中繼資料标簽都是執行個體中包含的,而relabel則是動态的修改、覆寫、添加删除這些标簽
# 或者這些标簽對應的值。而且以__開頭的标簽通常是系統内部使用的,是以這些标簽不會被寫入樣本資料中,如果我們要收集這些東西那麼則要進行
# relabel操作。當然reabel操作也不僅限于操作__開頭的标簽。
#
# action的行為:
# replace:預設行為,不配置action的話就采用這種行為,它會根據regex來去比對source_labels标簽上的值,并将并将比對到的值寫入target_label中
# labelmap:它會根據regex去比對标簽名稱,并将比對到的内容作為新标簽的名稱,其值作為新标簽的值
# keep:僅收集比對到regex的源标簽,而會丢棄沒有比對到的所有标簽,用于選擇
# drop:丢棄比對到regex的源标簽,而會收集沒有比對到的所有标簽,用于排除
# labeldrop:使用regex比對标簽,符合regex規則的标簽将從target執行個體中移除,其實也就是不收集不儲存
# labelkeep:使用regex比對标簽,僅收集符合regex規則的标簽,不符合的不收集
#
global:
scrape_interval: 10s
evaluation_interval: 30s
scrape_configs:
# 用于發現API SERVER
- job_name: 'kubernetes-apiservers'
kubernetes_sd_configs:
# 發現endpoints,它是從列出的服務端點發現目标,這個endpoints來自于Kubernetes中的service,每一個service都有對應的endpoints,這裡是一個清單
# 可以是一個IP:PORT也可以是多個,這些IP:PORT就是service通過标簽選擇器選擇的POD的IP和端口。是以endpoints角色就是用來發現server對應的pod的IP的
# kubernetes會有一個預設的service,通過找到這個service的endpoints就找到了api server的IP:PORT,那endpoints有很多,我怎麼知道哪個是api server呢
# 這個就靠source_labels指定的标簽名稱了。
- role: endpoints
# 通過什麼形式來連接配接,預設是https
scheme: https
# 下面這個ca_file和token_file的路徑都是預設的,你可能預設設定能用麼?其實可以,因為每一個運作起來的POD kubernetes都會為其
# 建立一個serviceaccout的Secret并且挂載到下面的目錄上,裡面就有ca.crt和token這兩個檔案,你可以自己啟動一個POD,然後通過
# kubectl describe pods 來檢視,一定會在Volumes下面有一個default-token-XXX的東西,并且Mounts裡面有下面的目錄。
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
# 下面的含義是源标簽__meta_kubernetes_namespace等如果其值為default;kubernetes;https标簽順序和值要對應。換句話說就是
# 當__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name三者對應的
# 值為default、kubernetes、https則進行保留,而且該endpoints對應的位址為api server的位址。
#
# __meta_kubernetes_namespace 端點對象的命名空間,在不同對象上這個标簽的含義不同,在角色是endpoints中這個是端點對象的名稱空間
# __meta_kubernetes_service_name 端點對象的服務名稱
# __meta_kubernetes_endpoint_port_name 端點的端口名稱
#
# kubernetes預設在default名稱空間有一個叫做kubernetes的service,是以這個service的有3個設定對應的就是下面三個标簽
# __meta_kubernetes_namespace 值為default
# __meta_kubernetes_service_name 值為kubernetes
# __meta_kubernetes_endpoint_port_name 值為https
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
action: keep
regex: default;kubernetes;https
# 配置針對kubelet的服務發現以及對标簽的處理,是擷取kubelet上/metrics接口資料來擷取node的資源使用情況
- job_name: 'kubernetes-nodes-kubelet'
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
# 跳過CA驗證
# insecure_skip_verify: true
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
kubernetes_sd_configs:
# 使用node角色,它使用預設的kubelet提供的http端口來發現叢集中每個node節點。那具體位址是什麼呢?
# 位址類型有四種NodeInternalIP, NodeExternalIP, NodeLegacyHostIP 和 NodeHostName,預設為這四個中第一個可用的位址。
# 那麼這裡為什麼使用node角色呢?因為node角色就是用來發現kubelet的
# __meta_kubernetes_node_name:節點對象的名字
# __meta_kubernetes_node_label_<labelname>:表示節點對象上的每一個标簽
# __meta_kubernetes_node_annotation_<annotationname>:表示節點對象上的每一個annotation
# __meta_kubernetes_node_address_<address_type>:如果存在,那麼将是每一個節點位址類型的第一個位址
# Node模式,Prometheus會自動發現Kubernetes中所有Node節點的資訊并作為監控的目标Target。
# 而這些Target的通路位址實際上就是Kubelet的通路位址,并且Kubelet實際上直接内置了對Promtheus的支援
- role: node
relabel_configs:
# 保留(.+)比對到的内容,去掉__meta_kubernetes_node_label_,實際上就是把(.+)當做新标簽,然後老标簽的值給這個新标簽,
# 這裡沒有設定source_labels,則表示比對所有标簽
- action: labelmap
# 比對節點對象上的每一個标簽
regex: __meta_kubernetes_node_label_(.+)
# 抓取cAdvisor資料,是擷取kubelet上/metrics/cadvisor接口資料來擷取容器的資源使用情況
- job_name: 'kubernetes-nodes-cadvisor'
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
kubernetes_sd_configs:
# 使用角色為node
- role: node
relabel_configs:
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
# 把__metrics_path__的值替換為/metrics/cadvisor,因為預設是/metrics
- target_label: __metrics_path__
replacement: /metrics/cadvisor
# 抓取服務端點,整個這個任務都是用來發現node-exporter和kube-state-metrics-service的,這裡用的是endpoints角色,這是通過這兩者的service來發現
# 的後端endpoints。另外需要說明的是如果滿足采集條件,那麼在service、POD中定義的labels也會被采集進去
- job_name: 'kubernetes-service-endpoints'
kubernetes_sd_configs:
- role: endpoints
relabel_configs:
# 重新打标僅抓取到的具有 "prometheus.io/scrape: true" 的annotation的端點,意思是說如果某個service具有prometheus.io/scrape = true annotation聲明則抓取
# annotation本身也是鍵值結構,是以這裡的源标簽設定為鍵,而regex設定值,當值比對到regex設定的内容時則執行keep動作也就是保留,其餘則丢棄.
# node-exporter這個POD的service裡面就有一個叫做prometheus.io/scrape = true的annotations是以就找到了node-exporter這個POD
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
action: keep
regex: true
# 應用中自定義暴露的名額,也許你暴露的API接口不是/metrics這個路徑,那麼你可以在這個POD對應的service中做一個
# "prometheus.io/path = /mymetrics" 聲明,下面的意思就是把你聲明的這個路徑指派給__metrics_path__
# 其實就是讓prometheus來擷取自定義應用暴露的metrices的具體路徑,不過這裡寫的要和service中做好約定
# 如果service中這樣寫 prometheus.io/app-metrics-path: '/metrics' 那麼你這裡就要
# __meta_kubernetes_service_annotation_prometheus_io_app_metrics_path這樣寫
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
# 暴露自定義的應用的端口,就是把位址和你在service中定義的 "prometheus.io/port = <port>" 聲明做一個拼接
# 然後指派給__address__,這樣prometheus就能擷取自定義應用的端口,然後通過這個端口再結合__metrics_path__來擷取
# 名額,如果__metrics_path__值不是預設的/metrics那麼就要使用上面的标簽替換來擷取真正暴露的具體路徑
- source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
action: replace
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
target_label: __address__
# 重新設定scheme
# 比對源标簽__meta_kubernetes_service_annotation_prometheus_io_scheme也就是prometheus.io/scheme annotation
# 如果源标簽的值比對到regex則把值替換為__scheme__對應的值
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
action: replace
target_label: __scheme__
regex: (https?)
# 下面主要是為了給樣本添加額外資訊
- 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,不過如果要想監控service則需要安裝blackbox-exporter
- job_name: 'kubernetes-services-http'
metrics_path: /probe
# 生成__param_module="http_2xx"的label,如果是TCP探測則使用 module: [tcp_connect]
params:
module: [http_2xx]
kubernetes_sd_configs:
- role: service
relabel_configs:
# 為了讓service可以被探測到,那需要在service的annotation中增加 prometheus.io/scrape: true 聲明
# 也就是隻保留prometheus.io/scrape: true的service
- action: keep
regex: true
source_labels:
- __meta_kubernetes_service_annotation_prometheus_io_scrape
# 用__address__這個label的值建立一個名為__param_target的label為blackbox-exporter,值為内部service的通路位址,作為blackbox-exporter采集用
- source_labels: [__address__]
target_label: __param_target
# 用blackbox-exporter的service位址值”prometheus-blackbox-exporter:9115"替換原__address__的值
- target_label: __address__
replacement: blackbox-exporter.example.com:9115
- source_labels: [__param_target]
target_label: instance
# 下面主要是為了給樣本添加額外資訊
- action: labelmap
regex: __meta_kubernetes_service_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
target_label: kubernetes_namespace
- source_labels: [__meta_kubernetes_service_name]
target_label: kubernetes_name
# 下面是對ingresses監控,不過如果要想監控ingresses則需要安裝blackbox-exporter
- job_name: 'kubernetes-ingresses'
metrics_path: /probe
# 生成__param_module="http_2xx"的label
params:
module: [http_2xx]
kubernetes_sd_configs:
- role: ingress
relabel_configs:
# Example relabel to probe only some ingresses that have "example.io/should_be_probed = true" annotation
# - source_labels: [__meta_kubernetes_ingress_annotation_example_io_should_be_probed]
# action: keep
# regex: true
- source_labels: [__meta_kubernetes_ingress_scheme,__address__,__meta_kubernetes_ingress_path]
regex: (.+);(.+);(.+)
replacement: ${1}://${2}${3}
target_label: __param_target
- target_label: __address__
replacement: blackbox-exporter.example.com:9115
- source_labels: [__param_target]
target_label: instance
# 下面主要是為了給樣本添加額外資訊
- action: labelmap
regex: __meta_kubernetes_ingress_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
target_label: kubernetes_namespace
- source_labels: [__meta_kubernetes_ingress_name]
target_label: kubernetes_name
# 抓取POD進行監控
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
# POD的 annotation 中含有"prometheus.io/scrape: true" 的則保留,意思就是會被Prometheus抓取,不具有這個的POD則不會被抓取
- action: keep
regex: true
source_labels:
- __meta_kubernetes_pod_annotation_prometheus_io_scrape
# 擷取POD的 annotation 中定義的"prometheus.io/path: XXX"定義的值,這個值就是你的程式暴露符合prometheus規範的metrics的位址
# 如果你的metrics的位址不是 /metrics 的話,通過這個标簽說,那麼這裡就會把這個值指派給 __metrics_path__這個變量,因為prometheus
# 是通過這個變量擷取路徑然後進行拼接出來一個完整的URL,并通過這個URL來擷取metrics值的,因為prometheus預設使用的就是 http(s)://X.X.X.X/metrics
# 這樣一個路徑來擷取的。
- action: replace
regex: (.+)
source_labels:
- __meta_kubernetes_pod_annotation_prometheus_io_path
target_label: __metrics_path__
# 這裡是端口資訊,因為你的程式很有可能在容器中并不是以80端口運作的,那麼就需要做一個拼接http(s)://x.x.x.x:xx/metrics
# __address__在prometheus中代表的就是執行個體的IP位址,而POD中的annotation 中定義的"prometheus.io/port: XX"就是你程式
# 被通路到的端口,最終在prometheus中将會被顯示為 instance=X.X.X.X:XX這樣
- action: replace
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
source_labels:
- __address__
- __meta_kubernetes_pod_annotation_prometheus_io_port
target_label: __address__
- action: labelmap
regex: __meta_kubernetes_pod_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: kubernetes_namespace
- source_labels: [__meta_kubernetes_pod_name]
action: replace
target_label: kubernetes_pod_name
後續:
本篇嚴格來說是完成了一部分,還有些監控項、監控政策、告警平台沒有加入,會補的。
過手如登山,一步一重天