新聞中心
簡(jiǎn)介

成都創(chuàng)新互聯(lián)堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都網(wǎng)站建設(shè)、網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的瀘溪網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
Prometheus 是當(dāng)下火熱的監(jiān)控解決方案,尤其是容器微服務(wù)架構(gòu),Kubernetes 的首選監(jiān)控方案。關(guān)于為什么要用 Prometheus,我這里就不多講,相關(guān)的文章太多了,大家也可以看看官方的說(shuō)法。本文就講講如何自動(dòng)化的搭建一套基于 Kubernetes 集群的 Prometheus 監(jiān)控系統(tǒng)。
我這里使用 Prometheus Operator 以及 helm 工具在 Kubernetes 集群上部署,后面給大家提供一個(gè)全自動(dòng)運(yùn)維 (http://t.cn/Ai8t4jLw) 的例子參考,這里直接看代碼。
關(guān)于 helm 的使用不清楚的可以參考這幾篇文章:
- Helm 入門(mén)指南
- 利用 Helm 快速部署 Ingress
- Kubernetes 實(shí)操手冊(cè)-Helm使用 (http://t.cn/Ai85DU9N)
關(guān)于什么是 Prometheus Operator 以及為什么要用 Prometheus Operator?
Operator 是以軟件的方式定義運(yùn)維過(guò)程,是一系列打包、部署和管理 Kubernetes 應(yīng)用的方法。簡(jiǎn)單來(lái)說(shuō)就是將運(yùn)維過(guò)程中的手動(dòng)操作轉(zhuǎn)換為自動(dòng)化流程,通過(guò) Kubernetes 的 CRD(Custom Resource Definition)將部署前后的相關(guān)操作自動(dòng)化,同時(shí)以參數(shù)的方式提供了靈活性。而 Prometheus Operator 是 CoreOS 提供的一整套 Prometheus 的 Operator,方便了 Prometheus 的部署。
下面我們先簡(jiǎn)單講講 Prometheus 的架構(gòu)。
Prometheus 核心
下圖是 Promtheus 官方的架構(gòu)圖
Prometheus Server
Prometheus Server 是監(jiān)控系統(tǒng)的服務(wù)端,服務(wù)端通過(guò)服務(wù)發(fā)現(xiàn)的方式,抓取被監(jiān)控服務(wù)的指標(biāo),或者通過(guò) pushgateway 的間接抓取,抓取到指標(biāo)數(shù)據(jù)后,通過(guò)特定的存儲(chǔ)引擎進(jìn)行存儲(chǔ),同時(shí)暴露一個(gè) HTTP 服務(wù),提供用 PromQL 來(lái)進(jìn)行數(shù)據(jù)查詢。注意,Prometheus 是定時(shí)采樣數(shù)據(jù),而不是全量數(shù)據(jù)。
Exporter
Prometheus 需要服務(wù)暴露 http 接口,如果服務(wù)本身沒(méi)有,我們不需要改造服務(wù),可以通過(guò) exporter 來(lái)間接獲取。Exporter 就充當(dāng)了 Prometheus 采集的目標(biāo),而由各個(gè) exporter 去直接獲取指標(biāo)。目前大多數(shù)的服務(wù)都有現(xiàn)成的 exporter,我們不需要重復(fù)造輪子,拿來(lái)用即可,如 MySQL,MongoDB 等,可以參考這里。
Push Gateway
Prometheus 采集指標(biāo)的方式主要有兩種,一種是服務(wù)端暴露接口(Exporter),由 Prometheus 主動(dòng)去抓取指標(biāo),稱(chēng)為 pull 模式。另一種是服務(wù)端主動(dòng)上報(bào),服務(wù)端將指標(biāo)主動(dòng)上報(bào)至 Push Gateway,Prometheus 再?gòu)?Push Gateway 中獲取,稱(chēng)為 push 模式。而 Push Gateway 就是 push 模式中重要的中介角色,用于暫存服務(wù)端上報(bào)的指標(biāo),等待 Prometheus 收集。
為什么要有兩種模式呢?我們來(lái)比較一下這兩種模式的特點(diǎn)。
Pull 模式:Prometheus 主動(dòng)抓取的方式,可以由 Prometheus 服務(wù)端控制抓取的頻率,簡(jiǎn)單清晰,控制權(quán)在 Prometheus 服務(wù)端。通過(guò)服務(wù)發(fā)現(xiàn)機(jī)制,可以自動(dòng)接入新服務(wù),去掉下線的服務(wù),無(wú)需任何人工干預(yù)。對(duì)于各種常見(jiàn)的服務(wù),官方或社區(qū)有大量 Exporter 來(lái)提供指標(biāo)采集接口,基本無(wú)需開(kāi)發(fā)。是官方推薦的方式。
Push 模式:由服務(wù)端主動(dòng)上報(bào)至 Push Gateway,采集最小粒度由服務(wù)端決定,等于 Push Gateway 充當(dāng)了中介的角色,收集各個(gè)服務(wù)主動(dòng)上報(bào)的指標(biāo),然后再由 Prometheus 來(lái)采集。但是這樣就存在了 Push Gateway 這個(gè)性能單點(diǎn),而且 Push Gateway 也要處理持久化問(wèn)題,不然宕機(jī)也會(huì)丟失部分?jǐn)?shù)據(jù)。同時(shí)需要服務(wù)端提供主動(dòng)上報(bào)的功能,可能涉及一些開(kāi)發(fā)改動(dòng)。不是首選的方式,但是在一些場(chǎng)景下很適用。例如,一些臨時(shí)性的任務(wù),存在時(shí)間可能非常短,如果采用 Pull 模式,可能抓取不到數(shù)據(jù)。
Alert Manager
Alert Manager 是 Prometheus 的報(bào)警組件,當(dāng) Prometheus 服務(wù)端發(fā)現(xiàn)報(bào)警時(shí),推送 alert 到 Alert Manager,再由 Alert Manager 發(fā)送到通知端,如 Email,Slack,微信,釘釘?shù)?。Alert Manager 根據(jù)相關(guān)規(guī)則提供了報(bào)警的分組、聚合、抑制、沉默等功能。
Web UI/Grafana
Prometheus 提供了一個(gè)簡(jiǎn)單的 web UI 界面,用于查詢數(shù)據(jù),查看告警、配置等,官方推薦使用另一個(gè)開(kāi)源項(xiàng)目 grafana 來(lái)做指標(biāo)的可視化展示,制作儀表盤(pán)等。
部署
下面詳細(xì)講講如何自動(dòng)化部署 Promethues,自動(dòng)化監(jiān)控以及遇到的一些坑。
部署這塊 Prometheus Operator 已經(jīng)幫我們做的非常好了,我們只需要調(diào)整一些參數(shù)即可實(shí)現(xiàn)部署。我們使用 helm 來(lái)部署 Prometheus,只需要一個(gè)命令。
- helm install --name my-release stable/prometheus-operator
不過(guò)這不可能滿足我們的需求,我們需要的不是演示,而是實(shí)戰(zhàn)。
下面是詳細(xì)講解,完整的項(xiàng)目可以參考這里:http://t.cn/Ai8tzUaR 。
我們首先要確定的是如何持久化存儲(chǔ) Prometheus 的指標(biāo)數(shù)據(jù),默認(rèn)的方式是以文件的方式保存在服務(wù)端的磁盤(pán)上,但這樣不利于服務(wù)端的橫向擴(kuò)展以及數(shù)據(jù)的備份恢復(fù)。Prometheus 還提供了其他存儲(chǔ)后端的整合,詳見(jiàn)這里。目前比較流行的做法是使用 InfluxDB 作為存儲(chǔ)后端,InfluxDB 是一款強(qiáng)大的時(shí)序數(shù)據(jù)庫(kù),就是為監(jiān)控指標(biāo)等時(shí)序數(shù)據(jù)而生的。
首先,我們來(lái)部署 InfluxDB,為了持久化 InfluxDB 的數(shù)據(jù),我們先創(chuàng)建一個(gè) PVC 來(lái)持久化數(shù)據(jù)。
pvc.yaml
- apiVersion: v1
- kind: PersistentVolumeClaim
- metadata:
- name: influxdb-pvc
- namespace: monitoring
- labels:
- app: influxdb
- release: influxdb
- spec:
- accessModes:
- - ReadWriteOnce
- storageClassName: monitor-ebs # 選擇合適的存儲(chǔ)類(lèi)
- resources:
- requests:
- storage: 200Gi # 設(shè)置合適的存儲(chǔ)空間
然后我們創(chuàng)建 InfluxDB 的配置文件
influxdb.yaml
- # 持久化存儲(chǔ)配置
- persistence:
- enabled: true
- useExisting: true
- name: "influxdb-pvc" # 使用我們剛才創(chuàng)建的 PVC
- accessMode: "ReadWriteOnce"
- size: 200Gi
- # 創(chuàng)建 Prometheus 的數(shù)據(jù)庫(kù)
- env:
- - name: INFLUXDB_DB
- value: "prometheus"
- # influxdb 配置
- config:
- data:
- # 這兩個(gè)配置默認(rèn)限制了數(shù)據(jù)的上限,建議設(shè)置為 0 變成無(wú)限制,不然在達(dá)到上限后插入數(shù)據(jù)會(huì)返回錯(cuò)誤
- max_series_per_database: 0
- max_values_per_tag: 0
- http:
- enabled: true # 啟動(dòng) http
- initScripts:
- enabled: true
- scripts:
- # 設(shè)置數(shù)據(jù)保留策略,默認(rèn)是永不失效,需要人工清理
- # 保留 180 天數(shù)據(jù)
- retention.iql: |+
- CREATE RETENTION POLICY "default_retention_policy" on "prometheus" DURATION 180d REPLICATION 1 DEFAULT
InfluxDB 的全部配置可以參考文檔,我講一下上面的兩個(gè)主要的配置。
max-series-per-database
內(nèi)存中每個(gè)數(shù)據(jù)庫(kù)最大的序列數(shù)量,默認(rèn)是 1000000,設(shè)置為 0 改成無(wú)限制。如果新來(lái)的數(shù)據(jù)增加了序列數(shù)量并超過(guò)了這個(gè)上限,那么數(shù)據(jù)就會(huì)被丟棄就并返回一個(gè) 500 錯(cuò)誤:
- {"error":"max series per database exceeded:
"}
max-values-per-tag
內(nèi)存中每個(gè)標(biāo)簽的最大數(shù)據(jù)量,默認(rèn)是 100000,設(shè)置為 0 改成無(wú)限制。如果新來(lái)的數(shù)據(jù)超過(guò)了這個(gè)限制,也會(huì)被丟棄并返回寫(xiě)入失敗的錯(cuò)誤。
我們使用如下命令來(lái)部署 InfluxDB:
- helm install --name=influxdb --namespace=monitoring -f influxdb.yaml stable/influxdb
存儲(chǔ)后端部署成功后,我們就來(lái)部署 Prometheus-operator 了,首先創(chuàng)建如下的配置文件:
prometheus.yaml
- # prometheus 服務(wù)端
- prometheus:
- prometheusSpec:
- # 遠(yuǎn)端存儲(chǔ)配置
- 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: ""
- # 報(bào)警路由
- 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']
- # 報(bào)警抑制規(guī)則
- inhibit_rules:
- - source_match:
- severity: 'critical'
- target_match:
- severity: 'warning'
- # 抑制相同的報(bào)警
- equal: ['alertname']
- # 接收者配置
- receivers:
- - name: 'monitoring-critical'
- email_configs:
- - to: 'monitor@mydomain.com'
- # 發(fā)送到釘釘?shù)?nbsp;webhook,需要部署一個(gè)轉(zhuǎn)發(fā)服務(wù),詳見(jiàn)項(xiàng)目代碼
- webhook_configs:
- - send_resolved: true
- url: http://prometheus-webhook-dingtalk/dingtalk/monitoring/send
- - name: 'monitoring-warning'
- email_configs:
- - to: 'monitor@mydomain.com'
- alertmanagerSpec:
- # alertmanager 存儲(chǔ)配置,alertmanager 會(huì)以文件形式存儲(chǔ)報(bào)警靜默等配置
- storage:
- volumeClaimTemplate:
- spec:
- accessModes:
- - ReadWriteOnce
- storageClassName: monitor-ebs # 選擇合適的存儲(chǔ)類(lèi)
- 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 數(shù)據(jù)庫(kù)
- # ingress 配置,暴露界面
- ingress:
- enabled: true
- annotations:
- kubernetes.io/ingress.class: traefik # ingress class
- hosts:
- - "grafana.mydomain.io" # 設(shè)置域名
- # exporter 設(shè)置,自建集群需要開(kāi)啟,如果是云服務(wù)商托管集群,則獲取不到這些信息,可以關(guān)閉
- kubeControllerManager:
- enabled: true
- kubeEtcd:
- enabled: true
- kubeScheduler:
- enabled: true
然后我們使用如下命令來(lái)部署 Prometheus-Operator。
- helm install --name=prometheus --namespace=monitoring -f prometheus.yam stable/prometheus-operator
如果需要 Prometheus-Pushgateway 的話,創(chuàng)建如下配置:
prometheus-pushgateway.yaml
- replicaCount: 1
- # 自動(dòng)在 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" # 設(shè)置域名
同樣的方式部署:
- helm install --name=prometheus-pushgateway --namespace=monitoring -f prometheus-pushgateway.yaml stable/prometheus-pushgateway
這樣 Prometheus 的核心組件都部署完成了,查看集群中的 Pod,有類(lèi)似如下圖所示的 Pod。
這里有個(gè)注意點(diǎn),如果通過(guò) Prometheus 收集 kube-proxy 的指標(biāo),需要 kube-proxy 開(kāi)通訪問(wèn),默認(rèn) kube-proxy 只允許本機(jī)訪問(wèn)。
需要修改 kube-proxy 的 ConfigMap 中的 metricsBindAddress 值為 0.0.0.0:10249。
- kubectl -n kube-system edit cm kube-proxy
會(huì)看到如下內(nèi)容,將 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,讓它重啟即可看到已正常抓取。
應(yīng)用
至此,Prometheus 的服務(wù)端就全部部署完成了。接下來(lái)就是根據(jù)實(shí)際業(yè)務(wù)部署相應(yīng)的 Exporter,ServiceMonitor 和 PrometheusRule 了。官方和社區(qū)有大量現(xiàn)成的 Exporters 可供使用,如果有特殊需求的也可以參考這里自行開(kāi)發(fā)。
接下來(lái)我們講講如何快速集成 Prometheus 監(jiān)控和報(bào)警。
我們之前提到過(guò) Operator 通過(guò) CRD 的方式提供了很多部署方面的自動(dòng)化,Prometheus-Operator 就提供了四個(gè) CRD,分別是:
- Prometheus,定義了 Prometheus 服務(wù)端,用來(lái)生成服務(wù)端控制器,保證了服務(wù)端的正常運(yùn)行,我們只需要一個(gè)此 CRD 的實(shí)例
- Alertmanager,定義了 AlertManager 服務(wù),用來(lái)生成服務(wù)端控制器,保證了服務(wù)的正常運(yùn)行,我們也只需要一個(gè)此 CRD 的實(shí)例
- ServiceMonitor,定義了 Prometheus 抓取指標(biāo)的目標(biāo),就是 Prometheus 界面 targets 頁(yè)面看到的內(nèi)容,此 CRD 幫助我們創(chuàng)建目標(biāo)的配置
- PrometheusRule,定義了 Prometheus 規(guī)則,就是 Prometheus 界面 Rules 頁(yè)面看到的內(nèi)容,此 CRD 幫助我們創(chuàng)建規(guī)則的配置
Prometheus 和 Alertmanager CRD 主要是之前部署階段關(guān)注的,在服務(wù)應(yīng)用階段,我們主要是創(chuàng)建各個(gè) ServiceMonitor 和 PrometheusRule 來(lái)配置服務(wù)端。
Prometheus-Operator 默認(rèn)會(huì)幫我們注冊(cè)相關(guān)組件的抓取目標(biāo),如下圖所示:
我們要定義其他的抓取目標(biāo),首先來(lái)創(chuàng)建了一個(gè) ServiceMonitor 抓取我們部署的 InfluxDB 的指標(biāo):
- 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:
- # 用標(biāo)簽選擇器來(lái)選擇相應(yīng)的 Pod
- selector:
- matchLabels:
- app: influxdb
- release: influxdb
- # 選擇命名空間
- namespaceSelector:
- matchNames:
- - monitoring
- # 定義抓取的配置,如端口、頻率等
- endpoints:
- - interval: 15s
- port: api
我們?cè)陧?xiàng)目中創(chuàng)建了一個(gè) Chart 模版(在 charts/scrape-targets/ 目錄),能夠快速的創(chuàng)建 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/
創(chuàng)建完成后無(wú)需重啟 Prometheus 服務(wù)端,服務(wù)端根據(jù)標(biāo)簽自動(dòng)載入,過(guò)一會(huì)可以在界面上看到:
Prometheus-Operator 同樣會(huì)幫我們注冊(cè)許多相關(guān)的規(guī)則,如下圖所示:
配置我們自己的 PrometheusRule 同樣很簡(jiǎn)單,我們用如下配置生成報(bào)警規(guī)則,如果 5 分鐘內(nèi)的 HTTP 500 錯(cuò)誤大于 5 則報(bào)警。
- 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
也可以用我們項(xiàng)目中的 Chart 模版(在 charts/rules/ 目錄)來(lái)快速配置。
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/
關(guān)于怎么寫(xiě)規(guī)則配置,可以參考官方的文檔和 PromQL 語(yǔ)法。
以上的操作還是手動(dòng)化的,如果要全自動(dòng)化的話,可以參考我的項(xiàng)目,定義好配置文件,寫(xiě)好自動(dòng)化腳本,接入 CI/CD 工作流,即可讓監(jiān)控系統(tǒng)實(shí)現(xiàn)自動(dòng)部署、自動(dòng)配置。
當(dāng)前文章:一文讀懂如何在Kubernetes上輕松實(shí)現(xiàn)自動(dòng)化部署Prometheus
URL地址:http://www.dlmjj.cn/article/cdeosdg.html


咨詢
建站咨詢
