一文讀懂如何在 Kubernetes 上輕鬆實現自動化部署 Prometheus

2019-09-06 08:20:33



簡介

Prometheus 是當下火熱的監控解決方案,尤其是容器微服務架構,Kubernetes 的首選監控方案。關於為什麼要用 Prometheus,我這裡就不多講,相關的文章太多了,大家也可以看看官方的說法。本文就講講如何自動化的搭建一套基於 Kubernetes 叢集的 Prometheus 監控系統。

我這裡使用 Prometheus Operator 以及 helm 工具在 Kubernetes 叢集上部署,後面給大家提供一個全自動運維 (http://t.cn/Ai8t4jLw) 的例子參考,這裡直接看程式碼。

關於 helm 的使用不清楚的可以參考這幾篇文章:

  • Helm 入門指南

  • 利用 Helm 快速部署 Ingress

  • Kubernetes 實操手冊-Helm使用 (http://t.cn/Ai85DU9N)

關於什麼是 Prometheus Operator 以及為什麼要用 Prometheus Operator

Operator 是以軟體的方式定義運維過程,是一系列打包、部署和管理 Kubernetes 應用的方法。簡單來說就是將運維過程中的手動操作轉換為自動化流程,通過 Kubernetes 的 CRD(Custom Resource Definition)將部署前後的相關操作自動化,同時以引數的方式提供了靈活性。而 Prometheus Operator 是 CoreOS 提供的一整套 Prometheus 的 Operator,方便了 Prometheus 的部署。


下面我們先簡單講講 Prometheus 的架構。

Prometheus 核心

下圖是 Promtheus 官方的架構圖

Prometheus Server

Prometheus Server 是監控系統的服務端,服務端通過服務發現的方式,抓取被監控服務的指標,或者通過 pushgateway 的間接抓取,抓取到指標資料後,通過特定的儲存引擎進行儲存,同時暴露一個 HTTP 服務,提供用 PromQL 來進行資料查詢。注意,Prometheus 是定時取樣資料,而不是全量資料。

Exporter

Prometheus 需要服務暴露 http 介面,如果服務本身沒有,我們不需要改造服務,可以通過 exporter 來間接獲取。Exporter 就充當了 Prometheus 採集的目標,而由各個 exporter 去直接獲取指標。目前大多數的服務都有現成的 exporter,我們不需要重複造輪子,拿來用即可,如 MySQL,MongoDB 等,可以參考這裡。

Push Gateway

Prometheus 採集指標的方式主要有兩種,一種是服務端暴露介面(Exporter),由 Prometheus 主動去抓取指標,稱為 pull 模式。另一種是服務端主動上報,服務端將指標主動上報至 Push Gateway,Prometheus 再從 Push Gateway 中獲取,稱為 push 模式。而 Push Gateway 就是 push 模式中重要的中介角色,用於暫存服務端上報的指標,等待 Prometheus 收集。

為什麼要有兩種模式呢?我們來比較一下這兩種模式的特點。

Pull 模式:Prometheus 主動抓取的方式,可以由 Prometheus 服務端控制抓取的頻率,簡單清晰,控制權在 Prometheus 服務端。通過服務發現機制,可以自動接入新服務,去掉下線的服務,無需任何人工干預。對於各種常見的服務,官方或社群有大量 Exporter 來提供指標採集介面,基本無需開發。是官方推薦的方式。

Push 模式:由服務端主動上報至 Push Gateway,採集最小粒度由服務端決定,等於 Push Gateway 充當了中介的角色,收集各個服務主動上報的指標,然後再由 Prometheus 來採集。但是這樣就存在了 Push Gateway 這個效能單點,而且 Push Gateway 也要處理持久化問題,不然宕機也會丟失部分資料。同時需要服務端提供主動上報的功能,可能涉及一些開發改動。不是首選的方式,但是在一些場景下很適用。例如,一些臨時性的任務,存在時間可能非常短,如果採用 Pull 模式,可能抓取不到資料。

Alert Manager

Alert Manager 是 Prometheus 的報警元件,當 Prometheus 服務端發現報警時,推送 alert 到 Alert Manager,再由 Alert Manager 傳送到通知端,如 Email,Slack,微信,釘釘等。Alert Manager 根據相關規則提供了報警的分組、聚合、抑制、沉默等功能。

Web UI/Grafana

Prometheus 提供了一個簡單的 web UI 介面,用於查詢資料,檢視告警、配置等,官方推薦使用另一個開源專案 grafana 來做指標的視覺化展示,製作儀表盤等。

部署

下面詳細講講如何自動化部署 Promethues,自動化監控以及遇到的一些坑。

部署這塊 Prometheus Operator 已經幫我們做的非常好了,我們只需要調整一些引數即可實現部署。我們使用 helm 來部署 Prometheus,只需要一個命令。

helm install --name my-release stable/prometheus-operator

不過這不可能滿足我們的需求,我們需要的不是演示,而是實戰。

下面是詳細講解,完整的專案可以參考這裡:http://t.cn/Ai8tzUaR 。

我們首先要確定的是如何持久化儲存 Prometheus 的指標資料,預設的方式是以檔案的方式儲存在服務端的磁碟上,但這樣不利於服務端的橫向擴充套件以及資料的備份恢復。Prometheus 還提供了其他儲存後端的整合,詳見這裡。目前比較流行的做法是使用 InfluxDB 作為儲存後端,InfluxDB 是一款強大的時序資料庫,就是為監控指標等時序資料而生的。

首先,我們來部署 InfluxDB,為了持久化 InfluxDB 的資料,我們先建立一個 PVC 來持久化資料。

pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: influxdb-pvc
namespace: monitoring
labels:
app: influxdb
release: influxdb
spec:
accessModes:
- ReadWriteOnce
storageClassName: monitor-ebs # 選擇合適的儲存類
resources:
requests:
storage: 200Gi # 設定合適的儲存空間

然後我們建立 InfluxDB 的配置檔案

influxdb.yaml

# 持久化儲存配置
persistence:
enabled: true
useExisting: true
name: "influxdb-pvc" # 使用我們剛才建立的 PVC
accessMode: "ReadWriteOnce"
size: 200Gi

# 建立 Prometheus 的資料庫
env:
- name: INFLUXDB_DB
value: "prometheus"

# influxdb 配置
config:
data:
# 這兩個配置預設限制了資料的上限,建議設定為 0 變成無限制,不然在達到上限後插入資料會返回錯誤
max_series_per_database: 0
max_values_per_tag: 0
http:
enabled: true # 啟動 http
initScripts:
enabled: true
scripts:
# 設定資料保留策略,預設是永不失效,需要人工清理
# 保留 180 天資料
retention.iql: |+
CREATE RETENTION POLICY "default_retention_policy" on "prometheus" DURATION 180d REPLICATION 1 DEFAULT

InfluxDB 的全部配置可以參考文件,我講一下上面的兩個主要的配置。

max-series-per-database

記憶體中每個資料庫最大的序列數量,預設是 1000000,設定為 0 改成無限制。如果新來的資料增加了序列數量並超過了這個上限,那麼資料就會被丟棄就並返回一個 500 錯誤:

{"error":"max series per database exceeded: "}

max-values-per-tag

記憶體中每個標籤的最大資料量,預設是 100000,設定為 0 改成無限制。如果新來的資料超過了這個限制,也會被丟棄並返回寫入失敗的錯誤。

我們使用如下命令來部署 InfluxDB:

helm install --name=influxdb --namespace=monitoring -f influxdb.yaml stable/influxdb

儲存後端部署成功後,我們就來部署 Prometheus-operator 了,首先建立如下的配置檔案

prometheus.yaml

# prometheus 服務端
prometheus:
prometheusSpec:
# 遠端儲存配置
remoteWrite:
- url: "http://influxdb:8086/api/v1/prom/write?db=prometheus"
remoteRead:
- url: "http://influxdb:8086/api/v1/prom/read?db=prometheus"

# ingress 配置,暴露 web 介面
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: traefik # ingress class
hosts:
- "prometheus.mydomain.io" # 配置域名

alertmanager:
# alertmanager 配置
config:
global:
# SMTP 配置
smtp_smarthost: 'xxx'
smtp_from: 'xxx'
smtp_auth_username: 'xxx'
smtp_auth_password: 'xxx'
# 全域性 opsgenie 配置
# opsgenie_api_key: ""
# 報警路由
route:
receiver: 'monitoring-warning'
group_by: ['alertname']
group_wait: 30s
group_interval: 3m
repeat_interval: 8h
routes:
- match:
severity: critical
receiver: monitoring-critical
group_by: ['alertname']
- match:
severity: warning
receiver: monitoring-warning
group_by: ['alertname']
# 報警抑制規則
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
# 抑制相同的報警
equal: ['alertname']
# 接收者配置
receivers:
- name: 'monitoring-critical'
email_configs:
- to: 'monitor@mydomain.com'
# 傳送到釘釘的 webhook,需要部署一個轉發服務,詳見專案程式碼
webhook_configs:
- send_resolved: true
url: http://prometheus-webhook-dingtalk/dingtalk/monitoring/send
- name: 'monitoring-warning'
email_configs:
- to: 'monitor@mydomain.com'
alertmanagerSpec:
# alertmanager 儲存配置,alertmanager 會以檔案形式儲存報警靜默等配置
storage:
volumeClaimTemplate:
spec:
accessModes:
- ReadWriteOnce
storageClassName: monitor-ebs # 選擇合適的儲存類
resources:
requests:
storage: 20Gi # 選擇合適的大小
# ingress 配置,暴露 alert 的介面
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: traefik # ingress class
hosts:
- "alert.mydomain.io" # 配置域名

# grafana 配置
grafana:
replicas: 1
adminPassword: "admin" # 管理員賬戶 admin,密碼 admin
env:
# GF_SERVER_DOMAIN: "" # 域名
GF_SERVER_ROOT_URL: "%(protocol)s://%(domain)s/"
# GF_DATABASE_URL: "mysql://user:secret@host:port/database" # SQL 資料庫
# ingress 配置,暴露介面
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: traefik # ingress class
hosts:
- "grafana.mydomain.io" # 設定域名

# exporter 設定,自建叢集需要開啟,如果是雲服務商託管叢集,則獲取不到這些資訊,可以關閉
kubeControllerManager:
enabled: true
kubeEtcd:
enabled: true
kubeScheduler:
enabled: true

然後我們使用如下命令來部署 Prometheus-Operator

helm install --name=prometheus --namespace=monitoring -f prometheus.yam stable/prometheus-operator

如果需要 Prometheus-Pushgateway 的話,建立如下配置

prometheus-pushgateway.yaml

replicaCount: 1
# 自動在 Prometheus 中新增 target
serviceMonitor:
enabled: true
namespace: monitoring
selector:
app: prometheus-pushgateway
release: prometheus
# ingress 配置,暴露介面
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: traefik # ingress class
hosts:
- "pushgateway.mydomain.io" # 設定域名

同樣的方式部署

helm install --name=prometheus-pushgateway --namespace=monitoring -f prometheus-pushgateway.yaml stable/prometheus-pushgateway

這樣 Prometheus 的核心元件都部署完成了,檢視叢集中的 Pod,有類似如下圖所示的 Pod

這裡有個注意點,如果通過 Prometheus 收集 kube-proxy 的指標,需要 kube-proxy 開通訪問,預設 kube-proxy 只允許本機訪問。

需要修改 kube-proxy 的 ConfigMap 中的 metricsBindAddress 值為 0.0.0.0:10249

kubectl -n kube-system edit cm kube-proxy

會看到如下內容,將 metricsBindAddress: 127.0.0.1:10249 這行修改為 metricsBindAddress: 0.0.0.0:10249 儲存即可。

apiVersion: v1
data:
config.conf: |-
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
# ...
# metricsBindAddress: 127.0.0.1:10249
metricsBindAddress: 0.0.0.0:10249
# ...
kubeconfig.conf: |-
# ...
kind: ConfigMap
metadata:
labels:
app: kube-proxy
name: kube-proxy
namespace: kube-system

然後刪除 kube-proxy 的 Pod,讓它重啟即可看到已正常抓取。

應用

至此,Prometheus 的服務端就全部部署完成了。接下來就是根據實際業務部署相應的 Exporter,ServiceMonitor 和 PrometheusRule 了。官方和社群有大量現成的 Exporters 可供使用,如果有特殊需求的也可以參考這裡自行開發。

接下來我們講講如何快速整合 Prometheus 監控和報警。

我們之前提到過 Operator 通過 CRD 的方式提供了很多部署方面的自動化,Prometheus-Operator 就提供了四個 CRD,分別是

  • Prometheus,定義了 Prometheus 服務端,用來生成服務端控制器,保證了服務端的正常執行,我們只需要一個此 CRD 的例項

  • Alertmanager,定義了 AlertManager 服務,用來生成服務端控制器,保證了服務的正常執行,我們也只需要一個此 CRD 的例項

  • ServiceMonitor,定義了 Prometheus 抓取指標的目標,就是 Prometheus 介面 targets 頁面看到的內容,此 CRD 幫助我們建立目標的配置

  • PrometheusRule,定義了 Prometheus 規則,就是 Prometheus 介面 Rules 頁面看到的內容,此 CRD 幫助我們建立規則的配置

Prometheus 和 Alertmanager CRD 主要是之前部署階段關注的,在服務應用階段,我們主要是建立各個 ServiceMonitor 和 PrometheusRule 來配置服務端。

Prometheus-Operator 預設會幫我們註冊相關元件的抓取目標,如下圖所示

我們要定義其他的抓取目標,首先來建立了一個 ServiceMonitor 抓取我們部署的 InfluxDB 的指標

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: influxdb-scrape-targets
labels:
app.kubernetes.io/name: scrape-targets
app.kubernetes.io/instance: influxdb-target
release: prometheus
spec:
# 用標籤選擇器來選擇相應的 Pod
selector:
matchLabels:
app: influxdb
release: influxdb

# 選擇名稱空間
namespaceSelector:
matchNames:
- monitoring

# 定義抓取的配置,如埠、頻率等
endpoints:
- interval: 15s
port: api

我們在專案中建立了一個 Chart 模版(在 charts/scrape-targets/ 目錄),能夠快速的建立 ServiceMonitor,提供下面的配置檔案

influxdb.yaml

selector:
matchLabels:
app: influxdb
release: influxdb
namespaceSelector:
matchNames:
- monitoring
endpoints:
- port: api
interval: 15s

然後使用 helm 安裝

helm install --name influxdb-target --namespace monitoring -f influxdb.yaml charts/scrape-targets/

建立完成後無需重啟 Prometheus 服務端,服務端根據標籤自動載入,過一會可以在介面上看到

Prometheus-Operator 同樣會幫我們註冊許多相關的規則,如下圖所示

配置我們自己的 PrometheusRule 同樣很簡單,我們用如下配置生成報警規則,如果 5 分鐘內的 HTTP 500 錯誤大於 5 則報警

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: request-rules
labels:
app.kubernetes.io/name: rules
app.kubernetes.io/instance: request
app: prometheus-operator
release: prometheus
spec:
groups:
- name: request-rules.rules
rules:
- alert: RequestStatusCode500
annotations:
summary: http status code 500 is high for `{{$labels.service}}`
expr: http_request_total{statuscode="500"} > 5
for: 5m
labels:
severity: critical

也可以用我們專案中的 Chart 模版(在 charts/rules/ 目錄)來快速配置

request.yaml

groups:
- rules:
- alert: RequestStatusCode500
expr: http_request_total{statuscode="500"} > 5
for: "5m"
labels:
severity: critical
annotations:
summary: http status code 500 is high for `{{$labels.service}}`

然後 helm 安裝

helm install --name request --namespace monitoring -f request.yaml charts/rules/

關於怎麼寫規則配置,可以參考官方的文件和 PromQL 語法。

以上的操作還是手動化的,如果要全自動化的話,可以參考我的專案,定義好配置檔案,寫好自動化指令碼,接入 CI/CD 工作流,即可讓監控系統實現自動部署、自動配置。

參考

  • Prometheus 官網

  • Prometheus 與其他監控系統對比

  • Kubernetes Operator

  • Prometheus Operator

  • Prometheus-Pushgateway Operator

  • Prometheus Remote Storage

  • InfluxDB

  • Kubernetes 實操手冊-Helm使用

  • Prometheus Exporters

  • Writing Exporters

  • Prometheus-Operator API Docs

  • Prometheus 自動部署

來源:知乎

原文:http://t.cn/Ai8tV2yE

題圖:來自谷歌圖片搜尋

版權:本文版權歸原作者所有

投稿:歡迎投稿,郵箱: editor@hi-linux.com


你可能還喜歡

點選下方圖片即可閱讀

Helm 入門指南


已同步到看一看
在看



熱點新聞