簡介
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: '13xxxxxxx91@163.com'
smtp_auth_username: '13xxxxxxx91@163.com'
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: '23xxxxxx0@qq.com'
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
后續:
本篇嚴格來說是完成了一部分,還有些監控項、監控策略、告警平台沒有加入,會補的。
