7.1 Prometheus與服務發現
在基于云(IaaS或者CaaS)的基礎設施環境中用戶可以像使用水、電一樣按需使用各種資源(計算、網絡、存儲)。按需使用就意味著資源的動態性,這些資源可以隨著需求規模的變化而變化。例如在AWS中就提供了專門的AutoScall服務,可以根據用戶定義的規則動態地創建或者銷毀EC2實例,從而使用戶部署在AWS上的應用可以自動的適應訪問規模的變化。
這種按需的資源使用方式對于監控系統而言就意味著沒有了一個固定的監控目標,所有的監控對象(基礎設施、應用、服務)都在動態的變化。對于Nagias這類基于Push模式傳統監控軟件就意味著必須在每一個節點上安裝相應的Agent程序,并且通過配置指向中心的Nagias服務,受監控的資源與中心監控服務器之間是一個強耦合的關系,要么直接將Agent構建到基礎設施鏡像當中,要么使用一些自動化配置管理工具(如Ansible、Chef)動態的配置這些節點。當然實際場景下除了基礎設施的監控需求以外,我們還需要監控在云上部署的應用,中間件等等各種各樣的服務。要搭建起這樣一套中心化的監控系統實施成本和難度是顯而易見的。
而對于Prometheus這一類基于Pull模式的監控系統,顯然也無法繼續使用的static_configs的方式靜態的定義監控目標。而對于Prometheus而言其解決方案就是引入一個中間的代理人(服務注冊中心),這個代理人掌握著當前所有監控目標的訪問信息,Prometheus只需要向這個代理人詢問有哪些監控目標控即可, 這種模式被稱為服務發現。
在不同的場景下,會有不同的東西扮演者代理人(服務發現與注冊中心)這一角色。比如在AWS公有云平臺或者OpenStack的私有云平臺中,由于這些平臺自身掌握著所有資源的信息,此時這些云平臺自身就扮演了代理人的角色。Prometheus通過使用平臺提供的API就可以找到所有需要監控的云主機。在Kubernetes這類容器管理平臺中,Kubernetes掌握并管理著所有的容器以及服務信息,那此時Prometheus只需要與Kubernetes打交道就可以找到所有需要監控的容器以及服務對象。Prometheus還可以直接與一些開源的服務發現工具進行集成,例如在微服務架構的應用程序中,經常會使用到例如Consul這樣的服務發現注冊軟件,Promethues也可以與其集成從而動態的發現需要監控的應用服務實例。除了與這些平臺級的公有云、私有云、容器云以及專門的服務發現注冊中心集成以外,Prometheus還支持基于DNS以及文件的方式動態發現監控目標,從而大大的減少了在云原生,微服務以及云模式下監控實施難度。
如上所示,展示了Push系統和Pull系統的核心差異。相較于Push模式,Pull模式的優點可以簡單總結為以下幾點:
- 只要Exporter在運行,你可以在任何地方(比如在本地),搭建你的監控系統;
- 你可以更容易的查看監控目標實例的健康狀態,并且可以快速定位故障;
- 更利于構建DevOps文化的團隊;
- 松耦合的架構模式更適合于云原生的部署環境。
7.2 基于文件的服務發現
前面我們配置監控任務都是直接在Prometheus的配置文件中添加配置信息,然后重啟Prometheus。這里有兩個問題,一是有大量的任務的時候,一個Prometheus的配置文件變得很大,難以維護;二是每次的修改都要重啟Prometheus,非常麻煩。基于文件的服務發現就是解決這兩個問題的。
在Prometheus支持的眾多服務發現的實現方式中,基于文件的服務發現是最通用的方式。這種方式不需要依賴于任何的平臺或者第三方服務。對于Prometheus而言也不可能支持所有的平臺或者環境。通過基于文件的服務發現方式下,Prometheus會定時從文件(json或者yaml格式)中讀取最新的Target信息,因此,你可以通過任意的方式將監控Target的信息寫入即可。
要定義文件發現服務非常簡單,只需要在配置文件中添加對應的標簽:
file_sd_configs:
- files:
- yourfile.yml
比如,我要把我之前監控的node exporter獨立到一個配置文件里面,我這么配置:
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['192.168.113.52:9090']
#采集node exporter監控數據
- job_name: node_exporter
file_sd_configs:
- files: ['/usr/local/prometheus/sd_config/node_exporter.yml']
上面我們定義了自動發現的配置,node_exporter這個任務的具體配置會從定義的文件中讀取,默認每5分鐘讀取一次。我們新建這樣的一個文件。
mkdir /usr/local/prometheus/sd_config
vim /usr/local/prometheus/sd_config/node_exporter.yml
yml文件里面定義了三個監控目標
- targets: ['192.168.113.52:9100']
- targets: ['192.168.113.70:9100']
- targets: ['192.168.1.174:9100']
然后重啟Prometheus,讓配置生效。在web頁面上我們可以看到這個監控任務
然后,我們修改下node_exporter.yml,給兩個目標增加標簽,5分鐘后查看Prometheus有沒有自動更新這些配置:
- targets: ['192.168.113.52:9100']
labels:
instance: prometheus02-192.168.113.52
- targets: ['192.168.113.70:9100']
labels:
instance: docker01-192.168.113.70
- targets: ['192.168.1.174:9100']
5分鐘后,我們看到 Labels 這一欄,明顯發生了變化,也就是說我們的配置被自動加載進去了,如果要加快刷新的頻率,可以修改Prometheus的配置文件:
scrape_configs:
#采集node exporter監控數據
- job_name: node_exporter
- refresh_interval: 1m
file_sd_configs:
- files: ['/usr/local/prometheus/sd_config/node_exporter.yml']
7.3 基于Consul的服務發現
上面介紹的服務發現是基于文件的,如果我有多個Prometheus那就是要維護多套的配置文件了,這樣似乎不夠智能。有沒有一種像,zookeeper那樣的注冊中心呢?Prometheus只要定期從注冊中心獲取信息即可。
在Prometheus技術棧里面,使用的工具是Consul。具體使用不做介紹,可以查看原文點我。
7.4 服務發現與Relabel
在上面的基礎上有個更加難搞的需求,那就是線上環境有多套的集群比如:dev, stage, prod。不同的團隊要采集的集群是不一樣的,有沒有什么方法可以過濾這些不同的信息么?或者說有什么方法可以給這些集群打標簽呢?
這里使用的是 Prometheus的Relabeling機制,具體的介紹和使用參考原文點我