本章節(jié)主要講自動(dòng)發(fā)現(xiàn)使用場(chǎng)景介紹與Prometheus基于文件膳叨、DNS的自動(dòng)發(fā)現(xiàn)配置
當(dāng)我們使用各類(lèi)exporter分別對(duì)系統(tǒng)、數(shù)據(jù)庫(kù)和HTTP服務(wù)進(jìn)行監(jiān)控指標(biāo)采集,對(duì)于所有監(jiān)控指標(biāo)對(duì)應(yīng)的Target的運(yùn)行狀態(tài)和資源使用情況,都是用Prometheus的靜態(tài)配置功能 static_configs
來(lái)
手動(dòng)添加主機(jī)IP和端口,然后重載服務(wù)讓Prometheus發(fā)現(xiàn)励堡。
對(duì)于一組比較少的服務(wù)器的測(cè)試環(huán)境中谷丸,這種手動(dòng)方式添加配置信息是最簡(jiǎn)單的方法。但是實(shí)際生產(chǎn)環(huán)境中应结,對(duì)于成百上千的節(jié)點(diǎn)組成的大型集群又或者Kubernetes這樣的大型集群刨疼,很明顯,手動(dòng)方式捉襟見(jiàn)肘了鹅龄。
為此揩慕,Prometheus提前已經(jīng)設(shè)計(jì)了一套服務(wù)發(fā)現(xiàn)功能。
Prometheus 服務(wù)發(fā)現(xiàn)能夠自動(dòng)檢測(cè)分類(lèi)扮休,并且能夠識(shí)別新節(jié)點(diǎn)和變更節(jié)點(diǎn)迎卤。也就是說(shuō),可以在容器或者云平臺(tái)中玷坠,自動(dòng)發(fā)現(xiàn)并監(jiān)控節(jié)點(diǎn)或更新節(jié)點(diǎn)蜗搔,動(dòng)態(tài)的進(jìn)行數(shù)據(jù)采集和處理。
目前 Prometheus 已經(jīng)支持了很多常見(jiàn)的自動(dòng)發(fā)現(xiàn)服務(wù)八堡,比如 consul
ec2
gce
serverset_sd_config
openStack
kubernetes
等等樟凄。
我們常用的就是sd_config、DNS兄渺、kubernetes缝龄、consul這些足夠了。如果有需要其他配置的探討挂谍,可以與我交流叔壤,我可以補(bǔ)上來(lái)。
本章節(jié)中會(huì)對(duì)Prometheus自動(dòng)發(fā)現(xiàn)中的基于文件口叙、DNS進(jìn)行發(fā)現(xiàn)講解百新,consul
在后面會(huì)單獨(dú)展開(kāi)來(lái)講,如何可以使其完美的解決當(dāng)前場(chǎng)景下常見(jiàn)的各類(lèi)服務(wù)發(fā)現(xiàn)監(jiān)控庐扫。
為什么要用自動(dòng)發(fā)現(xiàn)?
在基于云(IaaS或者CaaS)的基礎(chǔ)設(shè)施環(huán)境中用戶(hù)可以像使用水饭望、電一樣按需使用各種資源(計(jì)算仗哨、網(wǎng)絡(luò)、存儲(chǔ))铅辞。按需使用就意味著資源的動(dòng)態(tài)性厌漂,這些資源可以隨著需求規(guī)模的變化而變化。例如在AWS中就提供了專(zhuān)門(mén)的AutoScall服務(wù)斟珊,可以根據(jù)用戶(hù)定義的規(guī)則動(dòng)態(tài)地創(chuàng)建或者銷(xiāo)毀EC2實(shí)例苇倡,從而使用戶(hù)部署在AWS上的應(yīng)用可以自動(dòng)的適應(yīng)訪問(wèn)規(guī)模的變化。
這種按需的資源使用方式對(duì)于監(jiān)控系統(tǒng)而言就意味著沒(méi)有了一個(gè)固定的監(jiān)控目標(biāo)囤踩,所有的監(jiān)控對(duì)象(基礎(chǔ)設(shè)施旨椒、應(yīng)用、服務(wù))都在動(dòng)態(tài)的變化堵漱。對(duì)于Nagias這類(lèi)基于Push模式傳統(tǒng)監(jiān)控軟件就意味著必須在每一個(gè)節(jié)點(diǎn)上安裝相應(yīng)的Agent程序综慎,并且通過(guò)配置指向中心的Nagias服務(wù),受監(jiān)控的資源與中心監(jiān)控服務(wù)器之間是一個(gè)強(qiáng)耦合的關(guān)系勤庐,要么直接將Agent構(gòu)建到基礎(chǔ)設(shè)施鏡像當(dāng)中示惊,要么使用一些自動(dòng)化配置管理工具(如Ansible、Chef)動(dòng)態(tài)的配置這些節(jié)點(diǎn)愉镰。當(dāng)然實(shí)際場(chǎng)景下除了基礎(chǔ)設(shè)施的監(jiān)控需求以外米罚,我們還需要監(jiān)控在云上部署的應(yīng)用,中間件等等各種各樣的服務(wù)丈探。要搭建起這樣一套中心化的監(jiān)控系統(tǒng)實(shí)施成本和難度是顯而易見(jiàn)的录择。
而對(duì)于Prometheus這一類(lèi)基于Pull模式的監(jiān)控系統(tǒng),顯然也無(wú)法繼續(xù)使用的static_configs的方式靜態(tài)的定義監(jiān)控目標(biāo)碗降。而對(duì)于Prometheus而言其解決方案就是引入一個(gè)中間的代理人(服務(wù)注冊(cè)中心)糊肠,這個(gè)代理人掌握著當(dāng)前所有監(jiān)控目標(biāo)的訪問(wèn)信息,Prometheus只需要向這個(gè)代理人詢(xún)問(wèn)有哪些監(jiān)控目標(biāo)控即可遗锣, 這種模式被稱(chēng)為服務(wù)發(fā)現(xiàn)货裹。
在不同的場(chǎng)景下,會(huì)有不同的東西扮演者代理人(服務(wù)發(fā)現(xiàn)與注冊(cè)中心)這一角色精偿。比如在AWS公有云平臺(tái)或者OpenStack的私有云平臺(tái)中弧圆,由于這些平臺(tái)自身掌握著所有資源的信息,此時(shí)這些云平臺(tái)自身就扮演了代理人的角色笔咽。Prometheus通過(guò)使用平臺(tái)提供的API就可以找到所有需要監(jiān)控的云主機(jī)搔预。在Kubernetes這類(lèi)容器管理平臺(tái)中,Kubernetes掌握并管理著所有的容器以及服務(wù)信息叶组,那此時(shí)Prometheus只需要與Kubernetes打交道就可以找到所有需要監(jiān)控的容器以及服務(wù)對(duì)象拯田。Prometheus還可以直接與一些開(kāi)源的服務(wù)發(fā)現(xiàn)工具進(jìn)行集成,例如在微服務(wù)架構(gòu)的應(yīng)用程序中甩十,經(jīng)常會(huì)使用到例如Consul這樣的服務(wù)發(fā)現(xiàn)注冊(cè)軟件船庇,Promethues也可以與其集成從而動(dòng)態(tài)的發(fā)現(xiàn)需要監(jiān)控的應(yīng)用服務(wù)實(shí)例吭产。除了與這些平臺(tái)級(jí)的公有云、私有云鸭轮、容器云以及專(zhuān)門(mén)的服務(wù)發(fā)現(xiàn)注冊(cè)中心集成以外臣淤,Prometheus還支持基于DNS以及文件的方式動(dòng)態(tài)發(fā)現(xiàn)監(jiān)控目標(biāo),從而大大的減少了在云原生窃爷,微服務(wù)以及云模式下監(jiān)控實(shí)施難度邑蒋。
如上所示,展示了Push系統(tǒng)和Pull系統(tǒng)的核心差異按厘。相較于Push模式医吊,Pull模式的優(yōu)點(diǎn)可以簡(jiǎn)單總結(jié)為以下幾點(diǎn):
只要Exporter在運(yùn)行浦箱,你可以在任何地方(比如在本地)诵棵,搭建你的監(jiān)控系統(tǒng);
你可以更容易的查看監(jiān)控目標(biāo)實(shí)例的健康狀態(tài)昵宇,并且可以快速定位故障造虏;
更利于構(gòu)建DevOps文化的團(tuán)隊(duì);
松耦合的架構(gòu)模式更適合于云原生的部署環(huán)境麦箍。
基于文件的服務(wù)發(fā)現(xiàn)
在Prometheus支持的眾多服務(wù)發(fā)現(xiàn)的實(shí)現(xiàn)方式中漓藕,基于文件的服務(wù)發(fā)現(xiàn)是最通用的方式。這種方式不需要依賴(lài)于任何的平臺(tái)或者第三方服務(wù)挟裂。對(duì)于Prometheus而言也不可能支持所有的平臺(tái)或者環(huán)境享钞。通過(guò)基于文件的服務(wù)發(fā)現(xiàn)方式下,Prometheus會(huì)定時(shí)從文件中讀取最新的Target信息诀蓉,因此栗竖,你可以通過(guò)任意的方式將監(jiān)控Target的信息寫(xiě)入即可。
用戶(hù)可以通過(guò)JSON或者YAML格式的文件渠啤,定義所有的監(jiān)控目標(biāo)狐肢。例如,在下面的yaml文件中分別定義了2個(gè)采集任務(wù)沥曹,以及每個(gè)任務(wù)對(duì)應(yīng)的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"
}
}
]
同時(shí)還可以通過(guò)為這些實(shí)例添加一些額外的標(biāo)簽信息份名,例如使用env標(biāo)簽標(biāo)示當(dāng)前節(jié)點(diǎn)所在的環(huán)境,這樣從這些實(shí)例中采集到的樣本信息將包含這些標(biāo)簽信息妓美,從而可以通過(guò)該標(biāo)簽按照環(huán)境對(duì)數(shù)據(jù)進(jìn)行統(tǒng)計(jì)僵腺。
創(chuàng)建Prometheus配置文件/data/prometheus/conf/prometheus-file-sd.yml,并添加以下內(nèi)容:
- job_name: 'file_sd_test'
scrape_interval: 10s
file_sd_configs:
- files:
- /data/prometheus/static_conf/*.yml
- /data/prometheus/static_conf/*.json
這里定義了一個(gè)基于file_sd_configs的監(jiān)控采集test任務(wù)壶栋,其中模式的任務(wù)名稱(chēng)為file_sd_test辰如。在yml文件中可以使用yaml標(biāo)簽覆蓋默認(rèn)的job名稱(chēng),然后重載Prometheus服務(wù)贵试。
service prometheus restat
在Prometheus UI的Targets下就可以看到當(dāng)前從targets.json文件中動(dòng)態(tài)獲取到的Target實(shí)例信息以及監(jiān)控任務(wù)的采集狀態(tài)琉兜,同時(shí)在Labels列下會(huì)包含用戶(hù)添加的自定義標(biāo)簽:
Prometheus默認(rèn)每5m重新讀取一次文件內(nèi)容凯正,當(dāng)需要修改時(shí),可以通過(guò)refresh_interval進(jìn)行設(shè)置呕童,例如:
- job_name: 'file_sd_test'
scrape_interval: 10s
file_sd_configs:
- refresh_interval: 30s # 30s重載配置文件
files:
- /data/prometheus/static_conf/*.yml
- /data/prometheus/static_conf/*.json
通過(guò)這種方式漆际,Prometheus會(huì)自動(dòng)的周期性讀取文件中的內(nèi)容。當(dāng)文件中定義的內(nèi)容發(fā)生變化時(shí)夺饲,不需要對(duì)Prometheus進(jìn)行任何的重啟操作奸汇。
這種通用的方式可以衍生了很多不同的玩法,比如與自動(dòng)化配置管理工具(Ansible)結(jié)合往声、與Cron Job結(jié)合等等擂找。 對(duì)于一些Prometheus還不支持的云環(huán)境,比如國(guó)內(nèi)的阿里云浩销、騰訊云等也可以使用這種方式通過(guò)一些自定義程序與平臺(tái)進(jìn)行交互自動(dòng)生成監(jiān)控Target文件贯涎,從而實(shí)現(xiàn)對(duì)這些云環(huán)境中基礎(chǔ)設(shè)施的自動(dòng)化監(jiān)控支持。
基于DNS的發(fā)現(xiàn)
對(duì)于一些環(huán)境慢洋,可能基于文件與consul服務(wù)發(fā)現(xiàn)已經(jīng)無(wú)法滿足的時(shí)候塘雳,我們可能就需要DNS來(lái)做服務(wù)發(fā)現(xiàn)了。在互聯(lián)網(wǎng)架構(gòu)中普筹,我們使用主機(jī)節(jié)點(diǎn)或者Kubernetes集群通常是不對(duì)外暴露IP的败明,這就要求我們?cè)谝粋€(gè)內(nèi)部局域網(wǎng)或者專(zhuān)用的網(wǎng)絡(luò)中部署DNS服務(wù)器,使用DNS服務(wù)來(lái)完成內(nèi)部網(wǎng)絡(luò)中的域名解析工作太防。
這個(gè)時(shí)候我們就可以使用Prometheus的DNS服務(wù)發(fā)現(xiàn)妻顶,Prometheus的DNS服務(wù)發(fā)現(xiàn)有倆種方法,第一種是使用DNA A記錄來(lái)做自動(dòng)發(fā)現(xiàn)蜒车,第二種方法是DNS SRV讳嘱,第一種顯然沒(méi)有沒(méi)有SRV資源記錄更為便捷,在這里就把倆種配置全部做一遍酿愧,對(duì)于取決用什么沥潭,根據(jù)你自己的環(huán)境來(lái)抉擇。
DNA A記錄發(fā)現(xiàn)配置嬉挡,首先你內(nèi)網(wǎng)需要有一個(gè)DNS服務(wù)器叛氨,或者直接自行配置解析記錄即可,我這里使用的dnsmasq服務(wù)在內(nèi)網(wǎng)測(cè)試
# 驗(yàn)證 test1 DNS記錄
nslookup test1.example.com
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
Name: test1.example.com
Address: 192.168.1.221
# 驗(yàn)證 test2 DNS記錄
nslookup test2.example.com
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
Name: test2.example.com
Address: 192.168.1.222
Prometheus配置
# 基于DNS A記錄發(fā)現(xiàn)
- job_name: 'DNS-A' # job 名稱(chēng)
metrics_path: "/metrics" # 路徑
dns_sd_configs:
- names: ["test1.example.com", "test2.example.com"] # A記錄
type: A # 解析類(lèi)型
port: 29100 # 端口
重啟Prometheus 在targets中可以看到dns-a記錄
DNS SRV是DNS資源記錄中的一種記錄類(lèi)型棘伴,用來(lái)指定服務(wù)器地址與端口寞埠,并且可以設(shè)置每個(gè)服務(wù)器的優(yōu)先級(jí)和權(quán)重。訪問(wèn)到服務(wù)的時(shí)候焊夸,本地的DNS resolver 從DNS服務(wù)器獲取一個(gè)地址列表仁连,然后根據(jù)優(yōu)先級(jí)和權(quán)重來(lái)選擇一個(gè)地址作為本次請(qǐng)求的目標(biāo)地址。
SRV的記錄格式:
_service._proto.name. TTL class SRV priority weight port target
參數(shù) | 說(shuō)明 |
---|---|
_service |
服務(wù)名稱(chēng),前綴 _ 是為了防止與DNS 標(biāo)簽(域名)沖突 |
proto |
服務(wù)使用的通訊協(xié)議 通常是 tcp udp
|
name |
此記錄有效域名 |
TTL |
標(biāo)準(zhǔn)DNS class 字段 如 IN
|
priority |
記錄優(yōu)先級(jí)饭冬,數(shù)值越小使鹅,優(yōu)先級(jí)越高。 [0-65535] |
weight |
記錄權(quán)重昌抠,數(shù)值越大患朱,權(quán)重越高。[0-65535] |
port |
服務(wù)使用端口 |
target |
使用服務(wù)的主機(jī)地址名稱(chēng) |
這里沒(méi)有使用named炊苫,而是使用的dnsmasq來(lái)做的測(cè)試裁厅,添加SRV記錄完成后,需要重啟dnsmasq服務(wù)使其生效侨艾。
# 配置dns解析
cat /etc/dnsmasq.d/localdomain.conf
address=/test1.example.com/192.168.1.221
address=/test2.example.com/192.168.1.222
# 添加 SRV 記錄
cat /etc/dnsmasq.conf
srv-host =_prometheus._tcp.example.com,test1.example.com,29100
srv-host =_prometheus._tcp.example.com,test2.example.com,29100
# 驗(yàn)證srv服務(wù)是否正確执虹,192.168.1.123 是內(nèi)部DNS服務(wù)器,
dig @192.168.1.123 +noall +answer SRV _prometheus._tcp.example.com
output...
_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服務(wù)袋励。
- job_name: 'DNS-SRV' # 名稱(chēng)
metrics_path: "/metrics" # 獲取數(shù)據(jù)的路徑
dns_sd_configs: # 配置使用DNS解析
- names: ['_prometheus._tcp.example.com'] # 配置SRV對(duì)應(yīng)的解析地址
這個(gè)時(shí)候在targets中可以看到DNS自動(dòng)發(fā)現(xiàn)的記錄了。
這個(gè)時(shí)候当叭,我們?cè)谛录右粋€(gè)記錄茬故,用來(lái)做自動(dòng)發(fā)現(xiàn)。
# 添加test0解析
cat /etc/dnsmasq.d/localdomain.conf
address=/test1.example.com/192.168.1.221
address=/test2.example.com/192.168.1.222
address=/test0.example.com/192.168.1.220
# 添加 test0 SRV 記錄
cat /etc/dnsmasq.conf
srv-host =_prometheus._tcp.example.com,test1.example.com,29100
srv-host =_prometheus._tcp.example.com,test2.example.com,29100
srv-host =_prometheus._tcp.example.com,test0.example.com,19100
# 驗(yàn)證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.
這個(gè)時(shí)候在去觀察targets就發(fā)現(xiàn)已經(jīng)可以自動(dòng)發(fā)現(xiàn)test0了蚁鳖。