<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Prometheus 如何做到“活學(xué)活用”,大牛總結(jié)的避坑指南

          共 20616字,需瀏覽 42分鐘

           ·

          2020-12-21 13:01

          公眾號(hào)關(guān)注“杰哥的IT之旅”,

          選擇“星標(biāo)”,重磅干貨,第一時(shí)間送達(dá)!
          作者丨徐亞松?
          來(lái)源丨h(huán)ttp://www.xuyasong.com/?p=1921
          監(jiān)控系統(tǒng)的歷史悠久,是一個(gè)很成熟的方向,而 Prometheus 作為新生代的開(kāi)源監(jiān)控系統(tǒng),慢慢成為了云原生體系的事實(shí)標(biāo)準(zhǔn),也證明了其設(shè)計(jì)很受歡迎。

          本文主要分享在 Prometheus 實(shí)踐中遇到的一些問(wèn)題和思考,如果你對(duì) K8S 監(jiān)控體系或 Prometheus 的設(shè)計(jì)還不太了解,可以先看下容器監(jiān)控系列。

          容器監(jiān)控系列:https://yasongxu.gitbook.io/container-monitor/

          幾點(diǎn)原則

          • 監(jiān)控是基礎(chǔ)設(shè)施,目的是為了解決問(wèn)題,不要只朝著大而全去做,尤其是不必要的指標(biāo)采集,浪費(fèi)人力和存儲(chǔ)資源(To B商業(yè)產(chǎn)品例外)。

          • 需要處理的告警才發(fā)出來(lái),發(fā)出來(lái)的告警必須得到處理。

          • 簡(jiǎn)單的架構(gòu)就是最好的架構(gòu),業(yè)務(wù)系統(tǒng)都掛了,監(jiān)控也不能掛。Google Sre 里面也說(shuō)避免使用 Magic 系統(tǒng),例如機(jī)器學(xué)習(xí)報(bào)警閾值、自動(dòng)修復(fù)之類(lèi)。這一點(diǎn)見(jiàn)仁見(jiàn)智吧,感覺(jué)很多公司都在搞智能 AI 運(yùn)維。


          Prometheus 的局限

          • Prometheus 是基于 Metric 的監(jiān)控,不適用于日志(Logs)、事件(Event)、調(diào)用鏈(Tracing)。

          • Prometheus 默認(rèn)是 Pull 模型,合理規(guī)劃你的網(wǎng)絡(luò),盡量不要轉(zhuǎn)發(fā)。

          • 對(duì)于集群化和水平擴(kuò)展,官方和社區(qū)都沒(méi)有銀彈,需要合理選擇 Federate、Cortex、Thanos等方案。

          • 監(jiān)控系統(tǒng)一般情況下可用性大于一致性,容忍部分副本數(shù)據(jù)丟失,保證查詢(xún)請(qǐng)求成功。這個(gè)后面說(shuō) Thanos 去重的時(shí)候會(huì)提到。

          • Prometheus 不一定保證數(shù)據(jù)準(zhǔn)確,這里的不準(zhǔn)確一是指 rate、histogram_quantile 等函數(shù)會(huì)做統(tǒng)計(jì)和推斷,產(chǎn)生一些反直覺(jué)的結(jié)果,這個(gè)后面會(huì)詳細(xì)展開(kāi)。二來(lái)查詢(xún)范圍過(guò)長(zhǎng)要做降采樣,勢(shì)必會(huì)造成數(shù)據(jù)精度丟失,不過(guò)這是時(shí)序數(shù)據(jù)的特點(diǎn),也是不同于日志系統(tǒng)的地方。


          K8S 集群中常用的 exporter一級(jí)標(biāo)題

          Prometheus 屬于 CNCF 項(xiàng)目,擁有完整的開(kāi)源生態(tài),與 Zabbix 這種傳統(tǒng) agent 監(jiān)控不同,它提供了豐富的 exporter 來(lái)滿(mǎn)足你的各種需求。

          你可以在這里看到官方、非官方的 exporter。如果還是沒(méi)滿(mǎn)足你的需求,你還可以自己編寫(xiě) exporter,簡(jiǎn)單方便、自由開(kāi)放,這是優(yōu)點(diǎn)。

          Prometheus:https://prometheus.io/docs/instrumenting/exporters/

          但是過(guò)于開(kāi)放就會(huì)帶來(lái)選型、試錯(cuò)成本。之前只需要在 zabbix agent里面幾行配置就能完成的事,現(xiàn)在你會(huì)需要很多 exporter 搭配才能完成。還要對(duì)所有 exporter 維護(hù)、監(jiān)控。尤其是升級(jí) exporter 版本時(shí),很痛苦。非官方exporter 還會(huì)有不少 bug。這是使用上的不足,當(dāng)然也是 Prometheus 的設(shè)計(jì)原則。

          K8S 生態(tài)的組件都會(huì)提供/metric接口以提供自監(jiān)控,這里列下我們正在使用的:

          • cadvisor: 集成在 Kubelet 中。

          • kubelet: 10255為非認(rèn)證端口,10250為認(rèn)證端口。

          • apiserver: 6443端口,關(guān)心請(qǐng)求數(shù)、延遲等。

          • scheduler: 10251端口。

          • controller-manager: 10252端口。

          • etcd: 如etcd 寫(xiě)入讀取延遲、存儲(chǔ)容量等。

          • docker: 需要開(kāi)啟 experimental 實(shí)驗(yàn)特性,配置 metrics-addr,如容器創(chuàng)建耗時(shí)等指標(biāo)。

          • kube-proxy: 默認(rèn) 127 暴露,10249端口。外部采集時(shí)可以修改為 0.0.0.0 監(jiān)聽(tīng),會(huì)暴露:寫(xiě)入 iptables 規(guī)則的耗時(shí)等指標(biāo)。

          • kube-state-metrics: K8S 官方項(xiàng)目,采集pod、deployment等資源的元信息。

          • node-exporter: Prometheus 官方項(xiàng)目,采集機(jī)器指標(biāo)如 CPU、內(nèi)存、磁盤(pán)。

          • blackbox_exporter: Prometheus 官方項(xiàng)目,網(wǎng)絡(luò)探測(cè),dns、ping、http監(jiān)控

          • process-exporter: 采集進(jìn)程指標(biāo)

          • nvidia exporter: 我們有 gpu 任務(wù),需要 gpu 數(shù)據(jù)監(jiān)控

          • node-problem-detector: 即 npd,準(zhǔn)確的說(shuō)不是 exporter,但也會(huì)監(jiān)測(cè)機(jī)器狀態(tài),上報(bào)節(jié)點(diǎn)異常打 taint

          • 應(yīng)用層 exporter: mysql、nginx、mq等,看業(yè)務(wù)需求。


          cadvisor:http://www.xuyasong.com/?p=1483
          kube-state-metrics:http://www.xuyasong.com/?p=1525
          node-exporter:http://www.xuyasong.com/?p=1539

          還有各種場(chǎng)景下的自定義 exporter,如日志提取后面會(huì)再做介紹。

          自定義 exporter:http://www.xuyasong.com/?p=1942

          K8S 核心組件監(jiān)控與 Grafana 面板

          k8s 集群運(yùn)行中需要關(guān)注核心組件的狀態(tài)、性能。如 kubelet、apiserver 等,基于上面提到的 exporter 的指標(biāo),可以在 Grafana 中繪制如下圖表:


          模板可以參考dashboards-for-kubernetes-administrators,根據(jù)運(yùn)行情況不斷調(diào)整報(bào)警閾值。

          dashboards-for-kubernetes-administrators:https://povilasv.me/grafana-dashboards-for-kubernetes-administrators

          這里提一下 Grafana 雖然支持了 templates 能力,可以很方便地做多級(jí)下拉框選擇,但是不支持templates 模式下配置報(bào)警規(guī)則,相關(guān)issue

          issue:https://github.com/grafana/grafana/issues/9334

          官方對(duì)這個(gè)功能解釋了一堆,可最新版本仍然沒(méi)有支持。借用 issue 的一句話吐槽下:

          關(guān)于 Grafana 的基礎(chǔ)用法,可以看看《容器監(jiān)控實(shí)踐—Grafana》。

          容器監(jiān)控實(shí)踐—Grafana:http://www.xuyasong.com/?p=1693

          采集組件 All IN One

          Prometheus 體系中 Exporter 都是獨(dú)立的,每個(gè)組件各司其職,如機(jī)器資源用 Node-Exporter,Gpu 有Nvidia Exporter等等。但是 Exporter 越多,運(yùn)維壓力越大,尤其是對(duì) Agent做資源控制、版本升級(jí)。我們嘗試對(duì)一些Exporter進(jìn)行組合,方案有二:

          • 通過(guò)主進(jìn)程拉起N個(gè) Exporter 進(jìn)程,仍然可以跟著社區(qū)版本做更新、bug fix。

          • 用Telegraf來(lái)支持各種類(lèi)型的 Input,N 合 1。


          另外,Node-Exporter 不支持進(jìn)程監(jiān)控,可以加一個(gè)Process-Exporter,也可以用上邊提到的Telegraf,使用 procstat 的 input來(lái)采集進(jìn)程指標(biāo)。

          合理選擇黃金指標(biāo)

          采集的指標(biāo)有很多,我們應(yīng)該關(guān)注哪些?Google 在“Sre Handbook”中提出了“四個(gè)黃金信號(hào)”:延遲、流量、錯(cuò)誤數(shù)、飽和度。實(shí)際操作中可以使用 Use 或 Red 方法作為指導(dǎo),Use 用于資源,Red 用于服務(wù)。

          • Use 方法:Utilization、Saturation、Errors。如 Cadvisor 數(shù)據(jù)

          • Red 方法:Rate、Errors、Duration。如 Apiserver 性能指標(biāo)


          Prometheus 采集中常見(jiàn)的服務(wù)分三種:

          • 在線服務(wù):如 Web 服務(wù)、數(shù)據(jù)庫(kù)等,一般關(guān)心請(qǐng)求速率,延遲和錯(cuò)誤率即 RED 方法。

          • 離線服務(wù):如日志處理、消息隊(duì)列等,一般關(guān)注隊(duì)列數(shù)量、進(jìn)行中的數(shù)量,處理速度以及發(fā)生的錯(cuò)誤即 Use 方法。

          • 批處理任務(wù):和離線任務(wù)很像,但是離線任務(wù)是長(zhǎng)期運(yùn)行的,批處理任務(wù)是按計(jì)劃運(yùn)行的,如持續(xù)集成就是批處理任務(wù),對(duì)應(yīng) K8S 中的 job 或 cronjob, 一般關(guān)注所花的時(shí)間、錯(cuò)誤數(shù)等,因?yàn)檫\(yùn)行周期短,很可能還沒(méi)采集到就運(yùn)行結(jié)束了,所以一般使用 Pushgateway,改拉為推。


          對(duì) Use 和 Red 的實(shí)際示例可以參考容器監(jiān)控實(shí)踐—K8S常用指標(biāo)分析這篇文章。

          容器監(jiān)控實(shí)踐—K8S常用指標(biāo)分析:http://www.xuyasong.com/?P=1717

          K8S 1.16中 Cadvisor 的指標(biāo)兼容問(wèn)題

          在 K8S 1.16版本,Cadvisor 的指標(biāo)去掉了 pod_Name 和 container_name 的 label,替換為了pod 和 container。如果你之前用這兩個(gè) label 做查詢(xún)或者 Grafana 繪圖,需要更改下 Sql 了。因?yàn)槲覀円恢敝С侄鄠€(gè) K8S 版本,就通過(guò) relabel配置繼續(xù)保留了原來(lái)的**_name。


          注意要用 metric_relabel_configs,不是 relabel_configs,采集后做的replace。

          Prometheus采集外部K8S集群、多集群

          Prometheus 如果部署在K8S集群內(nèi)采集是很方便的,用官方給的Yaml就可以,但我們因?yàn)闄?quán)限和網(wǎng)絡(luò)需要部署在集群外,二進(jìn)制運(yùn)行,采集多個(gè) K8S 集群。

          以 Pod 方式運(yùn)行在集群內(nèi)是不需要證書(shū)的(In-Cluster 模式),但集群外需要聲明 token之類(lèi)的證書(shū),并替換address,即使用 Apiserver Proxy采集,以 Cadvisor采集為例,Job 配置為:


          bearer_token_file 需要提前生成,這個(gè)參考官方文檔即可。記得 base64 解碼。

          對(duì)于 cadvisor 來(lái)說(shuō),__metrics_path__可以轉(zhuǎn)換為/api/v1/nodes/${1}/proxy/metrics/cadvisor,代表Apiserver proxy 到 Kubelet,如果網(wǎng)絡(luò)能通,其實(shí)也可以直接把 Kubelet 的10255作為 target,可以直接寫(xiě)為:

          ${1}:10255/metrics/cadvisor,代表直接請(qǐng)求Kubelet,規(guī)模大的時(shí)候還減輕了 Apiserver 的壓力,即服務(wù)發(fā)現(xiàn)使用 Apiserver,采集不走 Apiserver。

          因?yàn)?cadvisor 是暴露主機(jī)端口,配置相對(duì)簡(jiǎn)單,如果是 kube-state-metric 這種 Deployment,以 endpoint 形式暴露,寫(xiě)法應(yīng)該是:


          對(duì)于 endpoint 類(lèi)型,需要轉(zhuǎn)換__metrics_path__為/api/v1/namespaces/${1}/services/${2}:${3}/proxy/metrics,需要替換 namespace、svc 名稱(chēng)端口等,這里的寫(xiě)法只適合接口為/metrics的exporter,如果你的 exporter 不是/metrics接口,需要替換這個(gè)路徑。或者像我們一樣統(tǒng)一約束都使用這個(gè)地址。

          這里的__meta_kubernetes_service_annotation_prometheus_io_port來(lái)源就是 exporter 部署時(shí)寫(xiě)的那個(gè) annotation,大多數(shù)文章中只提到prometheus.io/scrape: 'true',但也可以定義端口、路徑、協(xié)議。以方便在采集時(shí)做替換處理。

          其他的一些 relabel 如kubernetes_namespace 是為了保留原始信息,方便做 promql 查詢(xún)時(shí)的篩選條件。

          如果是多集群,同樣的配置多寫(xiě)幾遍就可以了,一般一個(gè)集群可以配置三類(lèi)job:

          • role:node 的,包括 cadvisor、 node-exporter、kubelet 的 summary、kube-proxy、docker 等指標(biāo)。

          • role:endpoint 的,包括 kube-state-metric 以及其他自定義 Exporter。

          • 普通采集:包括Etcd、Apiserver 性能指標(biāo)、進(jìn)程指標(biāo)等。


          GPU 指標(biāo)的獲取

          nvidia-smi可以查看機(jī)器上的 GPU 資源,而Cadvisor 其實(shí)暴露了Metric來(lái)表示容器使用 GPU 情況,


          如果要更詳細(xì)的 GPU 數(shù)據(jù),可以安裝dcgm exporter,不過(guò)K8S 1.13 才能支持。

          更改 Prometheus 的顯示時(shí)區(qū)

          Prometheus 為避免時(shí)區(qū)混亂,在所有組件中專(zhuān)門(mén)使用 Unix Time 和 Utc 進(jìn)行顯示。不支持在配置文件中設(shè)置時(shí)區(qū),也不能讀取本機(jī) /etc/timezone 時(shí)區(qū)。

          其實(shí)這個(gè)限制是不影響使用的:

          • 如果做可視化,Grafana是可以做時(shí)區(qū)轉(zhuǎn)換的。

          • 如果是調(diào)接口,拿到了數(shù)據(jù)中的時(shí)間戳,你想怎么處理都可以。

          • 如果因?yàn)?Prometheus 自帶的 UI 不是本地時(shí)間,看著不舒服,2.16 版本的新版 Web UI已經(jīng)引入了Local Timezone 的選項(xiàng),區(qū)別見(jiàn)下圖。

          • 如果你仍然想改 Prometheus 代碼來(lái)適應(yīng)自己的時(shí)區(qū),可以參考《修改源碼更改prometheus的時(shí)區(qū)問(wèn)題》。


          2.16 版本:
          https://github.com/prometheus/prometheus/commit/d996ba20ec9c7f1808823a047ed9d5ce96be3d8f
          修改源碼更改prometheus的時(shí)區(qū)問(wèn)題:
          https://zhangguanzhang.github.io/2019/09/05/prometheus-change-timezone/


          關(guān)于 timezone 的討論,可以看這個(gè)issue。

          issue:https://github.com/prometheus/prometheus/issues/500

          如何采集 LB 后面的 RS 的 Metric

          假如你有一個(gè)負(fù)載均衡 LB,但網(wǎng)絡(luò)上 Prometheus 只能訪問(wèn)到 LB 本身,訪問(wèn)不到后面的 RS,應(yīng)該如何采集 RS 暴露的 Metric?

          • RS 的服務(wù)加 Sidecar Proxy,或者本機(jī)增加 Proxy 組件,保證 Prometheus 能訪問(wèn)到。

          • LB 增加 /backend1 和 /backend2請(qǐng)求轉(zhuǎn)發(fā)到兩個(gè)單獨(dú)的后端,再由 Prometheus 訪問(wèn) LB 采集。


          版本的選擇

          Prometheus 當(dāng)前最新版本為 2.16,Prometheus 還在不斷迭代,因此盡量用最新版,1.X版本就不用考慮了。

          2.16 版本上有一套實(shí)驗(yàn) UI,可以查看 TSDB 的狀態(tài),包括Top 10的 Label、Metric。


          Prometheus 大內(nèi)存問(wèn)題

          隨著規(guī)模變大,Prometheus 需要的 CPU 和內(nèi)存都會(huì)升高,內(nèi)存一般先達(dá)到瓶頸,這個(gè)時(shí)候要么加內(nèi)存,要么集群分片減少單機(jī)指標(biāo)。這里我們先討論單機(jī)版 Prometheus 的內(nèi)存問(wèn)題。

          原因:

          • Prometheus 的內(nèi)存消耗主要是因?yàn)槊扛?小時(shí)做一個(gè) Block 數(shù)據(jù)落盤(pán),落盤(pán)之前所有數(shù)據(jù)都在內(nèi)存里面,因此和采集量有關(guān)。

          • 加載歷史數(shù)據(jù)時(shí),是從磁盤(pán)到內(nèi)存的,查詢(xún)范圍越大,內(nèi)存越大。這里面有一定的優(yōu)化空間。

          • 一些不合理的查詢(xún)條件也會(huì)加大內(nèi)存,如 Group 或大范圍 Rate。


          我的指標(biāo)需要多少內(nèi)存:

          • 作者給了一個(gè)計(jì)算器,設(shè)置指標(biāo)量、采集間隔之類(lèi)的,計(jì)算 Prometheus 需要的理論內(nèi)存值:計(jì)算公式。


          計(jì)算公式:https://www.robustperception.io/how-much-ram-does-prometheus-2-x-need-for-cardinality-and-ingestion

          以我們的一個(gè) Prometheus Server為例,本地只保留 2 小時(shí)數(shù)據(jù),95 萬(wàn) Series,大概占用的內(nèi)存如下:


          有什么優(yōu)化方案:

          • Sample 數(shù)量超過(guò)了 200 萬(wàn),就不要單實(shí)例了,做下分片,然后通過(guò) Victoriametrics,Thanos,Trickster 等方案合并數(shù)據(jù)。

          • 評(píng)估哪些 Metric 和 Label 占用較多,去掉沒(méi)用的指標(biāo)。2.14 以上可以看 Tsdb 狀態(tài)。

          • 查詢(xún)時(shí)盡量避免大范圍查詢(xún),注意時(shí)間范圍和 Step 的比例,慎用 Group。

          • 如果需要關(guān)聯(lián)查詢(xún),先想想能不能通過(guò) Relabel 的方式給原始數(shù)據(jù)多加個(gè) Label,一條Sql 能查出來(lái)的何必用Join,時(shí)序數(shù)據(jù)庫(kù)不是關(guān)系數(shù)據(jù)庫(kù)。


          Prometheus 內(nèi)存占用分析:

          • 通過(guò) pprof分析:https://www.robustperception.io/optimising-prometheus-2-6-0-memory-usage-with-pprof

          • 1.X 版本的內(nèi)存:https://www.robustperception.io/how-much-ram-does-my-prometheus-need-for-ingestion


          相關(guān) issue:

          • https://groups.google.com/forum/#!searchin/prometheus-users/memory%7Csort:date/prometheus-users/q4oiVGU6Bxo/uifpXVw3CwAJ

          • https://github.com/prometheus/prometheus/issues/5723

          • https://github.com/prometheus/prometheus/issues/1881


          Prometheus 容量規(guī)劃

          容量規(guī)劃除了上邊說(shuō)的內(nèi)存,還有磁盤(pán)存儲(chǔ)規(guī)劃,這和你的 Prometheus 的架構(gòu)方案有關(guān)。

          • 如果是單機(jī)Prometheus,計(jì)算本地磁盤(pán)使用量。

          • 如果是 Remote-Write,和已有的 Tsdb 共用即可。

          • 如果是 Thanos 方案,本地磁盤(pán)可以忽略(2H),計(jì)算對(duì)象存儲(chǔ)的大小就行。


          Prometheus 每2小時(shí)將已緩沖在內(nèi)存中的數(shù)據(jù)壓縮到磁盤(pán)上的塊中。包括Chunks、Indexes、Tombstones、Metadata,這些占用了一部分存儲(chǔ)空間。一般情況下,Prometheus中存儲(chǔ)的每一個(gè)樣本大概占用1-2字節(jié)大小(1.7Byte)。可以通過(guò)Promql來(lái)查看每個(gè)樣本平均占用多少空間:


          ? ? “`bash
          rate(prometheus_tsdb_compaction_chunk_size_bytes_sum[1h])
          /
          rate(prometheus_tsdb_compaction_chunk_samples_sum[1h]){instance="0.0.0.0:8890", job="prometheus"}
          1.252747585939941
          ? ? “`

          如果大致估算本地磁盤(pán)大小,可以通過(guò)以下公式:


          保留時(shí)間(retention_time_seconds)和樣本大小(bytes_per_sample)不變的情況下,如果想減少本地磁盤(pán)的容量需求,只能通過(guò)減少每秒獲取樣本數(shù)(ingested_samples_per_second)的方式。

          查看當(dāng)前每秒獲取的樣本數(shù):


          有兩種手段,一是減少時(shí)間序列的數(shù)量,二是增加采集樣本的時(shí)間間隔。考慮到 Prometheus 會(huì)對(duì)時(shí)間序列進(jìn)行壓縮,因此減少時(shí)間序列的數(shù)量效果更明顯。

          舉例說(shuō)明:

          • 采集頻率 30s,機(jī)器數(shù)量1000,Metric種類(lèi)6000,1000600026024 約 200 億,30G 左右磁盤(pán)。

          • 只采集需要的指標(biāo),如 match[], 或者統(tǒng)計(jì)下最常使用的指標(biāo),性能最差的指標(biāo)。


          以上磁盤(pán)容量并沒(méi)有把 wal 文件算進(jìn)去,wal 文件(Raw Data)在 Prometheus 官方文檔中說(shuō)明至少會(huì)保存3個(gè) Write-Ahead Log Files,每一個(gè)最大為128M(實(shí)際運(yùn)行發(fā)現(xiàn)數(shù)量會(huì)更多)。

          因?yàn)槲覀兪褂昧?Thanos 的方案,所以本地磁盤(pán)只保留2H 熱數(shù)據(jù)。Wal 每2小時(shí)生成一份Block文件,Block文件每2小時(shí)上傳對(duì)象存儲(chǔ),本地磁盤(pán)基本沒(méi)有壓力。
          關(guān)于 Prometheus 存儲(chǔ)機(jī)制,可以看《容器監(jiān)控實(shí)踐—Prometheus存儲(chǔ)機(jī)制》。

          容器監(jiān)控實(shí)踐—Prometheus存儲(chǔ)機(jī)制:http://www.xuyasong.com/?p=1601

          對(duì) Apiserver 的性能影響

          如果你的 Prometheus 使用了 kubernetes_sd_config 做服務(wù)發(fā)現(xiàn),請(qǐng)求一般會(huì)經(jīng)過(guò)集群的 Apiserver,隨著規(guī)模的變大,需要評(píng)估下對(duì) Apiserver性能的影響,尤其是Proxy失敗的時(shí)候,會(huì)導(dǎo)致CPU 升高。當(dāng)然了,如果單K8S集群規(guī)模太大,一般都是拆分集群,不過(guò)隨時(shí)監(jiān)測(cè)下 Apiserver 的進(jìn)程變化還是有必要的。

          在監(jiān)控Cadvisor、Docker、Kube-Proxy 的 Metric 時(shí),我們一開(kāi)始選擇從 Apiserver Proxy 到節(jié)點(diǎn)的對(duì)應(yīng)端口,統(tǒng)一設(shè)置比較方便,但后來(lái)還是改為了直接拉取節(jié)點(diǎn),Apiserver 僅做服務(wù)發(fā)現(xiàn)。

          Rate 的計(jì)算邏輯

          Prometheus 中的 Counter 類(lèi)型主要是為了 Rate 而存在的,即計(jì)算速率,單純的 Counter 計(jì)數(shù)意義不大,因?yàn)?Counter 一旦重置,總計(jì)數(shù)就沒(méi)有意義了。

          Rate 會(huì)自動(dòng)處理 Counter 重置的問(wèn)題,Counter 一般都是一直變大的,例如一個(gè) Exporter 啟動(dòng),然后崩潰了。本來(lái)以每秒大約10的速率遞增,但僅運(yùn)行了半個(gè)小時(shí),則速率(x_total [1h])將返回大約每秒5的結(jié)果。另外,Counter 的任何減少也會(huì)被視為 Counter 重置。例如,如果時(shí)間序列的值為[5,10,4,6],則將其視為[5,10,14,16]。

          Rate 值很少是精確的。由于針對(duì)不同目標(biāo)的抓取發(fā)生在不同的時(shí)間,因此隨著時(shí)間的流逝會(huì)發(fā)生抖動(dòng),query_range 計(jì)算時(shí)很少會(huì)與抓取時(shí)間完美匹配,并且抓取有可能失敗。面對(duì)這樣的挑戰(zhàn),Rate 的設(shè)計(jì)必須是健壯的。

          Rate 并非想要捕獲每個(gè)增量,因?yàn)橛袝r(shí)候增量會(huì)丟失,例如實(shí)例在抓取間隔中掛掉。如果 Counter 的變化速度很慢,例如每小時(shí)僅增加幾次,則可能會(huì)導(dǎo)致【假象】。比如出現(xiàn)一個(gè) Counter 時(shí)間序列,值為100,Rate 就不知道這些增量是現(xiàn)在的值,還是目標(biāo)已經(jīng)運(yùn)行了好幾年并且才剛剛開(kāi)始返回。

          建議將 Rate 計(jì)算的范圍向量的時(shí)間至少設(shè)為抓取間隔的四倍。這將確保即使抓取速度緩慢,且發(fā)生了一次抓取故障,您也始終可以使用兩個(gè)樣本。此類(lèi)問(wèn)題在實(shí)踐中經(jīng)常出現(xiàn),因此保持這種彈性非常重要。例如,對(duì)于1分鐘的抓取間隔,您可以使用4分鐘的 Rate 計(jì)算,但是通常將其四舍五入為5分鐘。

          如果 Rate 的時(shí)間區(qū)間內(nèi)有數(shù)據(jù)缺失,他會(huì)基于趨勢(shì)進(jìn)行推測(cè),比如:


          反直覺(jué)的 P95 統(tǒng)計(jì)

          histogram_quantile 是 Prometheus 常用的一個(gè)函數(shù),比如經(jīng)常把某個(gè)服務(wù)的 P95 響應(yīng)時(shí)間來(lái)衡量服務(wù)質(zhì)量。不過(guò)它到底是什么意思很難解釋得清,特別是面向非技術(shù)的同學(xué),會(huì)遇到很多“靈魂拷問(wèn)”。

          我們常說(shuō) P95(P99,P90都可以) 響應(yīng)延遲是 100ms,實(shí)際上是指對(duì)于收集到的所有響應(yīng)延遲,有 5% 的請(qǐng)求大于 100ms,95% 的請(qǐng)求小于 100ms。Prometheus 里面的 histogram_quantile 函數(shù)接收的是 0-1 之間的小數(shù),將這個(gè)小數(shù)乘以 100 就能很容易得到對(duì)應(yīng)的百分位數(shù),比如 0.95 就對(duì)應(yīng)著 P95,而且還可以高于百分位數(shù)的精度,比如 0.9999。

          當(dāng)你用 histogram_quantile 畫(huà)出響應(yīng)時(shí)間的趨勢(shì)圖時(shí),可能會(huì)被問(wèn):為什么P95大于或小于我的平均值?

          正如中位數(shù)可能比平均數(shù)大也可能比平均數(shù)小,P99 比平均值小也是完全有可能的。通常情況下 P99 幾乎總是比平均值要大的,但是如果數(shù)據(jù)分布比較極端,最大的 1% 可能大得離譜從而拉高了平均值。一種可能的例子:


          服務(wù) X 由順序的 A,B 兩個(gè)步驟完成,其中 X 的 P99 耗時(shí) 100Ms,A 過(guò)程 P99 耗時(shí) 50Ms,那么推測(cè) B 過(guò)程的 P99 耗時(shí)情況是?

          直覺(jué)上來(lái)看,因?yàn)橛?X=A+B,所以答案可能是 50Ms,或者至少應(yīng)該要小于 50Ms。實(shí)際上 B 是可以大于 50Ms 的,只要 A 和 B 最大的 1% 不恰好遇到,B 完全可以有很大的 P99:


          所以我們從題目唯一能確定的只有 B 的 P99 應(yīng)該不能超過(guò) 100ms,A 的 P99 耗時(shí) 50Ms 這個(gè)條件其實(shí)沒(méi)啥用。

          類(lèi)似的疑問(wèn)很多,因此對(duì)于 histogram_quantile 函數(shù),可能會(huì)產(chǎn)生反直覺(jué)的一些結(jié)果,最好的處理辦法是不斷試驗(yàn)調(diào)整你的 Bucket 的值,保證更多的請(qǐng)求時(shí)間落在更細(xì)致的區(qū)間內(nèi),這樣的請(qǐng)求時(shí)間才有統(tǒng)計(jì)意義。

          慢查詢(xún)問(wèn)題

          Prometheus 提供了自定義的 Promql 作為查詢(xún)語(yǔ)句,在 Graph 上調(diào)試的時(shí)候,會(huì)告訴你這條 Sql 的返回時(shí)間,如果太慢你就要注意了,可能是你的用法出現(xiàn)了問(wèn)題。

          慢查詢(xún):http://www.xuyasong.com/?p=1578

          評(píng)估 Prometheus 的整體響應(yīng)時(shí)間,可以用這個(gè)默認(rèn)指標(biāo):


          一般情況下響應(yīng)過(guò)慢都是Promql 使用不當(dāng)導(dǎo)致,或者指標(biāo)規(guī)劃有問(wèn)題,如:

          • 大量使用 join 來(lái)組合指標(biāo)或者增加 label,如將 kube-state-metric 中的一些 meta label和 node-exporter 中的節(jié)點(diǎn)屬性 label加入到 cadvisor容器數(shù)據(jù)里,像統(tǒng)計(jì) pod 內(nèi)存使用率并按照所屬節(jié)點(diǎn)的機(jī)器類(lèi)型分類(lèi),或按照所屬 rs 歸類(lèi)。

          • 范圍查詢(xún)時(shí),大的時(shí)間范圍 step 值卻很小,導(dǎo)致查詢(xún)到的數(shù)量過(guò)大。

          • rate 會(huì)自動(dòng)處理 counter 重置的問(wèn)題,最好由 promql 完成,不要自己拿出來(lái)全部元數(shù)據(jù)在程序中自己做 rate 計(jì)算。

          • 在使用 rate 時(shí),range duration要大于等于step,否則會(huì)丟失部分?jǐn)?shù)據(jù)

          • prometheus 是有基本預(yù)測(cè)功能的,如deriv和predict_linear(更準(zhǔn)確)可以根據(jù)已有數(shù)據(jù)預(yù)測(cè)未來(lái)趨勢(shì)

          • 如果比較復(fù)雜且耗時(shí)的sql,可以使用 record rule 減少指標(biāo)數(shù)量,并使查詢(xún)效率更高,但不要什么指標(biāo)都加 record,一半以上的 metric 其實(shí)不太會(huì)查詢(xún)到。同時(shí) label 中的值不要加到 record rule 的 name 中。


          step:https://www.robustperception.io/step-and-query_range
          部分?jǐn)?shù)據(jù):https://chanjarster.github.io/post/p8s-step-param/

          高基數(shù)問(wèn)題 Cardinality

          高基數(shù)是數(shù)據(jù)庫(kù)避不開(kāi)的一個(gè)話題,對(duì)于 Mysql 這種 DB 來(lái)講,基數(shù)是指特定列或字段中包含的唯一值的數(shù)量。基數(shù)越低,列中重復(fù)的元素越多。對(duì)于時(shí)序數(shù)據(jù)庫(kù)而言,就是 tags、label 這種標(biāo)簽值的數(shù)量多少。

          比如 Prometheus 中如果有一個(gè)指標(biāo) http_request_count{method="get",path="/abc",originIP="1.1.1.1"}表示訪問(wèn)量,method 表示請(qǐng)求方法,originIP 是客戶(hù)端 IP,method的枚舉值是有限的,但 originIP 卻是無(wú)限的,加上其他 label 的排列組合就無(wú)窮大了,也沒(méi)有任何關(guān)聯(lián)特征,因此這種高基數(shù)不適合作為 Metric 的 label,真要的提取originIP,應(yīng)該用日志的方式,而不是 Metric 監(jiān)控。

          時(shí)序數(shù)據(jù)庫(kù)會(huì)為這些 Label 建立索引,以提高查詢(xún)性能,以便您可以快速找到與所有指定標(biāo)簽匹配的值。如果值的數(shù)量過(guò)多,索引是沒(méi)有意義的,尤其是做 P95 等計(jì)算的時(shí)候,要掃描大量 Series 數(shù)據(jù)。

          官方文檔中對(duì)于Label 的建議


          如何查看當(dāng)前的Label 分布情況呢,可以使用 Prometheus提供的Tsdb工具。可以使用命令行查看,也可以在 2.16 版本以上的 Prometheus Graph 查看



          top10 高基數(shù)的 metric


          高基數(shù)的 label


          找到最大的 metric 或 job

          top10的 metric 數(shù)量:按 metric 名字分


          top10的 metric 數(shù)量:按 job 名字分


          Prometheus 重啟慢與熱加載

          Prometheus 重啟的時(shí)候需要把 Wal 中的內(nèi)容 Load 到內(nèi)存里,保留時(shí)間越久、Wal 文件越大,重啟的實(shí)際越長(zhǎng),這個(gè)是 Prometheus 的機(jī)制,沒(méi)得辦法,因此能 Reload 的就不要重啟,重啟一定會(huì)導(dǎo)致短時(shí)間的不可用,而這個(gè)時(shí)候Prometheus高可用就很重要了。

          Prometheus 也曾經(jīng)對(duì)啟動(dòng)時(shí)間做過(guò)優(yōu)化,在 2.6 版本中對(duì)于Wal的 Load 速度就做過(guò)速度的優(yōu)化,希望重啟的時(shí)間不超過(guò) 1 分鐘。

          1分鐘:https://www.robustperception.io/optimising-startup-time-of-prometheus-2-6-0-with-pprof

          Prometheus 提供了熱加載能力,不過(guò)需要開(kāi)啟web.enable-lifecycle配置,更改完配置后,curl 下 reload 接口即可。prometheus-operator 中更改了配置會(huì)默認(rèn)觸發(fā) reload,如果你沒(méi)有使用operator,又希望可以監(jiān)聽(tīng) configmap 配置變化來(lái) reload 服務(wù),可以試下這個(gè)簡(jiǎn)單的腳本。


          使用時(shí)和 prometheus 掛載同一個(gè) configmap,傳入如下參數(shù)即可:


          你的應(yīng)用需要暴露多少指標(biāo)

          當(dāng)你開(kāi)發(fā)自己的服務(wù)的時(shí)候,你可能會(huì)把一些數(shù)據(jù)暴露 Metric出去,比如特定請(qǐng)求數(shù)、Goroutine 數(shù)等,指標(biāo)數(shù)量多少合適呢?

          雖然指標(biāo)數(shù)量和你的應(yīng)用規(guī)模相關(guān),但也有一些建議(Brian Brazil),比如簡(jiǎn)單的服務(wù)如緩存等,類(lèi)似 Pushgateway,大約 120 個(gè)指標(biāo),Prometheus 本身暴露了 700 左右的指標(biāo),如果你的應(yīng)用很大,也盡量不要超過(guò) 10000 個(gè)指標(biāo),需要合理控制你的 Label。

          建議(Brian Brazil):https://www.robustperception.io/how-many-metrics-should-an-application-return

          node-exporter 的問(wèn)題

          • node-exporter 不支持進(jìn)程監(jiān)控,這個(gè)前面已經(jīng)提到了。

          • node-exporter 只支持 unix 系統(tǒng),windows機(jī)器 請(qǐng)使用 wmi_exporter。因此以 yaml 形式不是 node-exporter 的時(shí)候,node-selector 要表明os類(lèi)型。

          • 因?yàn)閚ode_exporter是比較老的組件,有一些最佳實(shí)踐并沒(méi)有merge進(jìn)去,比如符合Prometheus命名規(guī)范,因此建議使用較新的0.16和0.17版本。


          命名規(guī)范:https://prometheus.io/docs/practices/naming/

          一些指標(biāo)名字的變化:


          如果你之前用的舊版本 exporter,在繪制 grafana 的時(shí)候指標(biāo)名稱(chēng)就會(huì)有差別,解決方法有兩種:

          • 一是在機(jī)器上啟動(dòng)兩個(gè)版本的node-exporter,都讓prometheus去采集。

          • 二是使用指標(biāo)轉(zhuǎn)換器,他會(huì)將舊指標(biāo)名稱(chēng)轉(zhuǎn)換為新指標(biāo)


          指標(biāo)轉(zhuǎn)換器:https://github.com/prometheus/node_exporter/blob/master/docs/example-16-compatibility-rules.yml

          kube-state-metric 的問(wèn)題

          除了文章中提到的作用,kube-state-metric還有一個(gè)很重要的使用場(chǎng)景,就是和 cadvisor 指標(biāo)組合,原始的 cadvisor 中只有 pod 信息,不知道屬于哪個(gè) deployment 或者 sts,但是和kube-state-metric 中的 kube_pod_info 做 join 查詢(xún)之后就可以顯示出來(lái),kube-state-metric的元數(shù)據(jù)指標(biāo),在擴(kuò)展 cadvisor 的 label 中起到了很多作用,prometheus-operator 的很多 record rule 就使用了 kube-state-metric 做組合查詢(xún)。

          容器監(jiān)控實(shí)踐—kube-state-metrics:http://www.xuyasong.com/?p=1525

          kube-state-metric 中也可以展示 pod 的 label 信息,可以在拿到 cadvisor 數(shù)據(jù)后更方便地做 group by,如按照 pod 的運(yùn)行環(huán)境分類(lèi)。但是 kube-state-metric 不暴露 pod 的 annotation,原因是下面會(huì)提到的高基數(shù)問(wèn)題,即 annotation 的內(nèi)容太多,不適合作為指標(biāo)暴露。

          relabel_configs

          relabel_configs 與 metric_relabel_configs

          relabel_config 發(fā)生在采集之前,metric_relabel_configs 發(fā)生在采集之后,合理搭配可以滿(mǎn)足很多場(chǎng)景的配置。

          如:


          Prometheus 的預(yù)測(cè)能力

          場(chǎng)景1:你的磁盤(pán)剩余空間一直在減少,并且降低的速度比較均勻,你希望知道大概多久之后達(dá)到閾值,并希望在某一個(gè)時(shí)刻報(bào)警出來(lái)。

          場(chǎng)景2:你的 Pod 內(nèi)存使用率一直升高,你希望知道大概多久之后會(huì)到達(dá) Limit 值,并在一定時(shí)刻報(bào)警出來(lái),在被殺掉之前上去排查。

          Prometheus 的 Deriv 和 Predict_Linear 方法可以滿(mǎn)足這類(lèi)需求, Promtheus 提供了基礎(chǔ)的預(yù)測(cè)能力,基于當(dāng)前的變化速度,推測(cè)一段時(shí)間后的值。

          以 mem_free 為例,最近一小時(shí)的 free 值一直在下降。


          deriv函數(shù)可以顯示指標(biāo)在一段時(shí)間的變化速度:


          predict_linear方法是預(yù)測(cè)基于這種速度,最后可以達(dá)到的值:


          你可以基于設(shè)置合理的報(bào)警規(guī)則,如小于 10 時(shí)報(bào)警:


          predict_linear 與 deriv 的關(guān)系: 含義上約等于如下表達(dá)式,不過(guò) predict_linear 稍微準(zhǔn)確一些。


          如果你要基于 Metric做模型預(yù)測(cè),可以參考下forecast-prometheus。

          forecast-prometheus:https://github.com/nfrumkin/forecast-prometheus

          alertmanager 的上層封裝

          Prometheus 部署之后很少會(huì)改動(dòng),尤其是做了服務(wù)發(fā)現(xiàn),就不需要頻繁新增 target。但報(bào)警的配置是很頻繁的,如修改閾值、修改報(bào)警人等。alertmanager 擁有豐富的報(bào)警能力如分組、抑制等,但如果你要想把他給業(yè)務(wù)部門(mén)使用,就要做一層封裝了,也就是報(bào)警配置臺(tái)。用戶(hù)喜歡表單操作,而非晦澀的 yaml,同時(shí)他們也并不愿意去理解 promql。而且大多數(shù)公司內(nèi)已經(jīng)有現(xiàn)成的監(jiān)控平臺(tái),也只有一份短信或郵件網(wǎng)關(guān),所以最好能使用 webhook 直接集成。

          例如: 機(jī)器磁盤(pán)使用量超過(guò) 90% 就報(bào)警,rule 應(yīng)該寫(xiě)為:disk_used/disk_total > 0.9

          如果不加 label 篩選,這條報(bào)警會(huì)對(duì)所有機(jī)器生效,但如果你想去掉其中幾臺(tái)機(jī)器,就得在disk_used和disk_total后面加上{instance != “”}。這些操作在 promql 中是很簡(jiǎn)單的,但是如果放在表單里操作,就得和內(nèi)部的 cmdb 做聯(lián)動(dòng)篩選了。

          • 對(duì)于一些簡(jiǎn)單的需求,我們使用了 Grafana 的報(bào)警能力,所見(jiàn)即所得,直接在圖表下面配置告警即可,報(bào)警閾值和狀態(tài)很清晰。不過(guò) Grafana 的報(bào)警能力很弱,只是實(shí)驗(yàn)功能,可以作為調(diào)試使用。

          • 對(duì)于常見(jiàn)的 pod 或應(yīng)用監(jiān)控,我們做了一些表單化,如下圖所示:提取了 CPU、內(nèi)存、磁盤(pán) IO 等常見(jiàn)的指標(biāo)作為選擇項(xiàng),方便配置。



          • 使用 webhook 擴(kuò)展報(bào)警能力,改造 alertmanager, 在 send message 時(shí)做加密和認(rèn)證,對(duì)接內(nèi)部已有報(bào)警能力,并聯(lián)動(dòng)用戶(hù)體系,做限流和權(quán)限控制。

          • 調(diào)用 alertmanager api 查詢(xún)報(bào)警事件,進(jìn)行展示和統(tǒng)計(jì)。


          對(duì)于用戶(hù)來(lái)說(shuō),封裝 alertmanager yaml 會(huì)變的易用,但也會(huì)限制其能力,在增加報(bào)警配置時(shí),研發(fā)和運(yùn)維需要有一定的配合。如新寫(xiě)了一份自定義的 exporter,要將需要的指標(biāo)供用戶(hù)選擇,并調(diào)整好展示和報(bào)警用的 promql。還有報(bào)警模板、原生 promql 暴露、用戶(hù)分組等,需要視用戶(hù)需求做權(quán)衡。

          錯(cuò)誤的高可用設(shè)計(jì)

          有些人提出過(guò)這種類(lèi)型的方案,想提高其擴(kuò)展性和可用性。


          應(yīng)用程序?qū)?Metric 推到到消息隊(duì)列如 Kafaka,然后經(jīng)過(guò) Exposer 消費(fèi)中轉(zhuǎn),再被 Prometheus 拉取。產(chǎn)生這種方案的原因一般是有歷史包袱、復(fù)用現(xiàn)有組件、想通過(guò) Mq 來(lái)提高擴(kuò)展性。

          這種方案有幾個(gè)問(wèn)題:

          • 增加了 Queue 組件,多了一層依賴(lài),如果 App與 Queue 之間連接失敗,難道要在 App 本地緩存監(jiān)控?cái)?shù)據(jù)?

          • 抓取時(shí)間可能會(huì)不同步,延遲的數(shù)據(jù)將會(huì)被標(biāo)記為陳舊數(shù)據(jù),當(dāng)然你可以通過(guò)添加時(shí)間戳來(lái)標(biāo)識(shí),但就失去了對(duì)陳舊數(shù)據(jù)的處理邏輯。

          • 擴(kuò)展性問(wèn)題:Prometheus 適合大量小目標(biāo),而不是一個(gè)大目標(biāo),如果你把所有數(shù)據(jù)都放在了 Exposer 中,那么 Prometheus 的單個(gè) Job 拉取就會(huì)成為 CPU 瓶頸。這個(gè)和 Pushgateway 有些類(lèi)似,沒(méi)有特別必要的場(chǎng)景,都不是官方建議的方式。

          • 缺少了服務(wù)發(fā)現(xiàn)和拉取控制,Prom 只知道一個(gè) Exposer,不知道具體是哪些 Target,不知道他們的 UP 時(shí)間,無(wú)法使用 Scrape_* 等指標(biāo)做查詢(xún),也無(wú)法用scrape_limit做限制。


          處理邏輯:https://www.robustperception.io/staleness-and-promql
          scrape_limit:https://www.robustperception.io/using-sample_limit-to-avoid-overload

          如果你的架構(gòu)和 Prometheus 的設(shè)計(jì)理念相悖,可能要重新設(shè)計(jì)一下方案了,否則擴(kuò)展性和可靠性反而會(huì)降低。

          prometheus-operator 的場(chǎng)景

          如果你是在 K8S 集群內(nèi)部署 Prometheus,那大概率會(huì)用到 prometheus-operator,他對(duì) Prometheus 的配置做了 CRD 封裝,讓用戶(hù)更方便的擴(kuò)展 Prometheus實(shí)例,同時(shí) prometheus-operator 還提供了豐富的 Grafana 模板,包括上面提到的 master 組件監(jiān)控的 Grafana 視圖,operator 啟動(dòng)之后就可以直接使用,免去了配置面板的煩惱。

          operator 的優(yōu)點(diǎn)很多,就不一一列舉了,只提一下 operator 的局限:

          • 因?yàn)槭?operator,所以依賴(lài) K8S 集群,如果你需要二進(jìn)制部署你的 Prometheus,如集群外部署,就很難用上prometheus-operator了,如多集群場(chǎng)景。當(dāng)然你也可以在 K8S 集群中部署 operator 去監(jiān)控其他的 K8S 集群,但這里面坑不少,需要修改一些配置。

          • operator 屏蔽了太多細(xì)節(jié),這個(gè)對(duì)用戶(hù)是好事,但對(duì)于理解 Prometheus 架構(gòu)就有些 gap 了,比如碰到一些用戶(hù)一鍵安裝了operator,但 Grafana 圖表異常后完全不知道如何排查,record rule 和 服務(wù)發(fā)現(xiàn)還不了解的情況下就直接配置,建議在使用 operator 之前,最好熟悉 prometheus 的基礎(chǔ)用法。

          • operator 方便了 Prometheus 的擴(kuò)展和配置,對(duì)于 alertmanager 和 exporter 可以很方便的做到多實(shí)例高可用,但是沒(méi)有解決 Prometheus 的高可用問(wèn)題,因?yàn)闊o(wú)法處理數(shù)據(jù)不一致,operator目前的定位也還不是這個(gè)方向,和 Thanos、Cortex 等方案的定位是不同的,下面會(huì)詳細(xì)解釋。


          高可用方案

          Prometheus 高可用有幾種方案:

          • 基本 HA:即兩套 Prometheus 采集完全一樣的數(shù)據(jù),外邊掛負(fù)載均衡

          • HA + 遠(yuǎn)程存儲(chǔ):除了基礎(chǔ)的多副本 Prometheus,還通過(guò) Remote Write 寫(xiě)入到遠(yuǎn)程存儲(chǔ),解決存儲(chǔ)持久化問(wèn)題

          • 聯(lián)邦集群:即 Federation,按照功能進(jìn)行分區(qū),不同的 Shard 采集不同的數(shù)據(jù),由Global節(jié)點(diǎn)來(lái)統(tǒng)一存放,解決監(jiān)控?cái)?shù)據(jù)規(guī)模的問(wèn)題。

          • 使用 Thanos 或者 Victoriametrics,來(lái)解決全局查詢(xún)、多副本數(shù)據(jù) Join 問(wèn)題。


          就算使用官方建議的多副本 + 聯(lián)邦,仍然會(huì)遇到一些問(wèn)題:

          • 官方建議數(shù)據(jù)做 Shard,然后通過(guò)Federation來(lái)實(shí)現(xiàn)高可用,

          • 但是邊緣節(jié)點(diǎn)和Global節(jié)點(diǎn)依然是單點(diǎn),需要自行決定是否每一層都要使用雙節(jié)點(diǎn)重復(fù)采集進(jìn)行保活。也就是仍然會(huì)有單機(jī)瓶頸。

          • 另外部分敏感報(bào)警盡量不要通過(guò)Global節(jié)點(diǎn)觸發(fā),畢竟從Shard節(jié)點(diǎn)到Global節(jié)點(diǎn)傳輸鏈路的穩(wěn)定性會(huì)影響數(shù)據(jù)到達(dá)的效率,進(jìn)而導(dǎo)致報(bào)警實(shí)效降低。

          • 例如服務(wù)Updown狀態(tài),Api請(qǐng)求異常這類(lèi)報(bào)警我們都放在Shard節(jié)點(diǎn)進(jìn)行報(bào)警。


          本質(zhì)原因是,Prometheus 的本地存儲(chǔ)沒(méi)有數(shù)據(jù)同步能力,要在保證可用性的前提下,再保持?jǐn)?shù)據(jù)一致性是比較困難的,基礎(chǔ)的 HA Proxy 滿(mǎn)足不了要求,比如:

          • 集群的后端有 A 和 B 兩個(gè)實(shí)例,A 和 B 之間沒(méi)有數(shù)據(jù)同步。A 宕機(jī)一段時(shí)間,丟失了一部分?jǐn)?shù)據(jù),如果負(fù)載均衡正常輪詢(xún),請(qǐng)求打到A 上時(shí),數(shù)據(jù)就會(huì)異常。

          • 如果 A 和 B 的啟動(dòng)時(shí)間不同,時(shí)鐘不同,那么采集同樣的數(shù)據(jù)時(shí)間戳也不同,就不是多副本同樣數(shù)據(jù)的概念了

          • 就算用了遠(yuǎn)程存儲(chǔ),A 和 B 不能推送到同一個(gè) TSDB,如果每人推送自己的 TSDB,數(shù)據(jù)查詢(xún)走哪邊就是問(wèn)題了。


          因此解決方案是在存儲(chǔ)、查詢(xún)兩個(gè)角度上保證數(shù)據(jù)的一致:

          • 存儲(chǔ)角度:如果使用 Remote Write 遠(yuǎn)程存儲(chǔ), A 和 B后面可以都加一個(gè) Adapter,Adapter做選主邏輯,只有一份數(shù)據(jù)能推送到 TSDB,這樣可以保證一個(gè)異常,另一個(gè)也能推送成功,數(shù)據(jù)不丟,同時(shí)遠(yuǎn)程存儲(chǔ)只有一份,是共享數(shù)據(jù)。

          • 查詢(xún)角度:上邊的方案實(shí)現(xiàn)很復(fù)雜且有一定風(fēng)險(xiǎn),因此現(xiàn)在的大多數(shù)方案在查詢(xún)層面做文章,比如 Thanos 或者 Victoriametrics,仍然是兩份數(shù)據(jù),但是查詢(xún)時(shí)做數(shù)據(jù)去重和 Join。只是 Thanos 是通過(guò) Sidecar 把數(shù)據(jù)放在對(duì)象存儲(chǔ),Victoriametrics 是把數(shù)據(jù) Remote Write 到自己的 Server 實(shí)例,但查詢(xún)層 Thanos-Query 和 Victor 的 Promxy的邏輯基本一致。


          存儲(chǔ)方案:https://blog.timescale.com/blog/prometheus-ha-postgresql-8de68d19b6f5/

          我們采用了 Thanos 來(lái)支持多地域監(jiān)控?cái)?shù)據(jù)。

          高可用 Prometheus:Thanos 實(shí)踐:
          http://www.xuyasong.com/?p=1925

          容器日志與事件

          本文主要是 Prometheus 監(jiān)控內(nèi)容, 這里只簡(jiǎn)單介紹下 K8S 中的日志、事件處理方案,以及和 Prometheus 的搭配。

          日志處理:

          • 日志采集與推送:一般是Fluentd/Fluent-Bit/Filebeat等采集推送到 ES、對(duì)象存儲(chǔ)、kafaka,日志就該交給專(zhuān)業(yè)的 EFK 來(lái)做,分為容器標(biāo)準(zhǔn)輸出、容器內(nèi)日志。

          • 日志解析轉(zhuǎn) metric:可以提取一些日志轉(zhuǎn)為 Prometheus 格式的指標(biāo),如解析特定字符串出現(xiàn)次數(shù),解析 Nginx 日志得到 QPS 、請(qǐng)求延遲等。常用方案是 mtail 或者 grok


          日志采集方案:

          • sidecar 方式:和業(yè)務(wù)容器共享日志目錄,由 sidecar 完成日志推送,一般用于多租戶(hù)場(chǎng)景。

          • daemonset 方式:機(jī)器上運(yùn)行采集進(jìn)程,統(tǒng)一推送出去。


          需要注意的點(diǎn):對(duì)于容器標(biāo)準(zhǔn)輸出,默認(rèn)日志路徑是/var/lib/docker/containers/xxx, kubelet 會(huì)將改日志軟鏈到/var/log/pods,同時(shí)還有一份/var/log/containers 是對(duì)/var/log/pods的軟鏈。不過(guò)不同的 K8S 版本,日志的目錄格式有所變化,采集時(shí)根據(jù)版本做區(qū)分:

          • 1.15 及以下:/var/log/pods/{pod_uid}/

          • 1.15 以上:var/log/pods/{pod_name+namespace+rs+uuid}/


          事件:在這里特指 K8S Events,Events 在排查集群?jiǎn)栴}時(shí)也很關(guān)鍵,不過(guò)默認(rèn)情況下只保留 1h,因此需要對(duì) Events 做持久化。一般 Events 處理方式有兩種:

          • 使用 kube-eventer 之類(lèi)的組件采集 Events 并推送到 ES

          • 使用 event_exporter 之類(lèi)的組件將Events 轉(zhuǎn)化為 Prometheus Metric,同類(lèi)型的還有谷歌云的 stackdriver 下的 event-exporter


          kube-eventer :https://github.com/AliyunContainerService/kube-eventer
          event_exporter:https://github.com/caicloud/event_exporter
          event-exporter:
          https://github.com/GoogleCloudPlatform/k8s-stackdriver/tree/master/event-exporter

          >>>>

          參考資料


          • https://tech.meituan.com/2018/11/01/cat-in-depth-java-application-monitoring.html

          • https://dbaplus.cn/news-134-1462-1.html

          • https://www.infoq.cn/article/P3A5EuKl6jowO9v4_ty1

          • https://zhuanlan.zhihu.com/p/60791449

          • http://download.xuliangwei.com/jiankong.html#0-%E7%9B%91%E6%8E%A7%E7%9B%AE%E6%A0%87

          • https://aleiwu.com/post/prometheus-bp/

          • https://www.infoq.cn/article/1AofGj2SvqrjW3BKwXlN

          • http://bos.itdks.com/e8792eb0577b4105b4c9d19eb0dd1892.pdf

          • https://www.infoq.cn/article/ff46l7LxcWAX698zpzB2

          • https://www.robustperception.io/putting-queues-in-front-of-prometheus-for-reliability

          • https://www.slideshare.net/cadaam/devops-taiwan-monitor-tools-prometheus

          • https://www.robustperception.io/how-much-disk-space-do-prometheus-blocks-use

          • https://www.imooc.com/article/296613

          • https://dzone.com/articles/what-is-high-cardinality

          • https://www.robustperception.io/cardinality-is-key

          • https://www.robustperception.io/using-tsdb-analyze-to-investigate-churn-and-cardinality

          • https://blog.timescale.com/blog/prometheus-ha-postgresql-8de68d19b6f5/

          • https://asktug.com/t/topic/2618

          往期資源回顧 需要可自取

          推薦閱讀

          點(diǎn)個(gè)[在看],是對(duì)杰哥最大的支持!
          瀏覽 100
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  无码熟妇人妻AV在线电影 | 国产成人精品一级毛片 | 亚州的图五月丁香婷婷 | 色网站在线 | 久久久久久黄色片 |