在prometheus 使用心得文章中有簡單提到prometheus 的高可用方案,嘗試了聯邦、remote write 以後,咱們最終選擇了 thanos 做爲監控配套組件,利用其全局視圖來管理咱們的多地域/上百個集羣的監控數據。本文主要介紹 thanos 的一些組件使用和心得體會。html
prometheus官方的高可用有幾種方案:node
使用官方建議的多副本 + 聯邦仍然會遇到一些問題,本質緣由是prometheus的本地存儲沒有數據同步能力,要在保證可用性的前提下再保持數據一致性是比較困難的,基本的多副本 proxy 知足不了要求,好比:git
目前大多數的 prometheus 的集羣方案是在存儲、查詢兩個角度上保證數據的一致:github
隨着咱們的集羣規模愈來愈大,監控數據的種類和數量也愈來愈多:如master/node 機器監控、進程監控、4 大核心組件的性能監控,pod 資源監控、kube-stats-metrics、k8s events監控、插件監控等等。除了解決上面的高可用問題,咱們還但願基於 prometheus 構建全局視圖,主要需求有:web
在調研了大量的開源方案(cortex/thanos/victoria/..)和商業產品以後,咱們選擇了 thanos,準確的說,thanos只是監控套件,與 原生prometheus 結合,知足了長期存儲+ 無限拓展 + 全局視圖 + 無侵入性的需求。sql
thanos 的默認模式:sidecar 方式docker
除了 這個sidecar 方式,thanos還有一種不太經常使用的reviver 模式,後面會提到。數據庫
Thanos是一組組件,在官網上能夠看到包括:json
除了官方提到的這些,其實還有:後端
看起來組件不少,但其實部署時二進制只有一個,很是方便。只是搭配不一樣的參數實現不一樣的功能,如 query 組件就是 ./thanos query,sidecar 組件就是./thanos sidecar,組件all in one,也就是代碼也只有一份,體積很小。
其實核心的sidecar+query就已經能夠運行,其餘的組件只是爲了實現更多的功能
最新版 thanos 在 這裏下載release,對於 thanos這種仍然在修bug、迭代功能的軟件,有新版本就不要用舊的。
下面會介紹如何組合thanos組件,來快速實現你的 prometheus 高可用,由於是快速介紹,和官方的 quick start有一部分雷同,且本文截止2020.1 月的版本,不知道之後會thanos 會迭代成什麼樣子
thanos 是無侵入的,只是上層套件,所以你仍是須要部署你的 prometheus,這裏再也不贅述,默認你已經有一個單機的 prometheus在運行,能夠是 pod 也能夠是主機部署,取決於你的運行環境,咱們是在 k8s 集羣外,所以是主機部署。prometheus採集的是地域A的監控數據。你的 prometheus配置能夠是:
啓動配置:
"./prometheus --config.file=prometheus.yml \ --log.level=info \ --storage.tsdb.path=data/prometheus \ --web.listen-address='0.0.0.0:9090' \ --storage.tsdb.max-block-duration=2h \ --storage.tsdb.min-block-duration=2h \ --storage.tsdb.wal-compression \ --storage.tsdb.retention.time=2h \ --web.enable-lifecycle"
web.enable-lifecycle必定要開,用於熱加載reload你的配置,retention保留 2 小時,prometheus 默認 2 小時會生成一個 block,thanos 會把這個 block 上傳到對象存儲。
採集配置:prometheus.yml
global: scrape_interval: 60s evaluation_interval: 60s external_labels: region: 'A' replica: 0 rule_files: scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['0.0.0.0:9090'] - job_name: 'demo-scrape' metrics_path: '/metrics' params: ...
這裏須要聲明external_labels,標註你的地域。若是你是多副本運行,須要聲明你的副本標識,如 0號,1,2 三個副本採集如出一轍的數據,另外2個 prometheus就能夠同時運行,只是replica值不一樣而已。這裏的配置和官方的 federation差很少。
對 prometheus 的要求:
關鍵的步驟來了,最核心莫過於 sidecar組件。sidecar是 k8s 中的一種模式
Sidecar 組件做爲 Prometheus server pod 的 sidecar 容器,與 Prometheus server 部署於同一個 pod 中。 他有兩個做用:
固然,這不意味着Prometheus能夠是徹底無狀態的,由於若是它崩潰並從新啓動,您將丟失2個小時的指標,不過若是你的 prometheus 也是多副本,能夠減小這2h 數據的風險。
sidecar配置:
./thanos sidecar \ --prometheus.url="http://localhost:8090" \ --objstore.config-file=./conf/bos.yaml \ --tsdb.path=/home/work/opdir/monitor/prometheus/data/prometheus/ "
配置很簡單,只須要聲明prometheus.url和數據地址便可。objstore.config-file是可選項。若是你要把數據存放在對象存儲(這也是推薦作法),就配置下對象存儲的帳號信息。
thanos 默認支持谷歌雲/AWS等,以 谷歌云爲例,配置以下:
type: GCS config: bucket: "" service_account: ""
由於thanos默認還不支持咱們的雲存儲,所以咱們在 thanos代碼中加入了相應的實現,並向官方提交了 pr。
須要注意的是:別忘了爲你的另外兩個副本 1號 和 2號prometheus都搭配一個 sidecar。若是是 pod運行能夠加一個 container,127 訪問,若是是主機部署,指定prometheus端口就行。
另外 sidecar是無狀態的,也能夠多副本,多個 sidecar 能夠訪問一份 prometheus 數據,保證 sidecar自己的拓展性,不過若是是 pod 運行也就沒有這個必要了,sidecar和prometheus 同生共死就好了。
sidecar 會讀取prometheus 每一個 block 中的 meta.json信息,而後擴展這個 json 文件,加入了 Thanos所特有的 metadata 信息。然後上傳到塊存儲上。上傳後寫入thanos.shipper.json 中
sidecar 部署完成了,也有了 3 個同樣的數據副本,這個時候若是想直接展現數據,能夠安裝 query 組件
Query組件(也稱爲「查詢」)實現了Prometheus 的HTTP v1 API,能夠像 prometheus 的 graph同樣,經過PromQL查詢Thanos集羣中的數據。
簡而言之,sidecar暴露了StoreAPI,Query從多個StoreAPI中收集數據,查詢並返回結果。Query是徹底無狀態的,能夠水平擴展。
配置:
" ./thanos query \ --http-address="0.0.0.0:8090" \ --store=relica0:10901 \ --store=relica1:10901 \ --store=relica2:10901 \ --store=127.0.0.1:19914 \ "
store 參數表明的就是剛剛啓動的 sidecar 組件,啓動了 3 份,就能夠配置三個relica0、relica一、relica2,10901 是 sidecar 的默認端口。
http-address 表明 query 組件自己的端口,由於他是個 web 服務,啓動後,頁面是這樣的:
和 prometheus 幾乎同樣對吧,有了這個頁面你就不須要關心最初的 prometheus 了,能夠放在這裏查詢。
點擊 store,能夠看到對接了哪些 sidecar。
query 頁面有兩個勾選框,含義是:
你可能注意到了,在第 3 步裏,./thanos query有一條--store是 xxx:19914,並非一直提到的 3 副本,這個 19914 就是接下來要說的store gateway組件。
在第 2 步的 sidecar 配置中,若是你配置了對象存儲objstore.config-file,你的數據就會定時上傳到bucket 中,本地只留 2 小時,那麼要想查詢 2 小時前的數據怎麼辦呢?數據不被 prometheus 控制了,應該如何從 bucket 中拿回來,並提供如出一轍的查詢呢?
Store gateway 組件:Store gateway 主要與對象存儲交互,從對象存儲獲取已經持久化的數據。與sidecar同樣,Store gateway也實現了store api,query 組能夠從 store gateway 查詢歷史數據。
配置以下:
./thanos store \ --data-dir=./thanos-store-gateway/tmp/store \ --objstore.config-file=./thanos-store-gateway/conf/bos.yaml \ --http-address=0.0.0.0:19904 \ --grpc-address=0.0.0.0:19914 \ --index-cache-size=250MB \ --sync-block-duration=5m \ --min-time=-2w \ --max-time=-1h \
grpc-address就是store api暴露的端口,也就是query 中--store是 xxx:19914的配置。
由於Store gateway須要從網絡上拉取大量歷史數據加載到內存,所以會大量消耗 cpu 和內存,這個組件也是 thanos 面世時被質疑過的組件,不過當前的性能還算能夠,遇到的一些問題後面會提到。
Store gateway也能夠無限拓展,拉取同一份 bucket 數據。
放個示意圖,一個 thanos 副本,掛了多個地域的 store 組件
到這裏,thanos 的基本使用就結束了,至於 compact 壓縮和 bucket 校驗,不是核心功能,compact咱們只是簡單部署了一下,rule組件咱們沒有使用,就不作介紹了。
有了多地域多副本的數據,就能夠結合 grafana 作全局視圖了,好比:
按地域和集羣查看 etcd 的性能指標:
按地域、集羣、機器查看核心組件監控,如多副本 master 機器上的各類性能
數據聚合在一塊兒以後,能夠將全部視圖都集中展現,好比還有這些面板:
前面提到的全部組件都是基於 sidecar 模式配置的,但thanos還有一種Receive模式,不太經常使用,只是在Proposals中出現
由於一些網絡限制,咱們以前嘗試過Receive方案,這裏能夠描述下Receive的使用場景:
不過Receive畢竟不是默認方案,若是不是特別須要,仍是用默認的 sidecar 爲好
壓縮:官方文檔有提到,使用sidecar時,須要將 prometheus 的--storage.tsdb.min-block-duration 和 --storage.tsdb.max-block-duration,這兩個值設置爲2h,兩個參數相等才能保證prometheus關閉了本地壓縮,其實這兩個參數在 prometheus -help 中並無體現,prometheus 做者也說明這只是爲了開發測試才用的參數,不建議用戶修改。而 thanos 要求關閉壓縮是由於 prometheus 默認會以2,25,25*5的週期進行壓縮,若是不關閉,可能會致使 thanos 剛要上傳一個 block,這個 block 卻被壓縮中,致使上傳失敗。
不過你也沒必要擔憂,由於在 sidecar 啓動時,會堅持這兩個參數,若是不合適,sidecar會啓動失敗
store-gateway: store 組件資源消耗是最大的,畢竟他要拉取遠程數據,並加載到本地供查詢,若是你想控制歷史數據和緩存週期,能夠修改相應的配置,如
--index-cache-size=250MB \ --sync-block-duration=5m \ --min-time=-2w \ 最大查詢 1 周 --max-time=-1h \
store-gateway 默認支持索引緩存,來加快tsdb 塊的查找速度,但有時候啓動會佔用了大量的內存,在 0.11.0以後的版本作了修復,能夠查看這個issue
Prometheus 2.0 已經對存儲層進行了優化。例如按照時間和指標名字,連續的儘可能放在一塊兒。而 store gateway能夠獲取存儲文件的結構,所以能夠很好的將指標存儲的請求翻譯爲最少的 object storage 請求。對於那種大查詢,一次能夠拿成百上千個 chunks 數據。
二在 store 的本地,只有 index 數據是放入 cache的,chunk 數據雖然也能夠,可是就要大幾個數量級了。目前,從對象存儲獲取 chunk 數據只有很小的延時,所以也沒什麼動力去將 chunk 數據給 cache起來,畢竟這個對資源的需求很大。
store-gateway中的數據:
每一個文件夾中實際上是一個個的索引文件index.cache.json
prometheus數據愈來愈多,查詢必定會愈來愈慢,thanos提供了一個compactor組件來處理,他有兩個功能,
經過以上的方式,有效了優化查詢,可是並非萬能的。由於業務數據總在增加,這時候可能要考慮業務拆分了,咱們須要對業務有必定的估算,例如不一樣的業務存儲在不一樣bucket裏(須要改造或者多部署幾個 sidecar)。例若有5個bucket,再準備5個store gateway進行代理查詢。減小單個 store 數據過大的問題。
第二個方案是時間切片,也就是就是上面提到的store gateway能夠選擇查詢多長時間的數據。支持兩種表達,一種是基於相對時間的,例如--max-time 3d前到5d前的。一種是基於絕對時間的,19年3月1號到19年5月1號。例如想查詢3個月的數據,一個store代理一個月的數據,那麼就須要3個store來合做。
query組件啓動時,默認會根據query.replica-label字段作重複數據的去重,你也能夠在頁面上勾選deduplication 來決定。query 的結果會根據你的query.replica-label的 label選擇副本中的一個進行展現。可若是 0,1,2 三個副本都返回了數據,且值不一樣,query 會選擇哪個展現呢?
thanos會基於打分機制,選擇更爲穩定的 replica 數據, 具體邏輯在:https://github.com/thanos-io/...
本文爲容器監控實踐系列文章,完整內容見:container-monitor-book