天天看點

Thanos 架構

Thanos 架構

Kubernetes普羅米修斯技術棧

在為我們的客戶部署Kubernetes基礎設施時,在每個叢集上部署監控技術棧是标準做法。這個堆棧通常由幾個元件組成:

  • Prometheus:收集度量标準
  • 告警管理器:根據名額查詢向各種提供者發送警報
  • Grafana:可視化豪華儀表闆

簡化架構如下:

Thanos 架構

注意事項

這種架構有一些注意事項,當你想從其中擷取名額的叢集數量增加時,它的伸縮性以及可擴充性不太好。

多個Grafana

在這種設定中,每個叢集都有自己的Grafana和自己的一組儀表闆,維護起來很麻煩。

存儲名額資料是昂貴的

Prometheus将名額資料存儲在磁盤上,你必須在存儲空間和名額保留時間之間做出選擇。如果你想長時間存儲資料并在雲提供商上運作,那麼如果存儲TB的資料,塊存儲的成本可能會很高。同樣,在生産環境中,Prometheus經常使用複制或分片或兩者同時運作,這可能會使存儲需求增加兩倍甚至四倍。

解決方案

多個Grafana資料源

可以在外部網絡上公開Prometheus的端點,并将它們作為資料源添加到單個Grafana中。你隻需要在Prometheus外部端點上使用TLS或TLS和基本認證來實作安全性。此解決方案的缺點是不能基于不同的資料源進行計算。

Prometheus聯邦

Prometheus聯邦允許從Prometheus中抓取Prometheus,當你不抓取很多名額資料時,這個解決方案可以很好地工作。在規模上,如果你所有的Prometheus目标的抓取持續時間都比抓取間隔長,可能會遇到一些嚴重的問題。

Prometheus遠端寫

雖然遠端寫入是一種解決方案(也由Thanos receiver實作),但我們将不在本文中讨論“推送名額”部分。你可以在這裡[1]閱讀關于推送名額的利弊。建議在不信任多個叢集或租戶的情況下(例如在将Prometheus建構為服務提供時),将名額作為最後的手段。無論如何,這可能是以後文章的主題,但我們将在這裡集中讨論抓取。

Thanos,它來了

Thanos是一個“開源的,高可用的Prometheus系統,具有長期存儲能力”。很多知名公司都在使用Thanos,也是CNCF孵化項目的一部分。

Thanos的一個主要特點就是允許“無限”存儲空間。通過使用對象存儲(比如S3),幾乎每個雲提供商都提供對象存儲。如果在前提環境下運作,對象存儲可以通過rook或minio這樣的解決方案提供。

它是如何工作的?

Thanos和Prometheus并肩作戰,從Prometheus開始更新到Thanos是很常見的。Thanos被分成幾個元件,每個元件都有一個目标(每個服務都應該這樣:)),元件之間通過gRPC進行通信。

Thanos Sidecar

Thanos 架構

Thanos和Prometheus一起運作(有一個邊車),每2小時向一個對象存儲庫輸出Prometheus名額。這使得Prometheus幾乎是無狀态的。Prometheus仍然在記憶體中儲存着2個小時的路徑成本,是以在發生當機的情況下,你可能仍然會丢失2個小時的路徑成本(這個問題應該由你的Prometheus設定來處理,使用HA/分片,而不是Thanos)。

Thanos sidecar與Prometheus營運者和Kube Prometheus棧一起,可以輕松部署。這個元件充當Thanos查詢的存儲。

Thanos存儲

Thanos存儲充當一個網關,将查詢轉換為遠端對象存儲。它還可以在本地存儲上緩存一些資訊。基本上,這個元件允許你查詢對象存儲以擷取名額。這個元件充當Thanos查詢的存儲。

Thanos Compactor

Thanos Compactor是一個單例(它是不可擴充的),它負責壓縮和降低存儲在對象存儲中的名額。下采樣是随着時間的推移對名額粒度的寬松。例如,你可能想将你的名額保持2年或3年,但你不需要像昨天的名額那麼多資料點。這就是壓縮器的作用,它可以在對象存儲上節省位元組,進而節省成本。

Thanos Query

Thanos查詢是Thanos的主要元件,它是向其發送PromQL查詢的中心點。Thanos查詢暴露了一個與Prometheus相容的端點。然後它将查詢分派給所有的“stores”。記住,Store可能是任何其他提供名額的Thanos元件。Thanos查詢可以發送查詢到另一個Thanos查詢(他們可以堆疊)。

  • Thanos Store
  • Thanos Sidecar
  • Thanos Query

還負責對來自不同Store或Prometheus的相同名額進行重複資料删除。例如,如果你有一個路徑成本在Prometheus中,同時也在對象存儲中,Thanos Query可以對該名額值進行重複資料删除。在Prometheus HA設定的情況下,重複資料删除也基于Prometheus副本和分片。

Thanos Query Frontend

正如它的名字所暗示的,Thanos查詢前端是Thanos查詢的前端,它的目标是将大型查詢拆分為多個較小的查詢,并緩存查詢結果(在記憶體或memcached中)。

還有其他元件,比如在遠端寫的情況下接收Thanos,但這仍然不是本文的主題。

Thanos

之前在 大規模場景下 Prometheus 的優化手段 中,我們想盡 “千方百計” 才好不容易把 Prometheus 優化到适配大規模場景,部署和後期維護麻煩且複雜不說,還有很多不完美的地方,并且還無法滿足一些更進階的訴求,比如檢視時間久遠的監控資料,對于一些時間久遠不常用的 “冷資料”,最理想的方式就是存到廉價的對象存儲中,等需要查詢的時候能夠自動加載出來。

Thanos (沒錯,就是滅霸) 可以幫我們簡化分布式 Prometheus 的部署與管理,并提供了一些的進階特性:全局視圖,長期存儲,高可用。下面我們來詳細講解一下。

​​Thanos

Thanos 架構

https://thanos.io/​​是一個基于 Prometheus 實作的監控方案,其主要設計目的是解決原生 Prometheus 上的痛點,并且做進一步的提升,主要的特性有:全局查詢,高可用,動态拓展,長期存儲。下圖是 Thanos 官方的架構圖:

Thanos 架構

Thanos 主要由如下幾個特定功能的元件組成:(相當于微服務的模式,裡面有比較多的元件)

  • 邊車元件(Sidecar):連接配接 Prometheus,并把 Prometheus 暴露給查詢網關(Querier/Query),以供實時查詢,并且可以上傳 Prometheus 資料給雲存儲,以供長期儲存(相當于可以連接配接本地prometheus以及查詢器的)
  • 查詢網關(Querier/Query):實作了 Prometheus API,與彙集底層元件(如邊車元件 Sidecar,或是存儲網關 Store Gateway)的資料(可以去查詢sidecar裡面的資料,或者是程查詢存儲網關裡面的一個資料,有一部分的資料可能還在本地,因為sidecar還沒有将資料上傳上去,這個時候去查詢的時候會根據查詢時間會去路由到本地的sidecar,如果資料在遠端存儲上面,那麼就會從存儲網關上面去讀取)
  • 存儲網關(Store Gateway):将雲存儲中的資料内容暴露出來
  • 壓縮器(Compactor):将雲存儲中的資料進行壓縮和下采樣
  • 接收器(Receiver):從 Prometheus 的 remote-write WAL(Prometheus 遠端預寫式日志)擷取資料,暴露出去或者上傳到雲存儲(和sidecar是兩種不同的方式)
  • 規則元件(Ruler):針對監控資料進行評估和報警
  • Bucket:主要用于展示對象存儲中曆史資料的存儲情況,檢視每個名額源中資料塊的壓縮級别,解析度,存儲時段和時間長度等資訊。
  • 查詢前端:實作Prometheus的api,将其代理給query,同時緩存響應

從使用角度來看有兩種方式去使用 Thanos,sidecar模式和 receiver 模式。

sidecar架構模式

  1. Thanos Sidecar 元件需要和 Pormetheus 執行個體一起部署,用于代理 Thanos Querier 元件對本地 Prometheus 的資料讀取,允許 Querier 使用通用、高效的StoreAPI 查詢 Prometheus 資料。
  2. 第二是将 Prometheus 本地監控資料通過對象存儲接口上傳到對象存儲中,這個上傳是實時的,隻要發現有新的監控資料儲存到磁盤,會将這些監控資料上傳至對象存儲。下面是Sidecar模式架構圖。(一方面用于查詢本地資料,其次将本地資料存儲到遠端)
Thanos 架構

可以看到普羅米修斯有多個副本A,B,需要部署一個sidecar和Prometheus部署在一起,有多少個Prometheus副本就需要部署多少個sidecar。

當用戶端去查詢資料的時候(granfan或者自己的用戶端),會根據query來查詢結果(query實作了store api,store api會幫助我們去查詢結果),如果資料還在本地,因為比較新的資料,實時資料還是在本地的,sidecar是要等到Prometheus的資料存盤,兩個小時之後才能夠識别到,然後将兩個小時之後的資料上傳到遠端存儲上面,查詢的資料如果是兩個小時之後的話,會代理到store gateway這邊,資料從對象存儲當中拿就行了。(如果資料存盤超過兩個小時了,prometheus以塊的方式進行存儲,這個時候就會将TSDB block資料塊上傳到對象存儲上面去)

如果是兩個小時之前,實時最新的資料,那麼從sidecar中擷取。

最終的話,因為有兩個副本,thanos query會幫我們去做一個去重,那麼在grafana裡面查詢到的資料是沒有重複的。 

thanos compact其實也就是去做一些壓縮,這樣可以保證我們對象存儲當中的資料不是那麼大。 

Thanos Sidecar 元件在 Prometheus的遠端讀 API 之上實作了 Thanos 的Store API,這使得 Querier 可以将 Prometheus 伺服器視為時間序列資料的另一個來源,而無需直接與它的 API 進行互動。

(thanos query的資料來源可以是來源于存儲網關 thanos store gateway,從對象存儲中擷取,最新的實時的熱資料就從sidecar這邊擷取,sidecar和Prometheus對接一下就行了)

因為 Prometheus 每 2 小時生成一個時序資料塊,Thanos Sidecar 會每隔 2 小時将這個塊上傳到一個對象存儲桶中。這樣 Prometheus 伺服器就可以以相對較低的存儲空間運作,同時通過對象存儲提供曆史資料,使得監控資料具有持久性和可查詢性。但是這樣并不意味着 Prometheus 可以完全無狀态,因為如果 Prometheus 崩潰并重新啟動,我們将失去大約 2 個小時的名額資料,是以 Prometheus 在實際運作中還是需要持久性磁盤的。

receiver 架構模式

 Thanos Receiver 實作了 Prometheus 遠端寫 API,它建構在現有的 Prometheus TSDB 之上,并保持其實用性,同時通過長期存儲、水準可伸縮性和下采樣擴充其功能。Prometheus 執行個體被配置為連續地向它寫入名額,然後 Thanos Receiver 預設每 2 小時将時間序列格式的監控資料塊上傳到-個對象存儲的桶中。Thanos Receiver 同樣暴露了 Store API,以便 Thanos Querier 可以實時查詢接收到的名額。

Thanos 架構

之前是sidecar模式和Prometheus對接,然後将資料上傳到對象存儲上面去,而現在沒有一個元件直接上傳到對象存儲,而是通過thanos receiver,Prometheus有個遠端寫,可以将資料遠端寫入到thanos receiver裡面去,然後這個元件每隔兩個小時将資料上傳到對象存儲裡面。

Thanos 架構

查詢也是一樣,如果是兩個小時之前,也就是熱資料,那麼查詢到的也是receive裡面的資料,這裡沒有sidecar,是以最新的資料實在receive裡面了。

這種方式相對于之前更加輕量級一些,因為每個Prometheus server都得跟着sidecar,現在隻需要有個receive,但是看起來就對receive的壓力比較大了,壓力全部都到receiver上面去了。

這兩種模式有各種的優缺點,具體使用哪種模式需要結合生産環境綜合考慮。

工作流程 sidecar模式

Thanos 是同時支援 Prometheus 讀和寫的遠端存儲方案,首先我們先看下名額寫入的整個流程:

  • 首先 Prometheus 從所采集服務的 metrics 接口抓取名額資料,同時根據自身所配置的​

    ​recording rules​

    ​ 定期對抓取到的名額資料進行評估,将結果以 TSDB 格式分塊存儲到本地,每個資料塊的存儲時長為 2 小時,且預設禁用了壓縮功能。(每兩個小時會将資料存儲到tsdb的block裡面)
  • 然後​

    ​sidecar​

    ​​ 嗅探到 Prometheus 的資料存儲目錄生成了新的隻讀資料塊時,會将該資料塊上傳到對象存儲桶中做為長期曆史資料儲存,在上傳時會将資料塊中的​

    ​meta.json​

    ​​ 進行修改添加 thanos 相關的字段,如​

    ​external_labels(辨別哪個執行個體上傳的)​

    ​。
  • ​rule​

    ​​ 根據所配置的​

    ​recording rules​

    ​​ 定期地向​

    ​query​

    ​​ 發起查詢擷取評估所需的名額值,并将結果以 TSDB 格式分塊存儲到本地。每個資料塊的存儲時長為 2 小時,且預設禁用了壓縮功能,每個資料塊的​

    ​meta.json​

    ​​ 也附帶了 thanos 拓展的​

    ​external_lables​

    ​ 字段。當本地生成了新的隻讀資料塊時,其自身會将該資料塊上傳到遠端對象存儲桶中做為長期曆史資料儲存。
  • ​compact​

    ​​ 定期将對象存儲中地資料塊進行壓縮和降準采樣,進行壓縮時資料塊中的 truck 會進行合并,對應的​

    ​meta.json​

    ​​ 中的 level 也會一同增長,每次壓縮累加 1,初始值為 1。在進行降準采樣時會建立新的資料塊,根據采樣步長從原有的資料塊中抽取值存儲到新的資料塊中,在​

    ​meta.json​

    ​​ 中記錄​

    ​resolution​

    ​ 為采樣步長。

讀取名額的流程為:

  • 首先用戶端通過​

    ​query API​

    ​​ 向​

    ​query​

    ​​ 發起查詢,​

    ​query​

    ​​ 将請求轉換成​

    ​StoreAPI​

    ​​ 發送到其他的​

    ​query​

    ​​、​

    ​sidecar​

    ​​、​

    ​rule​

    ​​ 和​

    ​store​

    ​ 上。
  • ​sidecar​

    ​​ 接收到來自于​

    ​query​

    ​​ 發起的查詢請求後将其轉換成​

    ​query API​

    ​ 請求,發送給其綁定的 Prometheus,由 Prometheus 從本地讀取資料并響應,傳回短期的本地采集和評估資料。
  • ​rule​

    ​​ 接收到來自于​

    ​query​

    ​ 發起的查詢請求後直接從本地讀取資料并響應,傳回短期的本地評估資料。
  • ​store​

    ​​ 接收到來自于​

    ​query​

    ​​ 發起的查詢請求後首先從對象存儲桶中周遊資料塊的​

    ​meta.json​

    ​​,根據其中記錄的時間範圍和标簽先進行一次過濾。接下來從對象存儲桶中讀取資料塊的​

    ​index​

    ​​ 和​

    ​chunks​

    ​​ 進行查詢,部分查詢頻率較高的​

    ​index​

    ​ 會被緩存下來,下次查詢使用到時可以直接讀取。最終傳回長期的曆史采集和評估名額。

對于發送報警的流程如下所示:

  • Prometheus 根據自身配置的​

    ​alerting​

    ​ 規則定期地對自身采集的名額進行評估,當告警條件滿足的情況下發起告警到 Alertmanager 上。
  • ​rule​

    ​​ 根據自身配置的​

    ​alerting​

    ​​ 規則定期的向​

    ​query​

    ​ 發起查詢請求擷取評估所需的名額,當告警條件滿足的情況下發起告警到 Alertmanager 上。
  • Alertmanager 接收到來自于 Prometheus 和​

    ​rule​

    ​ 的告警消息後進行分組合并後發出告警通知。

特性

  • 統一查詢入口                以​

    ​Querier​

    ​​ 作為統一的查詢入口,其自身實作了 Prometheus 的查詢接口和​

    ​StoreAPI​

    ​​,可為其他的​

    ​Querier​

    ​​ 提供查詢服務,在查詢時會從每個 Prometheus 執行個體的​

    ​Sidecar​

    ​​ 和​

    ​Store Gateway​

    ​ 擷取到名額資料。
  • 查詢去重                       每個資料塊都會帶有特定的叢集标簽,​

    ​Querier​

    ​ 在做查詢時會去除叢集标簽,将名額名稱和标簽一緻的序列根據時間排序合并。雖然名額資料來自不同的采集源,但是隻會響應一份結果而不是多份重複的結果。(如果是Prometheus多個執行個體,同時去對名額資料進行采集,這樣就需要對資料去重,隻保留一份資料就行了,同一個時間點采樣的資料隻儲存一份即可)
  • 高空間使用率               每個 Prometheus 本身不存儲長時間的資料,​

    ​Sidecar​

    ​​ 會将 Prometheus 已經持久化的資料塊上傳到對象存儲中。​

    ​Compactor​

    ​ 會定時将遠端對象存儲中的長期資料進行壓縮,并且根據采樣時長做清理,節約存儲空間。(使用sidecar模式就需要保留很多資料,隻需要本地保留2個小時的資料,其餘的資料在對象存儲當中,如果需要儲存更長時間的資料,比如要查詢一周的資料,一個月内的資料,如果是之前單純的Prometheus,這樣要查詢曆史好久的資料Prometheus的壓力就非常大了,現在資料都在存儲當中)
  • 高可用​

    ​Querier​

    ​​ 是無狀态服務,天生支援水準拓展和高可用。​

    ​Store​

    ​​、​

    ​Rule​

    ​​ 和​

    ​Sidecar​

    ​ 是有狀态服務,在多副本部署的情況下也支援高可用,不過會産生資料備援,需要犧牲存儲空間。
  • 存儲長期資料               Prometheus 執行個體的​

    ​Sidecar​

    ​ 會将本地資料上傳到遠端對象存儲中作為長期資料
  • 橫向拓展                      當 Prometheus 的名額采集壓力過大時,可以建立新的 Prometheus 執行個體,将​

    ​scrape job​

    ​​ 拆分給多個 Prometheus,​

    ​Querier​

    ​ 從多個 Prometheus 查詢彙聚結果,降低單個 Prometheus 的壓力
  • 跨叢集查詢                  需要合并多個叢集的查詢結果時,僅需要在每個叢集的​

    ​Querier​

    ​​ 之上再添加一層​

    ​Querier​

    ​ 即可,這樣的層層嵌套,可以使得叢集規模無限制拓展。(可以将目前的query作為另外一個query的資料源)