本章節主要講自動發現使用場景介紹與Prometheus基於文件、DNS的自動發現配置.php
當咱們使用各種exporter分別對系統、數據庫和HTTP服務進行監控指標採集,對於全部監控指標對應的Target的運行狀態和資源使用狀況,都是用Prometheus的靜態配置功能 static_configs
來 手動添加主機IP和端口,而後重載服務讓Prometheus發現。數據庫
對於一組比較少的服務器的測試環境中,這種手動方式添加配置信息是最簡單的方法。可是實際生產環境中,對於成百上千的節點組成的大型集羣又或者Kubernetes這樣的大型集羣,很明顯,手動方式捉襟見肘了。爲此,Prometheus提早已經設計了一套服務發現功能。json
Prometheus 服務發現可以自動檢測分類,而且可以識別新節點和變動節點。也就是說,能夠在容器或者雲平臺中,自動發現並監控節點或更新節點,動態的進行數據採集和處理。目前 Prometheus 已經支持了不少常見的自動發現服務,好比 consul
ec2
gce
serverset_sd_config
openStack
kubernetes
等等。咱們經常使用的就是sd_config、DNS、kubernetes、consul這些足夠了。若是有須要其餘配置的探討,能夠與我交流,我能夠補上來。服務器
本章節中會對Prometheus自動發現中的基於文件、DNS進行發現講解,consul
在後面會單獨展開來說,如何可使其完美的解決當前場景下常見的各種服務發現監控。網絡
在基於雲(IaaS或者CaaS)的基礎設施環境中用戶能夠像使用水、電同樣按需使用各類資源(計算、網絡、存儲)。按需使用就意味着資源的動態性,這些資源能夠隨着需求規模的變化而變化。例如在AWS中就提供了專門的AutoScall服務,能夠根據用戶定義的規則動態地建立或者銷燬EC2實例,從而使用戶部署在AWS上的應用能夠自動的適應訪問規模的變化。架構
這種按需的資源使用方式對於監控系統而言就意味着沒有了一個固定的監控目標,全部的監控對象(基礎設施、應用、服務)都在動態的變化。對於Nagias這類基於Push模式傳統監控軟件就意味着必須在每個節點上安裝相應的Agent程序,而且經過配置指向中心的Nagias服務,受監控的資源與中心監控服務器之間是一個強耦合的關係,要麼直接將Agent構建到基礎設施鏡像當中,要麼使用一些自動化配置管理工具(如Ansible、Chef)動態的配置這些節點。固然實際場景下除了基礎設施的監控需求之外,咱們還須要監控在雲上部署的應用,中間件等等各類各樣的服務。要搭建起這樣一套中心化的監控系統實施成本和難度是顯而易見的。app
而對於Prometheus這一類基於Pull模式的監控系統,顯然也沒法繼續使用的static_configs的方式靜態的定義監控目標。而對於Prometheus而言其解決方案就是引入一箇中間的代理人(服務註冊中心),這個代理人掌握着當前全部監控目標的訪問信息,Prometheus只須要向這個代理人詢問有哪些監控目標控便可, 這種模式被稱爲服務發現。dom
Service-Disover在不一樣的場景下,會有不一樣的東西扮演者代理人(服務發現與註冊中心)這一角色。好比在AWS公有云平臺或者OpenStack的私有云平臺中,因爲這些平臺自身掌握着全部資源的信息,此時這些雲平臺自身就扮演了代理人的角色。Prometheus經過使用平臺提供的API就能夠找到全部須要監控的雲主機。在Kubernetes這類容器管理平臺中,Kubernetes掌握並管理着全部的容器以及服務信息,那此時Prometheus只須要與Kubernetes打交道就能夠找到全部須要監控的容器以及服務對象。Prometheus還能夠直接與一些開源的服務發現工具進行集成,例如在微服務架構的應用程序中,常常會使用到例如Consul這樣的服務發現註冊軟件,Promethues也能夠與其集成從而動態的發現須要監控的應用服務實例。除了與這些平臺級的公有云、私有云、容器雲以及專門的服務發現註冊中心集成之外,Prometheus還支持基於DNS以及文件的方式動態發現監控目標,從而大大的減小了在雲原生,微服務以及雲模式下監控實施難度。tcp
prom-pull-push如上所示,展現了Push系統和Pull系統的核心差別。相較於Push模式,Pull模式的優勢能夠簡單總結爲如下幾點:ide
只要Exporter在運行,你能夠在任何地方(好比在本地),搭建你的監控系統;
你能夠更容易的查看監控目標實例的健康狀態,而且能夠快速定位故障;
更利於構建DevOps文化的團隊;
鬆耦合的架構模式更適合於雲原生的部署環境。
在Prometheus支持的衆多服務發現的實現方式中,基於文件的服務發現是最通用的方式。這種方式不須要依賴於任何的平臺或者第三方服務。對於Prometheus而言也不可能支持全部的平臺或者環境。經過基於文件的服務發現方式下,Prometheus會定時從文件中讀取最新的Target信息,所以,你能夠經過任意的方式將監控Target的信息寫入便可。用戶能夠經過JSON或者YAML格式的文件,定義全部的監控目標。例如,在下面的yaml文件中分別定義了2個採集任務,以及每一個任務對應的Target列表:
yaml格式
- targets: ['192.168.1.220:9100']labels:app: 'app1'env: 'game1'region: 'us-west-2'- targets: ['192.168.1.221:9100']labels:app: 'app2'env: 'game2'region: 'ap-southeast-1'
json格式
[{"targets": [ "192.168.1.221:29090"],"labels": {"app": "app1","env": "game1","region": "us-west-2"}},{"targets": [ "192.168.1.222:29090" ],"labels": {"app": "app2","env": "game2","region": "ap-southeast-1"}}]
同時還能夠經過爲這些實例添加一些額外的標籤信息,例如使用env標籤標示當前節點所在的環境,這樣從這些實例中採集到的樣本信息將包含這些標籤信息,從而能夠經過該標籤按照環境對數據進行統計。
在Prometheus配置文件中添加如下內容:
- job_name: 'file_sd_test'scrape_interval: 10sfile_sd_configs:- files:- /data/prometheus/static_conf/*.yml- /data/prometheus/static_conf/*.json
這裏定義了一個基於file_sd_configs的監控採集test任務,其中模式的任務名稱爲file_sd_test。在yml文件中可使用yaml標籤覆蓋默認的job名稱,而後重載Prometheus服務。
service prometheus restat
在Prometheus UI的Targets下就能夠看到當前從targets.json文件中動態獲取到的Target實例信息以及監控任務的採集狀態,同時在Labels列下會包含用戶添加的自定義標籤:
file_sd_-testPrometheus默認每5m從新讀取一次文件內容,當須要修改時,能夠經過refresh_interval進行設置,例如:
- job_name: 'file_sd_test'scrape_interval: 10sfile_sd_configs:- refresh_interval: 30s # 30s重載配置文件files:- /data/prometheus/static_conf/*.yml- /data/prometheus/static_conf/*.json
經過這種方式,Prometheus會自動的週期性讀取文件中的內容。當文件中定義的內容發生變化時,不須要對Prometheus進行任何的重啓操做。
這種通用的方式能夠衍生了不少不一樣的玩法,好比與自動化配置管理工具(Ansible)結合、與Cron Job結合等等。對於一些Prometheus還不支持的雲環境,好比國內的阿里雲、騰訊雲等也可使用這種方式經過一些自定義程序與平臺進行交互自動生成監控Target文件,從而實現對這些雲環境中基礎設施的自動化監控支持。
對於一些環境,可能基於文件與consul服務發現已經沒法知足的時候,咱們可能就須要DNS來作服務發現了。在互聯網架構中,咱們使用主機節點或者Kubernetes集羣一般是不對外暴露IP的,這就要求咱們在一個內部局域網或者專用的網絡中部署DNS服務器,使用DNS服務來完成內部網絡中的域名解析工做。這個時候咱們就可使用Prometheus的DNS服務發現,Prometheus的DNS服務發現有倆種方法,第一種是使用DNA A記錄來作自動發現,第二種方法是DNS SRV,第一種顯然沒有沒有SRV資源記錄更爲便捷,在這裏就把倆種配置所有作一遍,對於取決用什麼,根據你本身的環境來抉擇。
DNA A記錄發現配置,首先你內網須要有一個DNS服務器,或者直接自行配置解析記錄便可,我這裏使用的dnsmasq服務在內網測試
# 驗證 test1 DNS記錄nslookup test1.example.comServer: 127.0.0.53Address: 127.0.0.53#53
Non-authoritative answer:Name: test1.example.comAddress: 192.168.1.221# 驗證 test2 DNS記錄nslookup test2.example.comServer: 127.0.0.53Address: 127.0.0.53#53
Non-authoritative answer:Name: test2.example.comAddress: 192.168.1.222
Prometheus配置
# 基於DNS A記錄發現- job_name: 'DNS-A' # job 名稱metrics_path: "/metrics" # 路徑dns_sd_configs:- names: ["test1.example.com", "test2.example.com"] # A記錄type: A # 解析類型port: 29100 # 端口
重啓Prometheus 在targets中能夠看到dns-a記錄
dns-aDNS SRV是DNS資源記錄中的一種記錄類型,用來指定服務器地址與端口,而且能夠設置每一個服務器的優先級和權重。訪問到服務的時候,本地的DNS resolver 從DNS服務器獲取一個地址列表,而後根據優先級和權重來選擇一個地址做爲本次請求的目標地址。
SRV的記錄格式:
_service._proto.name. TTL class SRV priority weight port target
參數 | 說明 |
---|---|
_service |
服務名稱,前綴 _ 是爲了防止與DNS 標籤(域名)衝突 |
proto |
服務使用的通信協議 一般是 tcp udp |
name |
此記錄有效域名 |
TTL |
標準DNS class 字段 如 IN |
priority |
記錄優先級,數值越小,優先級越高。[0-65535] |
weight |
記錄權重,數值越大,權重越高。[0-65535] |
port |
服務使用端口 |
target |
使用服務的主機地址名稱 |
這裏沒有使用named,而是使用的dnsmasq來作的測試,添加SRV記錄完成後,須要重啓dnsmasq服務使其生效。
# 配置dns解析cat /etc/dnsmasq.d/localdomain.confaddress=/test1.example.com/192.168.1.221address=/test2.example.com/192.168.1.222# 添加 SRV 記錄cat /etc/dnsmasq.confsrv-host =_prometheus._tcp.example.com,test1.example.com,29100srv-host =_prometheus._tcp.example.com,test2.example.com,29100
# 驗證srv服務是否正確,192.168.1.123 是內部DNS服務器,dig @192.168.1.123 +noall +answer SRV _prometheus._tcp.example.comoutput..._prometheus._tcp.example.com. 0 IN SRV 0 0 9100 test1.example.com._prometheus._tcp.example.com. 0 IN SRV 0 0 9100 test2.example.com.
Prometheus配置完成之後,重載Prometheus服務。
- job_name: 'DNS-SRV' # 名稱metrics_path: "/metrics" # 獲取數據的路徑dns_sd_configs: # 配置使用DNS解析- names: ['_prometheus._tcp.example.com'] # 配置SRV對應的解析地址
這個時候在targets中能夠看到DNS自動發現的記錄了。
DNS-SRV這個時候,咱們在新加一個記錄,用來作自動發現。
# 添加test0解析cat /etc/dnsmasq.d/localdomain.confaddress=/test1.example.com/192.168.1.221address=/test2.example.com/192.168.1.222address=/test0.example.com/192.168.1.220
# 添加 test0 SRV 記錄cat /etc/dnsmasq.confsrv-host =_prometheus._tcp.example.com,test1.example.com,29100srv-host =_prometheus._tcp.example.com,test2.example.com,29100srv-host =_prometheus._tcp.example.com,test0.example.com,19100
# 驗證dns SRV記錄是否成功dig @192.168.1.123 +noall +answer SRV _prometheus._tcp.example.com_prometheus._tcp.example.com. 0 IN SRV 0 0 19100 test0.example.com._prometheus._tcp.example.com. 0 IN SRV 0 0 29100 test2.example.com._prometheus._tcp.example.com. 0 IN SRV 0 0 29100 test1.example.com.
這個時候在去觀察targets就發現已經能夠自動發現test0了。
DNS-SRV-1