Prometheus監控神器-服務發現篇(二)

本章節講解服務發現與Relabelling的機制與范例。

通過服務發現的方式,我們可以在不重啟Prometheus服務的情況下動態的發現需要監控的Target實例信息。

image

如上圖所示,對于線上環境我們可能會劃分為:dev, stage, prod不同的集群。每一個集群運行多個主機節點,每個服務器節點上運行一個Node Exporter實例。Node Exporter實例會自動注冊到Consul中,而Prometheus則根據Consul返回的Node Exporter實例信息動態的維護Target列表,從而向這些Target輪詢監控數據。

然而,如果我們可能還需要:

  • 按照不同的環境dev, stage, prod聚合監控數據?
  • 對于研發團隊而言,我可能只關心dev環境的監控數據,如何處理?
  • 如果為每一個團隊單獨搭建一個Prometheus Server。那么如何讓不同團隊的Prometheus Server采集不同的環境監控數據?

面對以上這些場景下的需求時,我們實際上是希望Prometheus Server能夠按照某些規則(比如標簽)從服務發現注冊中心返回的Target實例中有選擇性的采集某些Exporter實例的監控數據。

接下來,我們實驗如何通過Prometheus強大的Relabel機制來實現以上這些具體的目標。

Prometheus的Relabeling機制

在Prometheus所有的Target實例中,都包含一些默認的Metadata標簽信息。可以通過Prometheus UI的Targets頁面中查看這些實例的Metadata標簽的內容:

image

默認情況下,當Prometheus加載Target實例完成后,這些Target時候都會包含一些默認的標簽:

  • __address__:當前Target實例的訪問地址<host>:<port>
  • __scheme__:采集目標服務訪問地址的HTTP Scheme,HTTP或者HTTPS
  • __metrics_path__:采集目標服務訪問地址的訪問路徑
  • __param_<name>:采集任務目標服務的中包含的請求參數

上面這些標簽將會告訴Prometheus如何從該Target實例中獲取監控數據。除了這些默認的標簽以外,我們還可以為Target添加自定義的標簽,例如,在“基于文件的服務發現”小節中的示例中,我們通過JSON配置文件,為Target實例添加了自定義標簽env,如下所示該標簽最終也會保存到從該實例采集的樣本數據中:

node_cpu{cpu="cpu0",env="prod",instance="localhost:9100",job="node",mode="idle"}

一般來說,Target以__作為前置的標簽是在系統內部使用的,因此這些標簽不會被寫入到樣本數據中。不過這里有一些例外,例如,我們會發現所有通過Prometheus采集的樣本數據中都會包含一個名為instance的標簽,該標簽的內容對應到Target實例的address。 這里實際上是發生了一次標簽的重寫處理。

這種發生在采集樣本數據之前,對Target實例的標簽進行重寫的機制在Prometheus被稱為Relabeling。

image

Prometheus允許用戶在采集任務設置中通過relabel_configs來添加自定義的Relabeling過程。

使用replace/labelmap重寫標簽

Relabeling最基本的應用場景就是基于Target實例中包含的metadata標簽,動態的添加或者覆蓋標簽。例如,通過Consul動態發現的服務實例還會包含以下Metadata標簽信息:

  • __meta_consul_address:consul地址
  • __meta_consul_dc:consul服務所在的數據中心
  • __meta_consulmetadata:服務的metadata
  • __meta_consul_node:consul服務node節點的信息
  • __meta_consul_service_address:服務訪問地址
  • __meta_consul_service_id:服務ID
  • __meta_consul_service_port:服務端口
  • __meta_consul_service:服務名稱
  • __meta_consul_tags:服務包含的標簽信息

在默認情況下,從Node Exporter實例采集上來的樣本數據如下所示:

node_cpu{cpu="cpu0",instance="localhost:9100",job="node",mode="idle"} 93970.8203125

我們希望能有一個額外的標簽dc可以表示該樣本所屬的數據中心:

node_cpu{cpu="cpu0",instance="localhost:9100",job="node",mode="idle", dc="dc1"} 93970.8203125

在每一個采集任務的配置中可以添加多個relabel_config配置,一個最簡單的relabel配置如下:

scrape_configs:
  - job_name: node_exporter
    consul_sd_configs:
      - server: localhost:8500
        services:
          - node_exporter
    relabel_configs:
    - source_labels:  ["__meta_consul_dc"]
      target_label: "dc"

該采集任務通過Consul動態發現Node Exporter實例信息作為監控采集目標。在上一小節中,我們知道通過Consul動態發現的監控Target都會包含一些額外的Metadata標簽,比如標簽__meta_consul_dc表明了當前實例所在的Consul數據中心,因此我們希望從這些實例中采集到的監控樣本中也可以包含這樣一個標簽,例如:

node_cpu{cpu="cpu0",dc="dc1",instance="172.21.0.6:9100",job="consul_sd",mode="guest"}

這樣可以方便的根據dc標簽的值,根據不同的數據中心聚合分析各自的數據。

在這個例子中,通過從Target實例中獲取__meta_consul_dc的值,并且重寫所有從該實例獲取的樣本中。

完整的relabel_config配置如下所示:

# The source labels select values from existing labels. Their content is concatenated
# using the configured separator and matched against the configured regular expression
# for the replace, keep, and drop actions.
[ source_labels: '[' <labelname> [, ...] ']' ]

# Separator placed between concatenated source label values.
[ separator: <string> | default = ; ]

# Label to which the resulting value is written in a replace action.
# It is mandatory for replace actions. Regex capture groups are available.
[ target_label: <labelname> ]

# Regular expression against which the extracted value is matched.
[ regex: <regex> | default = (.*) ]

# Modulus to take of the hash of the source label values.
[ modulus: <uint64> ]

# Replacement value against which a regex replace is performed if the
# regular expression matches. Regex capture groups are available.
[ replacement: <string> | default = $1 ]

# Action to perform based on regex matching.
[ action: <relabel_action> | default = replace ]

其中action定義了當前relabel_config對Metadata標簽的處理方式,默認的action行為為replace。 replace行為會根據regex的配置匹配source_labels標簽的值(多個source_label的值會按照separator進行拼接),并且將匹配到的值寫入到target_label當中,如果有多個匹配組,則可以使用{1},{2}確定寫入的內容。如果沒匹配到任何內容則不對target_label進行重新。

repalce操作允許用戶根據Target的Metadata標簽重寫或者寫入新的標簽鍵值對,在多環境的場景下,可以幫助用戶添加與環境相關的特征維度,從而可以更好的對數據進行聚合。

除了使用replace以外,還可以定義action的配置為labelmap。與replace不同的是,labelmap會根據regex的定義去匹配Target實例所有標簽的名稱,并且以匹配到的內容為新的標簽名稱,其值作為新標簽的值。

例如,在監控Kubernetes下所有的主機節點時,為將這些節點上定義的標簽寫入到樣本中時,可以使用如下relabel_config配置:

- job_name: 'kubernetes-nodes'
  kubernetes_sd_configs:
  - role: node
  relabel_configs:
  - action: labelmap
    regex: __meta_kubernetes_node_label_(.+)

而使用labelkeep或者labeldrop則可以對Target標簽進行過濾,僅保留符合過濾條件的標簽,例如:

relabel_configs:
  - regex: label_should_drop_(.+)
    action: labeldrop

該配置會使用regex匹配當前Target實例的所有標簽,并將符合regex規則的標簽從Target實例中移除。labelkeep正好相反,會移除那些不匹配regex定義的所有標簽。

使用keep/drop過濾Target實例

在上一部分中我們介紹了Prometheus的Relabeling機制,并且使用了replace/labelmap/labelkeep/labeldrop對標簽進行管理。而本節開頭還提到過第二個問題,使用中心化的服務發現注冊中心時,所有環境的Exporter實例都會注冊到該服務發現注冊中心中。而不同職能(開發、測試、運維)的人員可能只關心其中一部分的監控數據,他們可能各自部署的自己的Prometheus Server用于監控自己關心的指標數據,如果讓這些Prometheus Server采集所有環境中的所有Exporter數據顯然會存在大量的資源浪費。如何讓這些不同的Prometheus Server采集各自關心的內容?答案還是Relabeling,relabel_config的action除了默認的replace以外,還支持keep/drop行為。例如,如果我們只希望采集數據中心dc1中的Node Exporter實例的樣本數據,那么可以使用如下配置:

scrape_configs:
  - job_name: node_exporter
    consul_sd_configs:
      - server: localhost:8500
        services:
          - node_exporter
    relabel_configs:
    - source_labels:  ["__meta_consul_dc"]
      regex: "dc1"
      action: keep

當action設置為keep時,Prometheus會丟棄source_labels的值中沒有匹配到regex正則表達式內容的Target實例,而當action設置為drop時,則會丟棄那些source_labels的值匹配到regex正則表達式內容的Target實例。可以簡單理解為keep用于選擇,而drop用于排除。

使用hashmod計算source_labels的Hash值

當relabel_config設置為hashmod時,Prometheus會根據modulus的值作為系數,計算source_labels值的hash值。例如:

scrape_configs
- job_name: 'file_ds'
  relabel_configs:
    - source_labels: [__address__]
      modulus:       4
      target_label:  tmp_hash
      action:        hashmod
  file_sd_configs:
  - files:
    - targets.json

根據當前Target實例address的值以4作為系數,這樣每個Target實例都會包含一個新的標簽tmp_hash,并且該值的范圍在1~4之間,查看Target實例的標簽信息,可以看到如下的結果,每一個Target實例都包含了一個新的tmp_hash值:

利用Hashmod的能力在Target實例級別實現對采集任務的功能分區的:

scrape_configs:
  - job_name: some_job
    relabel_configs:
    - source_labels: [__address__]
      modulus:       4
      target_label:  __tmp_hash
      action:        hashmod
    - source_labels: [__tmp_hash]
      regex:         ^1$
      action:        keep

這里需要注意的是,如果relabel的操作只是為了產生一個臨時變量,以作為下一個relabel操作的輸入,那么我們可以使用 __tmp 作為標簽名的前綴,通過該前綴定義的標簽就不會寫入到Target或者采集到的樣本的標簽中。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,363評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,497評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,305評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,962評論 1 311
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,727評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,193評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,257評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,411評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,945評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,777評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,978評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,519評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,216評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,657評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,960評論 2 373