050.Kubernetes集群管理-Prometheus+Grafana監控方案


一 Prometheus概述

1.1 Prometheus簡介

Prometheus是由SoundCloud公司開發的開源監控系統,是繼Kubernetes之后CNCF第2個畢業的項目,在容器和微服務領域得到了廣泛應用。Prometheus的主要特點如下:
  • 使用指標名稱及鍵值對標識的多維度數據模型。
  • 采用靈活的查詢語言PromQL。
  • 不依賴分布式存儲,為自治的單節點服務。
  • 使用HTTP完成對監控數據的拉取。
  • 支持通過網關推送時序數據。
  • 支持多種圖形和Dashboard的展示,例如Grafana。
Prometheus生態系統由各種組件組成,用於功能的擴充。
  • Prometheus Server:負責監控數據采集和時序數據存儲,並提供數據查詢功能。
  • 客戶端SDK:對接Prometheus的開發工具包。
  • Push Gateway:推送數據的網關組件。
  • 第三方Exporter:各種外部指標收集系統,其數據可以被Prometheus采集。
  • AlertManager:告警管理器。
  • 其他輔助支持工具。
Prometheus的核心組件Prometheus Server的主要功能包括:
  • 從Kubernetes Master獲取需要監控的資源或服務信息;
  • 從各種Exporter抓取(Pull)指標數據,然后將指標數據保存在時序數據庫(TSDB)中;
  • 向其他系統提供HTTP API進行查詢;
  • 提供基於PromQL語言的數據查詢;
  • 可以將告警數據推送(Push)給AlertManager,等等。

1.2 Prometheus組件架構圖

clipboard
Prometheus 直接從jobs接收或者通過中間的 Pushgateway 網關被動獲取指標數據,在本地存儲所有獲取的指標數據,並對這些數據進行一些規則整理,用來生成一些聚合數據或者報警信息,然后可以通過 Grafana 或者其他工具來可視化這些數據。
其工作流程大致如下:
  1. Prometheus 服務器定期從配置好的 jobs 或者 exporters 中獲取度量數據;或者接收來自推送網關發送過來的度量數據。
  2. Prometheus 服務器在本地存儲收集到的度量數據,並對這些數據進行聚合;
  3. 運行已定義好的 alert.rules,記錄新的時間序列或者向告警管理器推送警報。
  4. 告警管理器根據配置文件,對接收到的警報進行處理,並通過email等途徑發出告警。
  5. Grafana等圖形工具獲取到監控數據,並以圖形化的方式進行展示。

1.3 Prometheus監控粒度

Prometheus作為監控系統主要在以下各層面實現監控:
  • 基礎設施層:監控各個主機服務器資源(包括Kubernetes的Node和非Kubernetes的Node),如CPU,內存,網絡吞吐和帶寬占用,磁盤I/O和磁盤使用等指標。
  • 中間件層:監控獨立部署於Kubernetes集群之外的中間件,例如:MySQL、Redis、RabbitMQ、ElasticSearch、Nginx等。
  • Kubernetes集群:監控Kubernetes集群本身的關鍵指標
  • Kubernetes集群上部署的應用:監控部署在Kubernetes集群上的應用

二 Prometheus相關概念

2.1 數據模型

Prometheus從根本上將所有數據存儲為時間序列:屬於相同度量標准和同一組標注尺寸的時間戳值流。除了存儲的時間序列之外,Prometheus可能會生成臨時派生時間序列作為查詢的結果。
  • 度量名稱和標簽
每個時間序列都是由度量標准名稱和一組鍵值對(也稱為標簽)組成唯一標識。度量名稱指定被測量的系統的特征(例如:http_requests_total-接收到的HTTP請求的總數)。它可以包含ASCII字母和數字,以及下划線和冒號。它必須匹配正則表達式[a-zA-Z_:][a-zA-Z0-9_:]*。
標簽啟用Prometheus的維度數據模型:對於相同度量標准名稱,任何給定的標簽組合都標識該度量標准的特定維度實例。查詢語言允許基於這些維度進行篩選和聚合。更改任何標簽值(包括添加或刪除標簽)都會創建新的時間序列。標簽名稱可能包含ASCII字母,數字以及下划線。他們必須匹配正則表達式[a-zA-Z_][a-zA-Z0-9_]*。以__開始的標簽名稱保留給供內部使用。
  • 樣本
實際的時間序列,每個序列包括:一個 float64 的值和一個毫秒級的時間戳。
  • 格式
給定度量標准名稱和一組標簽,時間序列通常使用以下格式來標識:<metric name>{<label name>=<label value>, ...}
例如,時間序列的度量名稱為api_http_requests_total,標簽method=”POST”和handler=”/messages”,則標記為:
api_http_requests_total{method="POST", handler="/messages"}

2.2 度量類型

Prometheus 客戶端庫主要提供Counter、Gauge、Histogram和Summery四種主要的 metric 類型:
  • Counter(計算器)
Counter是一種累加的度量,它的值只能增加或在重新啟動時重置為零。例如,可以使用計數器來表示提供的請求數,已完成的任務或錯誤的數量。不要使用計數器來表達可減少的值。例如,不要使用Counter來計算當前正在運行的進程的數量,而是使用Gauge。
  • Gauge(測量)
Gauge表示單個數值,表達可以任意地上升和下降的度量。Gauge通常用於測量值,例如溫度或當前的內存使用情況,但也可以表達上升和下降的“計數”,如正在運行的goroutines的數量。
  • Histogram(直方圖)
Histogram樣本觀測(例如:請求持續時間或響應大小),並將它們計入配置的桶中。它也提供所有觀測值的總和。具有<basename>基本度量標准名稱的histogram的在獲取數據期間會顯示多個時間序列:
    • 觀察桶的累計計數器,暴露為 <basename>_bucket{le=”<upper inclusive bound>”}
    • 所有觀察值的總和,暴露為<basename>_sum
    • 已觀察到的事件的計數,暴露為<basename>_count(等同於<basename>_bucket{le=”+Inf”})
  • Summery:類似於Histogram,Summery樣本觀察(通常是請求持續時間和響應大小)。雖然它也提供觀測總數和所有觀測值的總和,但它計算滑動時間窗內的可配置分位數。在獲取數據期間,具有<basename>基本度量標准名稱的Summery會顯示多個時間序列:
    • 流動φ分位數(0≤φ≤1)的觀察事件,暴露為<basename>{quantile=”<φ>”}
    • 所有觀察值的總和,暴露為<basename>_sum
    • 已經觀察到的事件的計數,暴露為<basename>_count

2.3 工作和實例

在Prometheus中,可以獲取數據的端點被稱為實例(instance),通常對應於一個單一的進程。具有相同目的的實例集合(例如為了可伸縮性或可靠性而復制的進程)稱為作業(job)。

2.4 標簽和時間序列

當Prometheus獲取目標時,它會自動附加一些標簽到所獲取的時間序列中,以識別獲取目標:
  • job:目標所屬的配置作業名稱。
  • instance:<host>:<port>被抓取的目標網址部分。
如果這些標簽中的任何一個已經存在於抓取的數據中,則行為取決於honor_labels配置選項。對於每個實例抓取,Prometheus會在以下時間序列中存儲一個樣本:
  • up{job=”<job-name>”, instance=”<instance-id>”}:1 如果實例健康,即可達;或者0抓取失敗。
  • scrape_duration_seconds{job=”<job-name>”, instance=”<instance-id>”}:抓取的持續時間。
  • scrape_samples_post_metric_relabeling{job=”<job-name>”, instance=”<instance-id>”}:應用度量標准重新標記后剩余的樣本數。
  • scrape_samples_scraped{job=”<job-name>”, instance=”<instance-id>”}:目標暴露的樣本數量。
up時間序列是實例可用性的監控。

三 Prometheus部署

3.1 創建命名空間

[root@k8smaster01 study]# vi monitor-namespace.yaml
  1 apiVersion: v1
  2 kind: Namespace
  3 metadata:
  4   name: monitoring
  5 
[root@k8smaster01 study]# kubectl create -f monitor-namespace.yaml

3.2 獲取部署文件

[root@k8smaster01 study]# git clone https://github.com/prometheus/prometheus

3.3 創建RBAC

[root@k8smaster01 ~]# cd prometheus/documentation/examples/
[root@k8smaster01 examples]# vi rbac-setup.yml
  1 apiVersion: rbac.authorization.k8s.io/v1beta1
  2 kind: ClusterRole
  3 metadata:
  4   name: prometheus
  5 rules:
  6 - apiGroups: [""]
  7   resources:
  8   - nodes
  9   - nodes/proxy
 10   - services
 11   - endpoints
 12   - pods
 13   verbs: ["get", "list", "watch"]
 14 - apiGroups:
 15   - extensions
 16   resources:
 17   - ingresses
 18   verbs: ["get", "list", "watch"]
 19 - nonResourceURLs: ["/metrics"]
 20   verbs: ["get"]
 21 ---
 22 apiVersion: v1
 23 kind: ServiceAccount
 24 metadata:
 25   name: prometheus
 26   namespace: monitoring               #修改命名空間
 27 ---
 28 apiVersion: rbac.authorization.k8s.io/v1beta1
 29 kind: ClusterRoleBinding
 30 metadata:
 31   name: prometheus
 32 roleRef:
 33   apiGroup: rbac.authorization.k8s.io
 34   kind: ClusterRole
 35   name: prometheus
 36 subjects:
 37 - kind: ServiceAccount
 38   name: prometheus
 39   namespace: monitoring               #修改命名空間
 40 
[root@k8smaster01 examples]# kubectl create -f rbac-setup.yml

3.4 創建Prometheus ConfigMap

[root@k8smaster01 examples]# cat prometheus-kubernetes.yml | grep -v ^$ | grep -v "#" >> prometheus-config.yaml
[root@k8smaster01 examples]# vi prometheus-config.yaml
  1 apiVersion: v1
  2 kind: ConfigMap
  3 metadata:
  4   name: prometheus-server-conf
  5   labels:
  6     name: prometheus-server-conf
  7   namespace: monitoring               #修改命名空間
  8 data:
  9   prometheus.yml: |-
 10     global:
 11       scrape_interval: 10s
 12       evaluation_interval: 10s
 13 
 14     scrape_configs:
 15       - job_name: 'kubernetes-apiservers'
 16         kubernetes_sd_configs:
 17         - role: endpoints
 18         scheme: https
 19         tls_config:
 20           ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
 21         bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
 22         relabel_configs:
 23         - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
 24           action: keep
 25           regex: default;kubernetes;https
 26 
 27       - job_name: 'kubernetes-nodes'
 28         scheme: https
 29         tls_config:
 30           ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
 31         bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
 32         kubernetes_sd_configs:
 33         - role: node
 34         relabel_configs:
 35         - action: labelmap
 36           regex: __meta_kubernetes_node_label_(.+)
 37         - target_label: __address__
 38           replacement: kubernetes.default.svc:443
 39         - source_labels: [__meta_kubernetes_node_name]
 40           regex: (.+)
 41           target_label: __metrics_path__
 42           replacement: /api/v1/nodes/${1}/proxy/metrics
 43 
 44       - job_name: 'kubernetes-cadvisor'
 45         scheme: https
 46         tls_config:
 47           ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
 48         bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
 49         kubernetes_sd_configs:
 50         - role: node
 51         relabel_configs:
 52         - action: labelmap
 53           regex: __meta_kubernetes_node_label_(.+)
 54         - target_label: __address__
 55           replacement: kubernetes.default.svc:443
 56         - source_labels: [__meta_kubernetes_node_name]
 57           regex: (.+)
 58           target_label: __metrics_path__
 59           replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
 60 
 61       - job_name: 'kubernetes-service-endpoints'
 62         kubernetes_sd_configs:
 63         - role: endpoints
 64         relabel_configs:
 65         - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
 66           action: keep
 67           regex: true
 68         - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
 69           action: replace
 70           target_label: __scheme__
 71           regex: (https?)
 72         - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
 73           action: replace
 74           target_label: __metrics_path__
 75           regex: (.+)
 76         - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
 77           action: replace
 78           target_label: __address__
 79           regex: ([^:]+)(?::\d+)?;(\d+)
 80           replacement: $1:$2
 81         - action: labelmap
 82           regex: __meta_kubernetes_service_label_(.+)
 83         - source_labels: [__meta_kubernetes_namespace]
 84           action: replace
 85           target_label: kubernetes_namespace
 86         - source_labels: [__meta_kubernetes_service_name]
 87           action: replace
 88           target_label: kubernetes_name
 89 
 90       - job_name: 'kubernetes-services'
 91         metrics_path: /probe
 92         params:
 93           module: [http_2xx]
 94         kubernetes_sd_configs:
 95         - role: service
 96         relabel_configs:
 97         - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_probe]
 98           action: keep
 99           regex: true
100         - source_labels: [__address__]
101           target_label: __param_target
102         - target_label: __address__
103           replacement: blackbox-exporter.example.com:9115
104         - source_labels: [__param_target]
105           target_label: instance
106         - action: labelmap
107           regex: __meta_kubernetes_service_label_(.+)
108         - source_labels: [__meta_kubernetes_namespace]
109           target_label: kubernetes_namespace
110         - source_labels: [__meta_kubernetes_service_name]
111           target_label: kubernetes_name
112 
113       - job_name: 'kubernetes-ingresses'
114         kubernetes_sd_configs:
115         - role: ingress
116         relabel_configs:
117         - source_labels: [__meta_kubernetes_ingress_annotation_prometheus_io_probe]
118           action: keep
119           regex: true
120         - source_labels: [__meta_kubernetes_ingress_scheme,__address__,__meta_kubernetes_ingress_path]
121           regex: (.+);(.+);(.+)
122           replacement: ${1}://${2}${3}
123           target_label: __param_target
124         - target_label: __address__
125           replacement: blackbox-exporter.example.com:9115
126         - source_labels: [__param_target]
127           target_label: instance
128         - action: labelmap
129           regex: __meta_kubernetes_ingress_label_(.+)
130         - source_labels: [__meta_kubernetes_namespace]
131           target_label: kubernetes_namespace
132         - source_labels: [__meta_kubernetes_ingress_name]
133           target_label: kubernetes_name
134 
135       - job_name: 'kubernetes-pods'
136         kubernetes_sd_configs:
137         - role: pod
138         relabel_configs:
139         - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
140           action: keep
141           regex: true
142         - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
143           action: replace
144           target_label: __metrics_path__
145           regex: (.+)
146         - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
147           action: replace
148           regex: ([^:]+)(?::\d+)?;(\d+)
149           replacement: $1:$2
150           target_label: __address__
151         - action: labelmap
152           regex: __meta_kubernetes_pod_label_(.+)
153         - source_labels: [__meta_kubernetes_namespace]
154           action: replace
155           target_label: kubernetes_namespace
156         - source_labels: [__meta_kubernetes_pod_name]
157           action: replace
158           target_label: kubernetes_pod_name
159 
[root@k8smaster01 examples]# kubectl create -f prometheus-config.yaml

3.5 創建Prometheus Deployment

[root@k8smaster01 examples]# vi prometheus-deployment.yml
  1 apiVersion: apps/v1beta2
  2 kind: Deployment
  3 metadata:
  4   labels:
  5     name: prometheus-deployment
  6   name: prometheus-server
  7   namespace: monitoring
  8 spec:
  9   replicas: 1
 10   selector:
 11     matchLabels:
 12       app: prometheus-server
 13   template:
 14     metadata:
 15       labels:
 16         app: prometheus-server
 17     spec:
 18       containers:
 19         - name: prometheus-server
 20           image: prom/prometheus:v2.14.0
 21           command:
 22           - "/bin/prometheus"
 23           args:
 24             - "--config.file=/etc/prometheus/prometheus.yml"
 25             - "--storage.tsdb.path=/prometheus/"
 26             - "--storage.tsdb.retention=72h"
 27           ports:
 28             - containerPort: 9090
 29               protocol: TCP
 30           volumeMounts:
 31             - name: prometheus-config-volume
 32               mountPath: /etc/prometheus/
 33             - name: prometheus-storage-volume
 34               mountPath: /prometheus/
 35       serviceAccountName: prometheus
 36       imagePullSecrets:
 37         - name: regsecret
 38       volumes:
 39         - name: prometheus-config-volume
 40           configMap:
 41             defaultMode: 420
 42             name: prometheus-server-conf
 43         - name: prometheus-storage-volume
 44           emptyDir: {}
 45 
[root@k8smaster01 examples]# kubectl create -f prometheus-deployment.yml
提示:若需要持久存儲Prometheus,可提前創建相應sc和pvc,sc《044.集群存儲-StorageClass》,PVC可參考如下:
[root@k8smaster01 examples]# vi prometheus-pvc.yaml
  1 apiVersion: v1
  2 kind: PersistentVolumeClaim
  3 metadata:
  4   name: prometheus-pvc
  5   namespace: monitoring
  6   annotations:
  7     volume.beta.kubernetes.io/storage-class: ghstorageclass
  8 spec:
  9   accessModes:
 10   - ReadWriteMany
 11   resources:
 12     requests:
 13       storage: 5Gi
[root@k8smaster01 examples]# kubectl create -f prometheus-pvc.yaml
將prometheus-deployment.yml存儲部分修改為:
  1 ……
  2         - name: prometheus-storage-volume
  3           persistentVolumeClaim:
  4             claimName: prometheus-pvc
  5 ……
  6 

3.6 創建Prometheus Service

[root@k8smaster01 examples]# vi prometheus-service.yaml
apiVersion: v1 kind: Service metadata: labels: app: prometheus-service name: prometheus-service namespace: monitoring spec: type: NodePort selector: app: prometheus-server ports: - port: 9090 targetPort: 9090 nodePort: 30909
[root@k8smaster01 examples]# kubectl create -f prometheus-service.yaml
[root@k8smaster01 examples]# kubectl get all -n monitoring
NAME READY STATUS RESTARTS AGE
pod/prometheus-server-fd5479489-q584s 1/1 Running 0 92s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/prometheus-service NodePort 10.107.69.147 <none> 9090:30909/TCP 29s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/prometheus-server 1/1 1 1 92s
NAME DESIRED CURRENT READY AGE
replicaset.apps/prometheus-server-fd5479489 1 1 1 92s

3.7 測試Prometheus

瀏覽器直接訪問:http://172.24.8.71:30909/
clipboard
查看所有Kubernetes集群上的Endpoint通過服務發現的方式自動連接到了Prometheus。
clipboard
通過圖形化界面查看內存。
clipboard
Prometheus更多配置參考官網:https://prometheus.io/docs/prometheus/latest/configuration/configuration/

四 部署Grafana

4.1 獲取部署文件

[root@uhost ~]# git clone https://github.com/liukuan73/kubernetes-addons

4.2 部署grafana

[root@uhost ~]# cd /root/kubernetes-addons/monitor/prometheus+grafana
[root@k8smaster01 prometheus+grafana]# vi grafana.yaml
  1 ---
  2 apiVersion: v1
  3 kind: Service
  4 metadata:
  5   name: grafana
  6   namespace: monitoring
  7   labels:
  8     app: grafana
  9 spec:
 10   type: NodePort
 11   ports:
 12   - port: 3000
 13     targetPort: 3000
 14     nodePort: 30007
 15   selector:
 16     app: grafana
 17 ---
 18 apiVersion: extensions/v1beta1
 19 kind: Deployment
 20 metadata:
 21   labels:
 22     app: grafana
 23   name: grafana
 24   namespace: monitoring
 25 spec:
 26   replicas: 1
 27   revisionHistoryLimit: 2
 28   template:
 29     metadata:
 30       labels:
 31         app: grafana
 32     spec:
 33       containers:
 34       - name: gragana
 35         image: grafana/grafana:5.0.0
 36         imagePullPolicy: IfNotPresent
 37         ports:
 38         - containerPort: 3000
 39         volumeMounts:
 40         - mountPath: /var
 41           name: grafana-storage
 42         env:
 43           - name: GF_AUTH_BASIC_ENABLED
 44             value: "false"
 45           - name: GF_AUTH_ANONYMOUS_ENABLED
 46             value: "true"
 47           - name: GF_AUTH_ANONYMOUS_ORG_ROLE
 48             value: Admin
 49           - name: GF_SERVER_ROOT_URL
 50 #              value: /api/v1/proxy/namespaces/default/services/grafana/
 51             value: /
 52         readinessProbe:
 53           httpGet:
 54             path: /login
 55             port: 3000
 56       volumes:
 57       - name: grafana-storage
 58         emptyDir: {}
 59       nodeSelector:
 60         node-role.kubernetes.io/master: "true"
 61 #      tolerations:
 62 #      - key: "node-role.kubernetes.io/master"
 63 #        effect: "NoSchedule"
 64 
[root@k8smaster01 prometheus+grafana]# kubectl label nodes k8smaster01 node-role.kubernetes.io/master=true
[root@k8smaster01 prometheus+grafana]# kubectl label nodes k8smaster02 node-role.kubernetes.io/master=true
[root@k8smaster01 prometheus+grafana]# kubectl label nodes k8smaster03 node-role.kubernetes.io/master=true
[root@k8smaster01 prometheus+grafana]# kubectl taint node --all node-role.kubernetes.io- #允許Master部署應用
[root@k8smaster01 prometheus+grafana]# kubectl create -f grafana.yaml
[root@k8smaster01 examples]# kubectl get all -n monitoring
clipboard

4.3 確認驗證

瀏覽器訪問:http://172.24.8.71:30007,使用默認用戶名admin/admin登錄。
clipboard

4.4 配置數據源

Configuration ----> Data Sources。
clipboard
添加新數據源。
clipboard
如下添加Prometheus數據源,本環境基於《附012.Kubeadm部署高可用Kubernetes》部署的高可用Kubernetes,存在vip:172.24.8.100,也可使用3.7步驟所測試的Prometheus地址。
clipboard
保存並測試是否成功。
clipboard

4.5 配置Grafana

配置dashboard,本實驗使用162號模板,此Dashboard 模板來展示 Kubernetes 集群的監控信息。
clipboard
選擇4.4所添加的Prometheus數據源,用於展示。
clipboard

4.6 添加用戶

可添加普通用戶,並配置相應角色。
clipboard
復制登錄鏈接:http://172.24.8.71:30007/invite/hlhkzz5O3dJj94OlHcKiqN8bPrZt40
clipboard
進入鏈接,設置新用戶密碼並登錄:
clipboard

4.7 其他設置

建議對時區進行設置,其他Grafana更多配置參考:https://grafana.com/docs/grafana/latest/installation/configuration/
clipboard

4.8 查看監控

登錄http://172.24.8.71:30007/,即可查看相應Kubernetes監控了。
clipboard
本方案參考鏈接:
https://www.kubernetes.org.cn/4184.html
https://www.kubernetes.org.cn/3418.html
https://www.jianshu.com/p/c2e549480c50


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM