Prometheus 通過 consul 實現自動服務發現

1、Consul 介紹

Consul 是基於 GO 語言開發的開源工具,主要面向分佈式,服務化的系統提供服務註冊、服務發現和配置管理的功能。Consul 提供服務註冊/發現、健康檢查、Key/Value存儲、多數據中心和分佈式一致性保證等功能。之前我們通過 Prometheus 實現監控,當新增一個 Target 時,需要變更服務器上的配置文件,即使使用 file_sd_configs 配置,也需要登錄服務器修改對應 Json 文件,會非常麻煩。不過 Prometheus 官方支持多種自動服務發現的類型,其中就支持 Consul。

2、環境、軟件準備

本次演示環境,我是在虛擬機上安裝 Linux 系統來執行操作,以下是安裝的軟件及版本:

  • Oracle VirtualBox: 5.1.20 r114628 (Qt5.6.2)
  • System: CentOS Linux release 7.3.1611 (Core)
  • Docker: 18.06.1-ce
  • Prometheus: v2.11.1
  • Consul: 1.6.1

注意:這裏爲了方便啓動 Prometheus、Consul服務,我使用 Docker 方式啓動,所以本機需要安裝好 Docker 環境,這裏忽略 Docker 的安裝過程。其中 Prometheus 安裝配置,可以參照之前文章 Prometheus 監控報警系統 AlertManager 之郵件告警,這裏着重介紹一下如何啓動並配置 Consul 並配置 Prometheus 基於 Consul 實現自動服務發現。

3、Consul 安裝配置

Consul 安裝很方便,官網 提供各個系統版本二進制安裝包,解壓安裝即可,同時也可以通過 Docker 來快速安裝。

3.1、源碼安裝

以 Linux 系統爲例,源碼安裝並以開發模式啓動一個單節點,下載最新版二進制安裝包,解壓啓動即可。

$ wget https://releases.hashicorp.com/consul/1.6.1/consul_1.6.1_linux_amd64.zip
$ unzip consul_1.5.3_linux_amd64.zip
$ ./consul agent -dev    

啓動完畢後,瀏覽器訪問 http://127.0.0.1:8500 地址,即可打開 Consul Web 管理頁面。可以看到默認只有 consul 一個 Service,後期我們註冊到 Consul 的 Service 都可以從頁面上看到,非常直觀。
promethues-consul

3.2、Docker 安裝

使用 Docker 啓動 Consul 單節點服務,直接獲取最新版官方鏡像 consul:latest 命令如下:

$ docker run --name consul -d -p 8500:8500 consul
  • 1

啓動完畢後,同上方法驗證是否啓動成功,這裏爲了方便演示,我採用 Docker 方式啓動 Consul,這裏的訪問地址爲:http://172.30.12.167:8500

4、API 註冊服務到 Consul

接下來,我們要註冊服務到 Consul 中,可以通過其提供的 API 標準接口來添加。那麼先註冊一個測試服務,該測試數據爲本機 node-exporter 服務信息,服務地址及端口爲 node-exporter 默認提供指標數據的地址,執行如下命令:

$ curl -X PUT -d '{"id": "node-exporter","name": "node-exporter-172.30.12.167","address": "172.30.12.167","port": 9100,"tags": ["test"],"checks": [{"http": "http://172.30.12.167:9100/metrics", "interval": "5s"}]}'  http://172.30.12.167:8500/v1/agent/service/register
  • 1

執行完畢後,刷新一下 Consul Web 控制檯頁面,可以看到成功註冊到 Consul 中。
promethues-consul
promethues-consul
提一下,如果要註銷掉某個服務,可以通過如下 API 命令操作,例如註銷上邊添加的 node-exporter 服務

$ curl -X PUT http://172.30.12.167:8500/v1/agent/service/deregister/node-exporter 
  • 1

5、配置 Prometheus 實現自動服務發現

現在 Consul 服務已經啓動完畢,併成功註冊了一個服務,接下來,我們需要配置 Prometheus 來使用 Consul 自動服務發現,目的就是能夠將上邊添加的服務自動發現到 Prometheus 的 Targets 中,增加 prometheus.yml 配置如下:

...
- job_name: 'consul-prometheus'
  consul_sd_configs:
  - server: '172.30.12.167:8500'
    services: []  

說明一下:這裏需要使用 consul_sd_configs 來配置使用 Consul 服務發現類型,server 爲 Consul 的服務地址,這裏跟上邊要對應上。 配置完畢後,重啓 Prometheus 服務,此時可以通過 Prometheus UI 頁面的 Targets 下查看是否配置成功。
promethues-consul
可以看到,在 Targets 中能夠成功的自動發現 Consul 中的 Services 信息,後期需要添加新的 Targets 時,只需要通過 API 往 Consul 中註冊服務即可,Prometheus 就能自動發現該服務,是不是很方便。

不過,我們會發現有如下幾個問題:

  1. 會發現 Prometheus 同時加載出來了默認服務 consul,這個是不需要的。
  2. 默認只顯示 job 及 instance 兩個標籤,其他標籤都默認屬於 before relabeling 下,有些必要的服務信息,也想要在標籤中展示,該如何操作呢?
  3. 如果需要自定義一些標籤,例如 team、group、project 等關鍵分組信息,方便後邊 alertmanager 進行告警規則匹配,該如何處理呢?
  4. 所有 Consul 中註冊的 Service 都會默認加載到 Prometheus 下配置的 consul_prometheus 組,如果有多種類型的 exporter,如何在 Prometheus 中配置分配給指定類型的組,方便直觀的區別它們?

以上問題,我們可以通過 Prometheus 配置中的 relabel_configs 參數來解決。

6、配置 relabel_configs 實現自定義標籤及分類

我們先來普及一下 relabel_configs 的功能, Prometheus 允許用戶在採集任務設置中,通過 relabel_configs 來添加自定義的 Relabeling 的額過程,來對標籤進行指定規則的重寫。 Prometheus 加載 Targets 後,這些 Targets 會自動包含一些默認的標籤,Target 以 __ 作爲前置的標籤是在系統內部使用的,這些標籤不會被寫入到樣本數據中。眼尖的會發現,每次增加 Target 時會自動增加一個 instance 標籤,而 instance 標籤的內容剛好對應 Target 實例的 __address__ 值,這是因爲實際上 Prometheus 內部做了一次標籤重寫處理,默認 __address__ 標籤設置爲 <host>:<port> 地址,經過標籤重寫後,默認會自動將該值設置爲 instance 標籤,所以我們能夠在頁面看到該標籤。
promethues-consul
詳細 relabel_configs 配置及說明可以參考 relabel_config 官網說明,這裏我簡單列舉一下里面每個 relabel_action 的作用,方便下邊演示。

  • replace: 根據 regex 的配置匹配 source_labels 標籤的值(注意:多個 source_label 的值會按照 separator 進行拼接),並且將匹配到的值寫入到 target_label 當中,如果有多個匹配組,則可以使用 ${1}, ${2} 確定寫入的內容。如果沒匹配到任何內容則不對 target_label 進行重新, 默認爲 replace。
  • keep: 丟棄 source_labels 的值中沒有匹配到 regex 正則表達式內容的 Target 實例
  • drop: 丟棄 source_labels 的值中匹配到 regex 正則表達式內容的 Target 實例
  • hashmod: 將 target_label 設置爲關聯的 source_label 的哈希模塊
  • labelmap: 根據 regex 去匹配 Target 實例所有標籤的名稱(注意是名稱),並且將捕獲到的內容作爲爲新的標籤名稱,regex 匹配到標籤的的值作爲新標籤的值
  • labeldrop: 對 Target 標籤進行過濾,會移除匹配過濾條件的所有標籤
  • labelkeep: 對 Target 標籤進行過濾,會移除不匹配過濾條件的所有標籤

接下來,我們來挨個處理上述問題。

問題一,我們可以配置 relabel_configs 來實現標籤過濾,只加載符合規則的服務。以上邊爲例,可以通過過濾 __meta_consul_tags 標籤爲 test 的服務,relabel_config 向 Consul 註冊服務的時候,只加載匹配 regex 表達式的標籤的服務到自己的配置文件。修改 prometheus.yml 配置如下:

...
- job_name: 'consul-prometheus'
  consul_sd_configs:
    - server: '172.30.12.167:8500'
      services: []  
  relabel_configs:
    - source_labels: [__meta_consul_tags]
      regex: .*test.*
      action: keep

解釋下,這裏的 relabel_configs 配置作用爲丟棄源標籤中 __meta_consul_tags 不包含 test 標籤的服務,__meta_consul_tags 對應到 Consul 服務中的值爲 "tags": ["test"],默認 consul 服務是不帶該標籤的,從而實現過濾。重啓 Prometheus 可以看到現在只獲取了 node-exporter-172.30.12.167 這個服務了。
promethues-consul
問題二和問題三可以歸爲一類,就是將系統默認標籤或者用戶自定義標籤轉換成可視化標籤,方便查看及後續 Alertmanager 進行告警規則匹配分組。不過要實現給服務添加自定義標籤,我們還得做一下修改,就是在註冊服務時,將自定義標籤信息添加到 Meta Data 數據中,具體可以參考 [這裏](Consul Service - Agent HTTP API) 官網說明,下邊來演示一下如何操作。

新建 consul-0.json 如下:

$ vim consul-0.json
{
  "ID": "node-exporter",
  "Name": "node-exporter-172.30.12.167",
  "Tags": [
    "test"
  ],
  "Address": "172.30.12.167",
  "Port": 9100,
  "Meta": {
    "app": "spring-boot",
    "team": "appgroup",
    "project": "bigdata"
  },
  "EnableTagOverride": false,
  "Check": {
    "HTTP": "http://172.30.12.167:9100/metrics",
    "Interval": "10s"
  },
  "Weights": {
    "Passing": 10,
    "Warning": 1
  }
}

說明一下:該 Json 文件爲要註冊的服務信息,同時往 Meta 信息中添加了 app=spring-bootteam=appgroupproject=bigdata 三組標籤,目的就是爲了方便告警分組使用。執行如下命令進行註冊:

$ curl --request PUT --data @consul-0.json http://172.30.12.167:8500/v1/agent/service/register?replace-existing-checks=1
  • 1

註冊完畢,通過 Consul Web 管理頁面可以查看到已註冊成功,並且包含了 Meta 信息。
promethues-consul
然後修改 prometheus.yml 配置如下:

...
- job_name: 'consul-prometheus'
  consul_sd_configs:
    - server: '172.30.12.167:8500'
      services: []  
  relabel_configs:
    - source_labels: [__meta_consul_tags]
      regex: .*test.*
      action: keep
    - regex: __meta_consul_service_metadata_(.+)
      action: labelmap

解釋一下,增加的配置作用爲匹配 __meta_consul_service_metadata_ 開頭的標籤,將捕獲到的內容作爲新的標籤名稱,匹配到標籤的的值作爲新標籤的值,而我們剛添加的三個自定義標籤,系統會自動添加 __meta_consul_service_metadata_app=spring-boot__meta_consul_service_metadata_team=appgroup__meta_consul_service_metadata_project=bigdata 三個標籤,經過 relabel 後,Prometheus 將會新增 app=spring-bootteam=appgroupproject=bigdata 三個標籤。重啓 Prometheus 服務,可以看到新增了對應了三個自定義標籤。
promethues-consul
問題四,將自動發現的服務進行分類,本質上跟上邊的處理方式一致,可以添加自定義的標籤方式,通過標籤來區分,二可以通過服務 Tag 來進行匹配來創建不同的類型 exporter 分組。這裏我以第二種爲例,通過給每個服務標記不同的 Tag,然後通過 relabel_configs 來進行匹配區分。我們來更新一下原 node-exporter-172.30.12.167 服務標籤,同時註冊一個其他類型 exporter 的服務如下:

$ vim consul-1.json
{
  "ID": "node-exporter",
  "Name": "node-exporter-172.30.12.167",
  "Tags": [
    "node-exporter"
  ],
  "Address": "172.30.12.167",
  "Port": 9100,
  "Meta": {
    "app": "spring-boot",
    "team": "appgroup",
    "project": "bigdata"
  },
  "EnableTagOverride": false,
  "Check": {
    "HTTP": "http://172.30.12.167:9100/metrics",
    "Interval": "10s"
  },
  "Weights": {
    "Passing": 10,
    "Warning": 1
  }
}

# 更新註冊服務
$ curl --request PUT --data @consul-1.json http://172.30.12.167:8500/v1/agent/service/register?replace-existing-checks=1

$ vim consul-2.json
{
“ID”: “cadvisor-exporter”,
“Name”: “cadvisor-exporter-172.30.12.167”,
“Tags”: [
“cadvisor-exporter”
],
“Address”: “172.30.12.167”,
“Port”: 8080,
“Meta”: {
“app”: “docker”,
“team”: “cloudgroup”,
“project”: “docker-service”
},
“EnableTagOverride”: false,
“Check”: {
“HTTP”: “http://172.30.12.167:8080/metrics”,
“Interval”: “10s”
},
“Weights”: {
“Passing”: 10,
“Warning”: 1
}
}

# 註冊服務
$ curl --request PUT --data @consul-2.json http://172.30.12.167:8500/v1/agent/service/register?replace-existing-checks=1

說明一下,我們更新了原 node-exporter-172.30.12.167 服務的標籤爲 node-exporter,同時註冊一個新類型 cadvisor-exporter-172.30.12.167 服務,並設置標籤爲 cadvisor-exporter,以示區別。註冊完畢,通過 Consul Web 控制檯可以看到成功註冊了這兩個服務。
promethues-consul
最後,我們修改 prometheus.yml 配置如下:

...
  - job_name: 'consul-node-exporter'
    consul_sd_configs:
      - server: '172.30.12.167:8500'
        services: []  
    relabel_configs:
      - source_labels: [__meta_consul_tags]
        regex: .*node-exporter.*
        action: keep
      - regex: __meta_consul_service_metadata_(.+)
        action: labelmap

- job_name: ‘consul-cadvisor-exproter’
consul_sd_configs:
- server: ‘172.30.12.167:8500’
services: []
relabel_configs:
- source_labels: [__meta_consul_tags]
regex: .cadvisor-exporter.
action: keep
- regex: _meta_consul_service_metadata(.+)
action: labelmap

這裏需要根據每種類型的 exporter 新增一個關聯 job,同時 relabel_configs 中配置以 Tag 來做匹配區分。重啓 Prometheus 服務,可以看到服務已經按照類型分類了,方便查看。
promethues-consul
參考資料

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章