天天看點

多叢集thanos sidecar+MinIO監控告警實踐

作者:崔亮的部落格

項目環境

為保障業務高可用,業務使用了多個網絡營運商的機房線路,每個機房均部署一套k8s環境,故而有多個k8s叢集,每個k8s叢集環境上運作的服務基本一緻。原來監控體系存在以下問題:

配置管理混亂:先前使用Prometheus-operator部署管理監控告警,但是每個叢集存在個别差異,導緻每次調整告警時需要逐個修改配置檔案,建立ServiceMonitor對象,才能完成Prometheus監控項添加。操作較為繁瑣,沒有統一管理。

無法統一查詢:每個叢集部署一套Prometheus,當需要查詢資料時,隻能在特定叢集的Prometheus上查詢資料。或者在grafana建立多個Prometheus的資料源,通過使用不同的資料源查詢資料,缺少所有Prometheus資料統一查詢的入口功能。

曆史資料存儲:先前Prometheus的曆史監控資料,隻能通過挂載pv方式持久化,每天監控資料量較大,存儲政策隻能設定為保留1個月。

運作環境

除了snmp exporter和ipmi exporter實體機部署外,其餘元件均部署在k8s叢集上。

每個叢集均部署sidecar、query、store gateway、compact、rule元件,其中一個叢集部署了Alertmanager、全局thanos-query、minIO元件。

元件版本

元件 版本
k8s 1.19.X
Alertmanager 0.24.0
thanos 0.26.0
prometheus 2.36.0
node exporter 1.3.1
blackbox exporter 0.21.0
elasticsearch exporter 1.3.0
kafka exporter 1.4.2
process exporter 0.7.10
ipmi exporter 1.5.1
snmp exporter 0.20.0

整體架構

多叢集thanos sidecar+MinIO監控告警實踐

告警架構.drawio.png

實作目标

配置檔案統一

所有叢集使用同一個告警和規則配置,當需要修改規則時,使用ansible paly統一推送并reload服務即可。

全局統一查詢

grafana隻需要配置一個Prometheus資料源,不同叢集通過label标簽區分。使用thanos-query全局查詢所有Prometheus監控資料。

曆史資料長期保留

監控資料留存三個月以上,用于同比分析對比監控名額。

方案選型

Thanos還是VictoriaMetrics

在VictoriaMetrics官方文檔列出了與thanos的差別。總結來說,

寫入方式:VictoriaMetrics隻能通過标準的 remote_write API 接收來自 Prometheus 執行個體寫入的資料然後持久化存儲,而thanos既可以使用sidecar将資料上傳對象存儲,也支援receiver模式遠端寫入。

全局查詢:VictoriaMetrics内置全局查詢視圖,Prometheus将資料寫入遠端存儲後就可以使用全局查詢,而thanos需要依賴store gateway、sidecar、query元件才能實作查詢。

部署難度:thanos部署難度比VictoriaMetrics更高,使用元件也更多。

存儲方式:thanos使用對象存儲,VictoriaMetrics使用塊存儲存儲。

使用習慣:thanos基于Prometheus開發,web界面風格和操作邏輯與Prometheus基本相同,更容易上手使用。

由于當初做技術選型時,thanos是較為主流的解決方案,社群活躍,文檔更豐富,是以選擇了thanos。但是目前VictoriaMetrics發展勢頭也不容小觑,也可以作為技術方案備選。例如開源的夜莺監控告警平台,就使用VictoriaMetrics作為解決方案。

thanos部署方式

Prometheus-operator:叢集中安裝了 prometheus-operator 後,就可以通過建立 CRD 對象來部署 Thanos,但是部署和使用多了一層封裝,屏蔽了許多底層細節,不利于後期更改。

helm charts:helm倉庫有多個版本,都可以實作一鍵部署,但需要修改大量變量。

kube-thanos:Thanos 官方的開源項目,包含部署 thanos 到 kubernetes 的 yaml 示例,資源檔案較多,具有較高的使用門檻。

此處選擇kube-thanos方式直接配置yaml檔案部署,因為直接使用 kubernetes 的 yaml 資源檔案部署更直覺,也更容易做自定義配置,當我們對 thanos 了解透徹後,可以靈活根據實際場景做架構和配置的調整。

對象存儲選擇

thanos支援的存儲如下表

Provider Maturity Aimed For Auto-tested on CI Maintainers
Google Cloud Storage Stable Production Usage yes @bwplotka
AWS/S3(and all S3-compatible storages e.g disk-based Minio) Stable Production Usage yes @bwplotka
Azure Storage Account Stable Production Usage no @vglafirov
OpenStack Swift Beta (working PoC) Production Usage yes @FUSAKLA
Tencent COS Beta Production Usage no @jojohappy,@hanjm
AliYun OSS Beta Production Usage no @shaulboozhiao,@wujinhu
Local Filesystem Stable Testing and Demo only yes @bwplotka

如果是公有雲服務,那就無腦選擇騰訊或阿裡的對象存儲即可,畢竟資料無價。存儲裡的水很深,一般人把持不住。難的不是部署搭建,而是服務異常如何解決問題,如何恢複資料,所有如果項目在公有雲的話,直接花錢買服務就行。

如果是自建IDC機房,私有雲使用,可以使用的對象存儲有MinIO和ceph的RGW可供選擇。這裡的建議是如果有專門的存儲負責人維護ceph存儲,那就首選ceph。如果是自己維護使用,對存儲不太熟悉,那就選minIO,相較ceph,minIO的使用門檻更低。

sidecar模式還是receiver模式

在先前的版本,receive一直是beat模式,近期的版本才穩定下來,可以在生産環境使用。使用sidecar還是receive模式,主要就看你的query元件和Prometheus離得遠不遠。

Sidecar和Receiver功能相似,都是擷取prometheus的資料給thanos。差別在于近期資料的查詢,sidecar采用邊車模式讀取prometheus資料,預設最近2H的資料都在Prometheus裡面,而receiver相當于存儲服務,prometheus的進群資料都随時寫入到了Receiver中。

如果你的 Query 跟 Sidecar 離的比較遠,比如 Sidecar  分布在多個資料中心,Query 向所有 Sidecar 查資料,速度會很慢,這種情況可以考慮用 Receiver,将資料集中吐到  Receiver,然後 Receiver 與 Query 部署在一起,Query 直接向 Receiver 查最新資料,提升查詢性能。

我們剛開始也是用receiver模式,但是發現随着叢集和節點的增加,資料量激增,整個thanos架構的壓力全在receiver節點上,非常消耗資源,重新開機一個receiver pod需要30分鐘以上,最後換回sidecar模式,都是國内節點,雖然跨機房和地域,但是查詢延遲并不是很大。

rule元件告警還是prometheus告警

直接使用 Prometheus 自帶的 rule 功能  (生成新名額+告警),當生成告警後直接推送至alertmanager,這種方式資源消耗最小,而且中間的資料鍊路較少,不會因為thanos某一元件異常導緻告警失敗的情況發生,但是如果每個叢集部署多套Prometheus的話,需要在alertmanager做重複告警抑制。

使用thanos-rule的話,他去定期查詢thanos-query的接口資料,計算是否生成告警,并推送給alertmanager。除此之外還可以根據規則配置計算新名額并存儲,同時,還可以将資料上傳到對象存儲以供長期儲存。由于rule元件實作了多Prometheus副本重複告警的屏蔽,是以就不需要在alertmanager做告警抑制了。

經驗分享

關于minio

thanos隻會對曆史資料壓縮降低采樣率,并不會删除指定天數前資料,需要在minio設定bucket資料保留天數。

多叢集thanos sidecar+MinIO監控告警實踐

image.png

跨叢集配置minio的endpoint位址時注意,最好将minio寫入位址使用vip做成高可用,minio的寫入接口屬于四層協定,而非七層。

minio的部署本文和yaml檔案不做涉及,大家可參考官網文檔(一定要看英文,中文版本有誤差)自行部署即可。

關于thanos-compact

當thanos使用了對象存儲後,我們就可以查詢較大時間範圍的監控資料,但是當時間範圍很大時,查詢的資料量也會很大,這會導緻查詢速度非常慢。通常在檢視較大時間範圍的監控資料時,我們并不需要那麼詳細的資料,隻需要看到大緻就行。Thanos Compact  這個元件應運而生,它讀取對象存儲的資料,對其進行壓縮以及降采樣再上傳到對象存儲,這樣在查詢大時間範圍資料時就可以隻讀取壓縮和降采樣後的資料,極大地減少了查詢的資料量,進而加速查詢。compact配置時主要關注如下幾個參數

- --retention.resolution-raw=7d # 指定原始資料存放時長
- --retention.resolution-5m=15d # 指定降采樣到資料點 5分鐘間隔的資料存放時長
- --retention.resolution-1h=30d # 指定降采樣到資料點 1小時間隔的資料存放時長      

它們的資料精細程度遞減,占用的存儲空間也是遞減,在生産環境配置時,這三個參數與minio的bucket保留天數一起決定了每個bucket資料占用空間。如果bucket占用空間較大,可嘗試調整compact的參數

多叢集thanos sidecar+MinIO監控告警實踐

image.png

關于多叢集标簽區分

當使用遠端存儲或叢集聯邦時,可以通過external_labels标簽區分不同的prometheus執行個體,所有名額都會帶這個額外标簽。在每個叢集部署一套prometheus叢集時,通過添加額外的cluster标簽來區分這個名額屬于哪個叢集。

external_labels:
  cluster: $(CLUSTER)
  prometheus_replica: $(CLUSTER)-$(POD_NAME)      
  • 使用thanos-query查詢時,效果如下所示:
多叢集thanos sidecar+MinIO監控告警實踐

image.png

  • 使用grafana時,記得添加cluster這個變量
多叢集thanos sidecar+MinIO監控告警實踐

image.png

關于grafana告警

雖然grafana告警配置友善,顯示更加直覺,但出現過由于MySQL服務異常,進而grafana異常,最終導緻grafana配置的告警沒有正常觸發的情況。

目前我們的告警配置政策是重要基礎告警和不需要經常調整門檻值的告警(例如服務是否正常運作,節點是否當機),交由Prometheus配置管理。

業務相關告警,門檻值經常變化,或者需要經常檢視名額變化的曆史情況,直覺反映業務性能名額的告警(網絡延遲,es活躍分片數等)以及es日志分析告警(例如日志500錯誤數量,逾時時間等),交由grafana配置管理,因為告警值經常變化,配置修改較為友善。

需要注意的是grafana的告警沒有額外标簽這個配置項,是以當配置grafana告警時,可以通過指定tag的方式,手動添加cluster标簽。

多叢集thanos sidecar+MinIO監控告警實踐

image.png

關于告警配置管理

在編寫告警規則時,記得告警規則通過​

​{{$labels.cluster}}​

​擷取每個告警所屬叢集,生成的告警内容如下所示:

多叢集thanos sidecar+MinIO監控告警實踐

image.png

告警配置管理目前的整體思路是所有prometheus和grafana的告警都接入alertmanager,然後通過webhook推送至事件平台建立工單,根據告警組和等級調用不同的告警媒介。所有告警通過alertmanager做統一的告警分組,抑制和靜默操作。但是alertmanager缺乏一個曆史告警的記錄功能,于是我們使用webhook功能,當有告警産生,推送到事件平台的過程中,通過webhook程式記錄告警詳細資訊并存入資料庫。通過grafana作圖顯示目前和曆史告警資訊表格。

後期規劃開發告警事件處理平台,功能子產品如下所示:

多叢集thanos sidecar+MinIO監控告警實踐

告警平台體系-功能子產品.drawio.png

關于全局查詢

每個叢集一套thanos元件,叢集内部的query通過 dns srv  做服務發現。查詢多個叢集的資料時,單獨再部署一個全局的thanos-query,然後将各個叢集的query元件grpc端口通過NodePort暴露出來,這個全局query的 store api 位址就寫各叢集的 query 的grpc暴露的NodePort位址。

- name: thanos-query-global
  args:
  - query
  - --log.level=debug
  - --query.auto-downsampling
  - --grpc-address=0.0.0.0:10901
  - --http-address=0.0.0.0:9090
  - --query.partial-response
  - --query.replica-label=prometheus_replica
  - --store=192.168.10.30:30030
  - --store=192.168.10.31:30030
  - --store=192.168.10.32:30030
  - --store=192.168.20.30:30030
  - --store=192.168.20.31:30030
  - --store=192.168.20.32:30030      

配置好全局thanos-query後,不僅可以檢視所有的監控名額,還可以檢視所有prometheus的alerts、targets、rules資訊

多叢集thanos sidecar+MinIO監控告警實踐

image.png

關于黑盒監測

如果網絡探測資源較少,可手動指定靜态targets ,當資源較多時,推薦基于Consul實作Prometheus的自動發現功能配置。監控所有tcp ipmi ssl資源的監控,可參考開源項目https://github.com/starsliao/ConsulManager

關于網絡監控

網絡監控主要snmp trap(異常事件)、syslog(全部日志)、ping(IP+端口網絡存活監控)、snmp get(流量采集、cup、記憶體)、net flow流量采集分析五個方面。除了net flow通過網管工具檢視分析外,其餘均建議監控。

  1. ping監測使用blackbox exporter定期抓取名額即可。
  2. snmp get資訊通過snmp export配置交換機位址,監控項即可擷取到。
  3. 網絡裝置的syslog日志統一發送到rsyslog伺服器,如果有es叢集的話,使用logstash讀取rsyslog日志,然後寫入es叢集,最後使用grafana作圖,展示日志關鍵字段資訊;或者自己開發exporter,通過正則比對過濾的方式,當日志中存在關鍵字資訊時,輸出一個異常問題的名額,由Prometheus抓取,并判斷是否觸發告警。
  4. snmp exporter官方暫時沒有計劃支援snmp trap,需要mib庫翻譯,可以借助較為成熟的zabbix插件翻譯的生成日志。思路如下:
  • 部署snmptrap伺服器,配置網絡裝置将trap資訊發送到這台伺服器上;
  • 在snmp trap伺服器上安裝snmptrapd和snmptt工具,snmptrapd負責接受snmptrap資訊,snmptt負責翻譯snmp并寫入到日志檔案,然後将日志檔案發送到rsyslog伺服器中;
  • 由logstash讀取rsyslog日志并存入es,最終由grafana作圖配置告警。

yaml資源清單檔案

github

​​https://github.com/cuiliang0302/thanos-install​​

gitee

​​https://gitee.com/cuiliang0302/thanos-install​​

注意事項

由于資源清單中存在敏感資訊,已進行脫敏替換,是以yaml資源清單并不能直接apply建立,參考readme.md檔案,按實際情況進行修改後建立。

參考文檔

VictoriaMetrics官方文檔,與thanos差別:https://docs.victoriametrics.com/FAQ.html?highlight=thanos#what-is-the-difference-between-victoriametrics-and-thanos

thanos與VictoriaMetrics對比:https://icloudnative.io/posts/comparing-thanos-to-victoriametrics-cluster/

thanos支援的存儲類型:https://thanos.io/v0.27/thanos/storage.md/

滴滴夜莺使用VictoriaMetrics長期存儲:https://n9e.github.io/docs/install/victoria/

Zabbix監控裝置SNMP Trap消息:https://cloud.tencent.com/developer/article/1784442

prometheus告警規則模闆:https://awesome-prometheus-alerts.grep.to/