使用 Telegraf 替換 Exporter 優(yōu)化采集監(jiān)控指標(biāo)
?1. 目前的困境
作為云平臺(tái)運(yùn)維,對(duì)接了司內(nèi)多個(gè)業(yè)務(wù)組的監(jiān)控事宜。繁雜的業(yè)務(wù)帶來(lái)的是各類(lèi)不同類(lèi)型的指標(biāo)處理,例如 LB/MySQL/MongoDB/Redis/Pika/Kafka 等數(shù)十類(lèi)中間件或業(yè)務(wù)自行上報(bào)的 metrics。此場(chǎng)景下給我們帶來(lái)了一些挑戰(zhàn)
下面主要以四個(gè)方面展開(kāi)討論:
- agent部署,監(jiān)控 agent 在多云環(huán)境多種不同中間件維護(hù)方式下,如何部署?
- 統(tǒng)一采集,不同類(lèi)型中間件的監(jiān)控?cái)?shù)據(jù)如何統(tǒng)一采集?
- 標(biāo)簽統(tǒng)一,不同類(lèi)型的metrics如何統(tǒng)一處理,確保監(jiān)控視圖/告警能夠路由至正確的業(yè)務(wù)團(tuán)隊(duì)?
- 安全采集,對(duì)于需要auth的中間件,agent需要有獨(dú)立的賬號(hào)密碼才能夠采集到監(jiān)控指標(biāo),賬號(hào)密碼如何加密保障安全?
2. 優(yōu)化之前采用 exporter
2.1 agent部署
基于混合云架構(gòu)下,對(duì)于相同的中間件,不同業(yè)務(wù)組之間使用的方式是迥異的。例如mysql,A業(yè)務(wù)選擇了云廠提供的托管RDS,而B(niǎo)業(yè)務(wù)會(huì)選擇服務(wù)器上自建MySQL 使用mysql_exporter進(jìn)行指標(biāo)采集時(shí),原生組件并不能提供一對(duì)多的方式,即單個(gè)exporter只能夠采集單個(gè)數(shù)據(jù)庫(kù)資源的指標(biāo)。對(duì)于自建MySQL,我們將exporter部署在了中間件所在的服務(wù)器上;而對(duì)于云廠托管RDS,我們?cè)诿總€(gè)VPC下選擇了一臺(tái)服務(wù)器,在這臺(tái)機(jī)器上啟動(dòng)不同的exporter進(jìn)程以監(jiān)控多實(shí)例 因agent部署方式不統(tǒng)一,增大了當(dāng)資源變更時(shí)的運(yùn)維成本,對(duì)于監(jiān)控的發(fā)現(xiàn)/下線等配置文件都需要人工維護(hù)。盡管使用了ansible編排監(jiān)控配置文件,但是對(duì)于不同部署方式的資源,需要編寫(xiě)多套playbook提供支撐
2.2 統(tǒng)一采集
各類(lèi)不同中間件采用不同的監(jiān)控agent,不同的agent使用邏輯也是迥異的,例如node_exporter是將實(shí)例信息通過(guò)file_sd方式寫(xiě)入target到prometheus中讀取,而pika_exporter卻是將實(shí)例信息維護(hù)在一個(gè)單獨(dú)的配置文件中,由agent直接讀取配置抓取數(shù)據(jù),prometheus只需要配置job
- node_exporter
[root@* ~]# cat /etc/prometheus/file_sd/node.yml |head -n 10
- labels:
public_cloud: "huawei" region: "***" team_id: "***" team_name: "***" host_name: "***" host_ip: "1.1.1.1"targets:
- 1.1.1.1:9100
[root@ ~]# cat /var/lib/pika_exporter/pika.host
- job_name: "node_exporter" file_sd_configs:
- files:
- "/etc/prometheus/file_sd/node*.yml"
- pika_exporter
[root@ ~]# cat /var/lib/pika_exporter/pika.host
1.1.1.1:6300,passwd,cluster_name
[root@ ~]# cat/etc/prometheus/prometheus.yml
- job_name: 'pika_exporter' scrape_interval: 30s
static_configs:
- targets: ['127.0.0.1:9099']
當(dāng)agent類(lèi)型有數(shù)十種時(shí),運(yùn)維成本急劇升高,工作變?yōu)橛山?jīng)驗(yàn)和人力堆積的苦力活被監(jiān)控資源類(lèi)型:
- 采集器
- 服務(wù)器 node_exporter
- redis redis_exporter
- mysql mysql_exporter
- mongodb
- mongo_exporter
- ... ...
2.3 標(biāo)簽統(tǒng)一
對(duì)于每個(gè)metrics,我們期望能夠進(jìn)行溯源,定位到具體的業(yè)務(wù)下,這樣在監(jiān)控視圖/告警時(shí),才能夠精確定位到團(tuán)隊(duì),讓團(tuán)隊(duì)聚焦于自己的監(jiān)控告警。底層標(biāo)簽的統(tǒng)一也方便了后續(xù)的上層運(yùn)維應(yīng)用能夠更好的抽象各類(lèi)不同業(yè)務(wù)特性。使用prometheus,針對(duì)job或者job下的target附加業(yè)務(wù)相關(guān)lable,例如 team_id=***,team_name=***
標(biāo)簽如何配置
回到上面說(shuō)的問(wèn)題,以MySQL為例,單個(gè)云廠的RDS實(shí)例需要啟用單獨(dú)的expoter進(jìn)程采集數(shù)據(jù),那么在prometheus配置時(shí),lable只能附加在job層級(jí)。對(duì)于云廠提供的托管RDS/Redis/Mongo 等實(shí)例,部分宿主機(jī)相關(guān)指標(biāo),我們無(wú)法通過(guò)exporter進(jìn)行采集。exporter采集的是中間件接口接口返回的數(shù)據(jù),不具備采集中間件所在的宿主機(jī)指標(biāo)的能力。例如無(wú)法獲取到CPU使用率/磁盤(pán)使用率/磁盤(pán)IOPS等指標(biāo) 同時(shí),對(duì)于一些資源指標(biāo),我們也無(wú)法使用社區(qū)的exporter進(jìn)行收集,例如 LB/VPC 等相關(guān)云原生組件 當(dāng)然,成熟的云廠會(huì)提供API或者它們定制的exporter用以獲取監(jiān)控?cái)?shù)據(jù),但是metric/lable 與社區(qū)exporter完全不一致。即使我們能夠通過(guò)云廠exporter獲取到數(shù)據(jù),但是并不能夠?qū)able使用prometheus精確的附加在每一個(gè)資源上。例如AWS提供的cloud watch,對(duì)接在prometheus時(shí)不需要配置target,那么lable只能夠?qū)懺趈ob層對(duì)所有資源附加相同的lable,不能滿足我們的需求
如果不能打平配置上的差異與使用不同方式獲取到的metric/lable的差異,不僅提高了運(yùn)維復(fù)雜性,對(duì)于相同中間件的監(jiān)控/告警 體驗(yàn)是割裂開(kāi)的,不夠完美。
2.4 安全采集
對(duì)于需要auth才能夠使用的中間件,我們需要維護(hù)一份密碼配置文件供exporter使用,而在服務(wù)器上明文保存密碼是不安全的
3. 優(yōu)化之后采用 telegraf 采集
使用telegraf解決痛點(diǎn) 參考鏈接:https://github.com/influxdata/telegraf
3.1 agent部署 & 統(tǒng)一采集
對(duì)于常見(jiàn)的中間件資源,telegraf社區(qū)均已適配,可實(shí)現(xiàn)由統(tǒng)一的telegraf二進(jìn)制包,同時(shí)啟動(dòng)不同的systemd管理不同類(lèi)型的中間件監(jiān)控agent 并且telegraf input原生支持一對(duì)多,單機(jī)部署即可滿足對(duì)所有中間件資源的監(jiān)控指標(biāo)抓取
[root@ ~]# systemctl status telegraf-telegraf-mongo.service telegraf-mysql.service telegraf-pika.service telegraf-redis.service
[root@ ~]# cat /etc/prometheus/prometheus.yml
- job_name: "telegraf-mysql" scrape_interval: 15s
metrics_path: "/metrics" static_configs:
- targets:
- 127.0.0.1:9274
- job_name: "telegraf-pika" scrape_interval: 15s
metrics_path: "/metrics" static_configs:
- targets:
- 127.0.0.1:9275
- job_name: "telegraf-mongo" scrape_interval: 15s
metrics_path: "/metrics" static_configs:
- targets:
- 127.0.0.1:9280
[root@ ~]# cat /etc/systemd/system/telegraf-mysql.service
[Unit]
Description=Telegraf Exporter
After=network.target
[Service]
WorkingDirectory=/opt/apps/telegraf-mysql
ExecStart=/usr/local/bin/telegraf --config /opt/apps/telegraf-mysql/telegraf.conf --config-directory /opt/apps/telegraf-mysql/telegraf.d
Restart=on-failure
[Install]
WantedBy=multi-user.target
3.2 標(biāo)簽統(tǒng)一
telegraf的processors支持value mapping,可以依據(jù)已經(jīng)存在的key-value映射新的lables到metrics中 參考鏈接:https://docs.influxdata.com/telegraf/v1.23/configuration/#metric-filtering
此處我們使用mapping構(gòu)造了 team_id,team_name,instance_name三個(gè)lable,它會(huì)查詢所有抓取到的 mysql metrics中的lable,若存在server=1.1.1.1,則映射上述三個(gè)指定的key-values到metrics中 配置文件
[root@ ~]# cat /opt/apps/telegraf-mysql/telegraf.conf
[global_tags] region = "***"
[agent]
interval = "10s" round_interval = true metric_batch_size = 1000 metric_buffer_limit = 10000 collection_jitter = "0s" flush_interval = "10s" flush_jitter = "0s" precision = "0s" hostname = "" omit_hostname = false [[outputs.prometheus_client]]
listen = ":9274"
[[inputs.mysql]]
gather_global_variables = true gather_slave_status = true interval_slow="10s" servers = ["username:password@tcp(1.1.1.1:3306)/"]
[[processors.enum]]
[[processors.enum.mapping]]
tag = "server" dest = "team_id" default = "null" [processors.enum.mapping.value_mappings]
"1.1.1.1:3306" = "123"
[[processors.enum]]
[[processors.enum.mapping]]
tag = "server" dest = "team_name" default = "null" [processors.enum.mapping.value_mappings]
"1.1.1.1:3306" = "test-team"
[[processors.enum]]
[[processors.enum.mapping]]
tag = "server" dest = "instance_name" default = "null" [processors.enum.mapping.value_mappings]
"1.1.1.1:3306" = "test-instance"
測(cè)試
[root@ ~]# curl 127.0.0.1:9274/metrics|grep mysql_up{
mysql_up{instance_name="test-instance",region="***",server="1.1.1.1:3306",team_id="123",team_name="test-team"} 1
而配置文件的生成,需要編寫(xiě)腳本去資源中心獲取到具體的實(shí)例信息,進(jìn)行自動(dòng)渲染。從而實(shí)現(xiàn)監(jiān)控的自動(dòng)發(fā)現(xiàn)。這依賴于運(yùn)維需要有一個(gè)統(tǒng)一的資源平臺(tái)能夠?qū)?nèi)服務(wù),不多贅述。當(dāng)使用同一個(gè)監(jiān)控agent時(shí),腳本的維護(hù)才會(huì)簡(jiǎn)單,否則不同類(lèi)型的中間件監(jiān)控都需要編寫(xiě)不同腳本來(lái)實(shí)現(xiàn)自動(dòng)發(fā)現(xiàn)。
同時(shí),telegraf支持多種不同的input數(shù)據(jù)輸入 對(duì)于aws cloud watch或者華為云的cloudeye,我們可以將他們先以job方式在prometheus抓取數(shù)據(jù),此時(shí)不進(jìn)行l(wèi)able增添 而后通過(guò)telegraf的mapping和input prometheus data,利用從資源中心獲取到的key-valus,進(jìn)行數(shù)據(jù)的二次格式化增加需要的lable,實(shí)現(xiàn)標(biāo)簽的統(tǒng)一 參考鏈接:https://docs.influxdata.com/telegraf/v1.23/data_formats/input/
3.3 安全采集
可惜的是,telegraf原生也不支持對(duì)密碼的加密 好處是,telegraf各個(gè)組件代碼風(fēng)格是統(tǒng)一的,不像各類(lèi)exporter。對(duì)于telegraf的二次開(kāi)發(fā),只要實(shí)現(xiàn)對(duì)某個(gè)INPUT模塊的密碼編碼解碼,可以很快復(fù)用到其他INPUT模塊,高效實(shí)現(xiàn)各個(gè)不同中間件在使用監(jiān)控時(shí)的密碼安全
4. 總結(jié)
本文是近期將監(jiān)控采集器從 exporter 遷移到 telegraf 的一次總結(jié),主要從 agent 部署、統(tǒng)一采集、標(biāo)簽統(tǒng)一、安全采集四個(gè)方面,比較了優(yōu)化前后的差異。
但 telegraf 也存在一些問(wèn)題,telegraf 原生支持二百余個(gè)模塊,同時(shí)提供各類(lèi)高級(jí)功能,實(shí)際使用中,發(fā)現(xiàn)某些模塊抓取的指標(biāo)并不令人滿意。例如mysql_exporter中的up指標(biāo)(探活),telegraf未進(jìn)行采集 使用時(shí)可按需裁剪,保留需要的模塊,否則使用起來(lái)較重(二進(jìn)制幾百M(fèi))。對(duì)于更多高級(jí)用法,需要進(jìn)行一定的二次開(kāi)發(fā)才能更好適配業(yè)務(wù)需求。同時(shí) telegraf 的 Grafana 面板較少,因此我們需要花費(fèi)點(diǎn)時(shí)間手工繪制。