SRE-DevOps不得不懂的:Prometheus的配置工程化

背景

Prometheus有兩個最基本的組件:一個是Prometheus程序呀打,一個是Alertmanager程序旱易。

它們的職責(zé)分工很明確:

  • Prometheus程序負(fù)責(zé):定時拉取監(jiān)控指標(biāo)數(shù)據(jù)饲做、存儲指標(biāo)數(shù)據(jù)主胧、根據(jù)告警規(guī)則發(fā)起告警通知迄委;
  • Alertmanager程序負(fù)責(zé):負(fù)責(zé)告警通知的路由蚌吸,即當(dāng)接收到Prometheus程序的通知后,該將通知以何種方式通知給誰龄坪。

Prometheus程序的配置最核心的配置是:

# ... 

# 當(dāng)指標(biāo)數(shù)據(jù)符合什么規(guī)則進行告警通知昭雌。
# 在其它文件定義,這里只是引用該文件的路徑健田。
rule_files:
  [ - <filepath_glob> ... ]

# 從哪里烛卧,該如何拉取指標(biāo)
scrape_configs:
  [ - <scrape_config> ... ]
  
# ...

Alertmanager程序的配置最核心的配置是:

# ...
# 告警通知路由規(guī)則
route:
    [- <route_config>-]
# 告警通知的接收者列表,部分監(jiān)控告警平臺也稱之為channel
receivers:
    [- <receivers>-]
# ...

在實際工作中妓局,Prometheus和Alertmanager的配置會非常大总放。

嚴(yán)謹(jǐn)?shù)能浖こ桃笪覀冊谡嬲渴疬@些配置前,對其進行有效性和正確性的檢查好爬。否則SRE/DevOps的工程效率就會很低局雄,因為你需要手工調(diào)試龐大的配置。

所以存炮,我們需要有一種高效率的方式來保證配置的有效性和正確性炬搭。

保證Prometheus程序配置的有效性和正確性

promtool

Prometheus程序提供了一個叫promtool的命令行程序。解壓Prometheus的程序包后穆桂,你會發(fā)現(xiàn)它和Prometheus程序放在一個文件夾中宫盔。

promtool提供了一些子命令來保證Prometheus程序配置的有效性和正確性:

# 校驗Prometheus配置的有效性,它支持--lint="duplicate-rules"參數(shù)享完,用于檢查重復(fù)的rule配置
check config [<flags>] <config-files>...
# 校驗rule配置的有效性
check rules [<flags>] <rule-files>...
# 執(zhí)行rules單元測試用例
test rules <test-rule-file>...

至于有效性檢查灼芭,只需要執(zhí)行check子命令即可,不需要過多說明般又。

promtool的test rules子命令可以實現(xiàn)rule配置的單元測試彼绷,具體命令如下:

./promtool test rules test.yml

test.yaml是單元測試描述文件。promtool是支持同時指定多個單元測試文件的倒源,如:./promtool test rules test.yml test1.yml test2.yml

單元測試描述文件內(nèi)容的格式如下:

# Prometheus的rule配置文件路徑
rule_files:
    - rule1.yml

# 評估的間隔時長
evaluation_interval: 1m

# 單元測試列表
tests:
- interval: 1m
  input_series:
  alert_rule_test:
  promql_expr_test:

tests下的每個用例由4個字段組成:

  1. input_series:測試用例的測試數(shù)據(jù)苛预,即指標(biāo)的時序數(shù)據(jù)句狼;
  2. interval:代表每個時序數(shù)據(jù)之間的間隔時長笋熬;
  3. alert_rule_test:告警規(guī)則的測試用例;
  4. promql_expr_test:promql表達(dá)式的測試用例腻菇。我們可以使用它進行調(diào)試我們的promsql胳螟。

接下來將詳細(xì)介紹它們昔馋。

測試用例數(shù)據(jù)

測試用例數(shù)據(jù)的定義格式如下:

  input_series:
  - series: 'up{job="prometheus", instance="localhost:9090"}'
    values: '0 0 0 0 0 0 0 0 0 0 0 0 0 0 0'
  - series: 'up{job="node_exporter", instance="localhost:9100"}'
    values: '1+0x6 0 0 0 0 0 0 0 0' 
  - series: 'go_goroutines{job="prometheus", instance="localhost:9090"}'
    values: '10+10x2 30+20x5' 
  - series: 'go_goroutines{job="node_exporter", instance="localhost:9100"}'
    values: '10+10x7 10+30x4' 

每一條input_serie由兩個字段組成:

  • series:指標(biāo)時序數(shù)據(jù)的key
  • values:指標(biāo)的value。其中的每一個值之間的間隔時長是interval的值

為了簡化values的值的定義糖耸,你可以一種擴展符號來定義其值秘遏。語法如下:

  • a+bxc代表:a a+b a+(2*b) a+(3*b) … a+(c*b);這一個a值是起始值的序列嘉竟,然后a以b的(0..c)的倍數(shù)進行遞增邦危;
  • a-bxc表示:這一個a值是起始值的序列,然后a以b的(0..c)的倍數(shù)進行遞減舍扰;
  • _下劃線表示:序列中的某次指標(biāo)值沒有被抓取到倦蚪;
  • stale表示:過期的樣本數(shù)據(jù)。
    以下是一些來自官方文檔的例子:
  • -2+4x3表示:-2 2 6 10
  • 1-2x4表示:1 -1 -3 -5 -7
  • 1x4表示:1 1 1 1 1
  • 1 _x3 stale表示:1 _ _ _ stale
  • 1+0x6 0 0 0 0 0 0 0 0表示: 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0
  • 10+10x2 30+20x5表示:10 20 30 30 50 70 90 110 130

測試Promsql表達(dá)式

在寫Prometheus告警規(guī)則時边苹,一個很大的痛點就是無法簡單的驗證自己寫的promsql的正確性陵且。我們在告警規(guī)則的單元測試中驗證后,再配置到真正的rule文件中个束。

promsql的測試用例的寫法如下:

  promql_expr_test:
  - expr: go_goroutines > 5 
    # 要測試的promsql表達(dá)式慕购,它將會從測試數(shù)據(jù)中查詢數(shù)據(jù)
    eval_time: 4m
    # 評估時長。從測試數(shù)據(jù)的第0秒開始算茬底。
    # 如果interval是1m沪悲,那么4m代表的是測試數(shù)據(jù)的第4個數(shù)值
    exp_samples: # 執(zhí)行promsql表達(dá)式后,預(yù)期得到的數(shù)據(jù)結(jié)果
        - labels: 'go_goroutines{job="prometheus",instance="localhost:9090"}'
          value: 50
        - labels: 'go_goroutines{job="node_exporter",instance="localhost:9100"}'
          value: 50

告警規(guī)則的單元測試

在單元測試描述文件中桩警,添加Promsql表達(dá)式的測試用例的同時可训,我們還可以添加告警規(guī)則的測試用例,代碼樣例如下:

alert_rule_test:
- eval_time: 10m
  alertname: InstanceDown
  exp_alerts:
  - exp_labels:
      severity: page
      instance: localhost:9090
      job: prometheus
    exp_annotations:
      summary: "Instance localhost:9090 down"
      description: "localhost:9090 of job prometheus has been down for more than 5 minutes."
  • eval_time:規(guī)則評估時長捶枢;
  • alertname:告警名握截,要求與Prometheus的告警規(guī)則中的alertname一致;
  • exp_labels:預(yù)期收到的告警通知中的label值烂叔;
  • exp_annotations:預(yù)期收到的告警通知中的annotation值谨胞。

保證Alertmanager程序配置的有效性和正確性

amtool

與Prometheus程序類似,Alertmanager程序提供了一個叫amtool的命令行程序蒜鸡。

我們關(guān)注它的兩個子命令:

  • config routes test:驗證配置的正確性
  • check-config <config.yaml>:驗證配置的有效性

config routes test子命令介紹

amtool不像promtool那樣支持在YAML文件中定義測試用例胯努,以下是它的命令樣例:
amtool config routes test --config.file=config.yaml --verify.receivers=team-X-pager service=database owner=team-X

--config.file參數(shù)指定了配置文件的路徑。

除了支持指定配置的路徑逢防,還可以通過參數(shù)--alertmanager.url指定使用某個運行中的Alertmanager的配置叶沛。

--verify.receivers指定期望返回的receiver列表,使用逗號分隔忘朝。

該子命令的最后是標(biāo)簽集灰署,由key=value的格式組成,并使用空格分隔。例子中service=database owner=team-X溉箕,代表的是{service="database",owner="team-X"}

為了更好的可視化晦墙,還可以加一個--tree的參數(shù),效果如下:

% amtool config routes test --config.file=config.yaml --tree --verify.receivers=team-X-pager service=database owner=team-X

Matching routes:
.
└── default-route
    └── {service="database"}
        └── {owner="team-X"}  receiver: team-X-pager

如果驗證失敗肴茄,該命令返回非0結(jié)果晌畅。

check-config子命令介紹

它的運行效果如下:

% amtool check-config config.yaml
Checking 'config.yaml'  SUCCESS
Found:
 - global config
 - route
 - 1 inhibit rules
 - 5 receivers
 - 1 templates
  SUCCESS

如果驗證失敗,該命令返回非0結(jié)果寡痰。

可視化告警通知路由

Prometheus官網(wǎng)提供了一個告警通知路由的在線可視化編輯器抗楔。

alertmanager-route-editor.png

將配置粘貼至編輯框中,然后在“Match Label Set”中輸入告警的標(biāo)簽拦坠,最后下方會顯示通知的路由路徑谓谦。如下圖,實心紅點即是匹配了該label的receiver:

alertmanager-route-editor-1.png

可視化工具在路由配置調(diào)試階段非常有用贪婉。減小了路由配置的難度反粥。但是,需要注意:不要將任何敏感配置上傳到公網(wǎng)疲迂。

如何集成到CI/CD Pipeline中

以上介紹的是兩個命令最原始的使用方法才顿,即手工運行。我們需要將其集成到CI/CD pipeline中尤蒿,以實現(xiàn)工程化郑气。

集成方式一般有兩:

  1. 在Pipeline中增加一個執(zhí)行promtool和amtool的階段
  2. 集成構(gòu)建工具中,比如集成到Bazel中腰池。

當(dāng)然有一些DevOps平臺如果需要深度集成尾组,可以將promtool的amtool的實現(xiàn)代碼引入到自己的DevOps平臺的代碼中。

工程化的挑戰(zhàn)

另一個工程化的挑戰(zhàn)示弓,就是以上的配置文件之間存在引用讳侨,如下prometheus的rule文件中的expr字段的值,實際上是被prometheus-unitesting.yml文件引用奏属。

如果不對這個引用關(guān)系進行治理跨跨,這些配置的維護成本將會非常高。

由于YAML文件天生不具備變量定義的功能囱皿∮掠ぃ可以采用類似Jsonnet、CUE這樣的支持編程的配置語言代替YAML嘱腥。

這個話題比較大耕渴,不在本文討論范圍。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末齿兔,一起剝皮案震驚了整個濱河市橱脸,隨后出現(xiàn)的幾起案子窄做,更是在濱河造成了極大的恐慌,老刑警劉巖慰技,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異组砚,居然都是意外死亡吻商,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門糟红,熙熙樓的掌柜王于貴愁眉苦臉地迎上來艾帐,“玉大人,你說我怎么就攤上這事盆偿∑獍郑” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵事扭,是天一觀的道長捎稚。 經(jīng)常有香客問我,道長求橄,這世上最難降的妖魔是什么今野? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮罐农,結(jié)果婚禮上条霜,老公的妹妹穿的比我還像新娘。我一直安慰自己涵亏,他們只是感情好宰睡,可當(dāng)我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著气筋,像睡著了一般拆内。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上宠默,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天矛纹,我揣著相機與錄音,去河邊找鬼光稼。 笑死或南,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的艾君。 我是一名探鬼主播采够,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼冰垄!你這毒婦竟也來了蹬癌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎逝薪,沒想到半個月后隅要,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡董济,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年步清,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片虏肾。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡廓啊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出封豪,到底是詐尸還是另有隱情谴轮,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布吹埠,位于F島的核電站第步,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏缘琅。R本人自食惡果不足惜雌续,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望胯杭。 院中可真熱鬧驯杜,春花似錦、人聲如沸做个。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽居暖。三九已至顽频,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間太闺,已是汗流浹背糯景。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留省骂,地道東北人蟀淮。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像钞澳,于是被迫代替她去往敵國和親怠惶。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容