參考文檔:https://www.kubernetes.org.cn/7217.html
prometheus高可用方案
prometheus
官方的高可用有幾種方案:
- HA:即兩套
prometheus
採集完全一樣的數據,外邊掛負載均衡 - HA + 遠程存儲:除了基礎的多副本
prometheus
,還通過Remote write
寫入到遠程存儲,解決存儲持久化問題 - 聯邦集羣:即
federation
,按照功能進行分區,不同的shard
分點採集不同的數據,由Global
節點來統一存放,解決監控數據規模的問題。
使用官方建議的多副本 + 聯邦仍然會遇到一些問題,本質原因是prometheus
的本地存儲沒有數據同步能力,要在保證可用性的前提下再保持數據一致性是比較困難的,基本的多副本 proxy
滿足不了要求,比如:
prometheus
集羣的後端有 A 和 B 兩個實例,A 和 B 之間沒有數據同步。A 宕機一段時間,丟失了一部分數據,如果負載均衡正常輪詢,請求打到A 上時,數據就會異常。- 如果 A 和 B 的啓動時間不同,時鐘不同,那麼採集同樣的數據時間戳也不同,就多副本的數據不相同
- 就算用了遠程存儲,A 和 B 不能推送到同一個
tsdb
,如果每人推送自己的tsdb
,數據查詢走哪邊就是問題 - 官方建議數據做
Shard
分點,然後通過federation
來實現高可用,但是邊緣節點和Global
節點依然是單點,需要自行決定是否每一層都要使用雙節點重複採集進行保活。也就是仍然會有單機瓶頸。 - 另外部分敏感報警儘量不要通過
global
節點觸發,畢竟從Shard
節點到Global
節點傳輸鏈路的穩定性會影響數據到達的效率,進而導致報警實效降低。
目前大多數的 prometheus
的集羣方案是在存儲、查詢兩個角度上保證數據的一致:
- 存儲角度:如果使用
remote write
遠程存儲, A 和 B後面可以都加一個adapter
,adapter
做選主邏輯,只有一份數據能推送到tsdb
,這樣可以保證一個異常,另一個也能推送成功,數據不丟,同時遠程存儲只有一份,是共享數據。方案可以參考這篇文章 - 存儲角度:仍然使用
remote write
遠程存儲,但是 A 和 B 分別寫入tsdb1
和tsdb2
兩個時序數據庫,利用sync
的方式在tsdb1
和2
之前做數據同步,保證數據是全量的。 - 查詢角度:上邊的方案需要自己實現,有侵入性且有一定風險,因此大多數開源方案是在查詢層面做文章,比如
thanos
或者victoriametrics
,仍然是兩份數據,但是查詢時做數據去重和join
。只是thanos
是通過sidecar
把數據放在對象存儲,victoriametrics
是把數據remote write
到自己的server
實例,但查詢層thanos-query
和victor
的promxy
的邏輯基本一致,都是爲全局視圖服務
實際需求:
隨着集羣規模越來越大,監控數據的種類和數量也越來越多:如master/node
機器監控、進程監控、4 大核心組件的性能監控,pod
資源監控、kube-stats-metrics
、k8s events
監控、插件監控等等。除了解決上面的高可用問題,還希望基於 prometheus
構建全局視圖,主要需求有:
- 長期存儲:1 個月左右的數據存儲,每天可能新增幾十G,希望存儲的維護成本足夠小,有容災和遷移。考慮過使用 influxdb,但influxdb沒有現成的集羣方案,且需要人力維護。最好是存放在雲上的 tsdb 或者對象存儲、文件存儲上。
- 無限拓展:我們有300+集羣,幾千節點,上萬個服務,單機prometheus無法滿足,且爲了隔離性,最好按功能做 shard,如 master 組件性能監控與 pod 資源等業務監控分開、主機監控與日誌監控也分開。或者按租戶、業務類型分開(實時業務、離線業務)。
- 全局視圖:按類型分開之後,雖然數據分散了,但監控視圖需要整合在一起,一個 grafana 裏 n個面板就可以看到所有地域+集羣+pod 的監控數據,操作更方便,不用多個 grafana 切來切去,或者 grafana中多個 datasource 切來切去。
- 無侵入性:不要對已有的 prometheus 做過多的修改,因爲 prometheus 是開源項目,版本也在快速迭代,我們最早使用過 1.x,可1.x 和 2.x的版本升級也就不到一年時間,2.x 的存儲結構查詢速度等都有了明顯提升,1.x 已經沒人使用了。因此我們需要跟着社區走,及時迭代新版本。因此不能對 prometheus 本身代碼做修改,最好做封裝,對最上層用戶透明。
在調研了大量的開源方案(cortex/thanos/victoria/…)和商業產品之後,我們選擇了 thanos,準確的說,thanos只是監控套件,與 原生prometheus 結合,滿足了長期存儲+ 無限拓展 + 全局視圖 + 無侵入性的需求。
簡單配置部署
Thanos是一組組件,在官網上可以看到包括:
- Bucket
- Check
- Compactor
- Query
- Rule
- Sidecar
- Store
除了官方提到的這些,其實還有:
- receive
- downsample
看起來組件很多,但其實部署時二進制只有一個,非常方便。只是搭配不同的參數實現不同的功能,如 query 組件就是 ./thanos query,sidecar 組件就是./thanos sidecar,組件all in one,代碼只有一份,體積很小。
示例使用Thanos Sidecar,Store,Query三個組件。
第 1 步:確認已有的 prometheus
docker-compose運行的prometheus配置
prometheus:
image: prom/prometheus
volumes:
- ./prometheus/:/etc/prometheus/
- /usr/local/npg/prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention=35d'
- '--storage.tsdb.max-block-duration=2h'
- '--storage.tsdb.min-block-duration=2h'
- '--storage.tsdb.wal-compression'
- '--storage.tsdb.retention.time=2h'
- '--web.console.libraries=/usr/share/prometheus/console_libraries'
- '--web.console.templates=/usr/share/prometheus/consoles'
- '--web.enable-admin-api'
- '--web.enable-lifecycle'
links:
- "alertmanager"
ports:
- 9090:9090
restart: always
network_mode: "bridge"
web.enable-lifecycle一定要開,用於熱加載reload你的配置,retention保留 2 小時,prometheus 默認 2 小時會生成一個 block,thanos 會把這個 block 上傳到對象存儲。
對 prometheus 的要求:
- 2.2.1版本以上
- 聲明你的external_labels
- 啓用–web.enable-admin-api
- 啓用–web.enable-lifecycle
第 2 步:部署 sidecar 組件
Sidecar 組件作爲 Prometheus server 的 sidecar ,與 Prometheus server 部署於同一個 pod或主機 中。 他有兩個作用:
- 它使用Prometheus的remote read API,實現了Thanos的Store API。這使後面要介紹的Query 組件可以將Prometheus服務器視爲時間序列數據的另一個來源,而無需直接與Prometheus API交互(這就是 sidecar 的攔截作用)
- 可選配置:在Prometheus每2小時生成一次TSDB塊時,Sidecar將TSDB塊上載到對象存儲桶中。這使得Prometheus服務器可以以較低的保留時間運行,同時使歷史數據持久且可通過對象存儲查詢。
當然,這不意味着Prometheus可以是完全無狀態的,因爲如果它崩潰並重新啓動,您將丟失2個小時的指標,不過如果你的 prometheus 也是多副本,可以減少這2h 數據的風險。
sidecar配置:
thanos sidecar --tsdb.path /usr/local/npg/prometheus_data --prometheus.url http://localhost:9090 --objstore.config-file /root/config.yaml --http-address 0.0.0.0:19191 --grpc-address 0.0.0.0:19090
存儲配置文件爲/root/config.yaml,可以是共享對象存儲或者本地文件系統,這裏演示方便使用的是本地文件系統,文件內容如下:
[root@localhost ~]# cat config.yaml
type: FILESYSTEM
config:
directory: "/data"
第 3 步:部署 query 組件
sidecar 部署完成,可以安裝 query 組件
Query組件(也稱爲“查詢”)實現了Prometheus 的HTTP v1 API,可以像 prometheus 的 graph一樣,通過PromQL查詢Thanos集羣中的數據。
簡而言之,sidecar暴露了StoreAPI,Query從多個StoreAPI中收集數據,查詢並返回結果。Query是完全無狀態的,可以水平擴展。
query配置
thanos query --http-address 0.0.0.0:19192 --store localhost:19090 --store localhost:19914
store 參數代表的就是剛剛啓動的 sidecar 組件。
第 4 步:部署 store gateway 組件
在第 3 步裏,./thanos query有一條–store是 xxx:19914,這個 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=/store --objstore.config-file=/root/config.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=-1hg
因爲Store gateway需要從網絡上拉取大量歷史數據加載到內存,因此會大量消耗 cpu 和內存,這個組件也是 thanos 面世時被質疑過的組件,不過當前的性能還算可以,遇到的一些問題後面會提到。
Store gateway也可以無限拓展,拉取同一份 bucket 數據。
下圖是查找近1d的數據。可以超過2小時,證明sotre組件生效。
store顯示在query的web 頁面上