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

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

經過服務發現的方式,咱們能夠在不重啓Prometheus服務的狀況下動態的發現須要監控的Target實例信息。正則表達式

image

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

然而,若是咱們可能還須要:json

  • 按照不一樣的環境dev, stage, prod聚合監控數據?
  • 對於研發團隊而言,我可能只關心dev環境的監控數據,如何處理?
  • 若是爲每個團隊單獨搭建一個Prometheus Server。那麼如何讓不一樣團隊的Prometheus Server採集不一樣的環境監控數據?

面對以上這些場景下的需求時,咱們其實是但願Prometheus Server可以按照某些規則(好比標籤)從服務發現註冊中心返回的Target實例中有選擇性的採集某些Exporter實例的監控數據。bash

接下來,咱們實驗如何經過Prometheus強大的Relabel機制來實現以上這些具體的目標。服務器

Prometheus的Relabeling機制

在Prometheus全部的Target實例中,都包含一些默認的Metadata標籤信息。能夠經過Prometheus UI的Targets頁面中查看這些實例的Metadata標籤的內容:運維

image

默認狀況下,當Prometheus加載Target實例完成後,這些Target時候都會包含一些默認的標籤:ide

  • __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__。 這裏其實是發生了一次標籤的重寫處理。ui

這種發生在採集樣本數據以前,對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或者採集到的樣本的標籤中。

相關文章
相關標籤/搜索