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


轉載自:https://cloud.tencent.com/developer/article/1536967

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 都可以從頁面上看到,非常直觀。

img

3.2、Docker 安裝

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

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

啟動完畢后,同上方法驗證是否啟動成功,這里為了方便演示,我采用 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

執行完畢后,刷新一下 Consul Web 控制台頁面,可以看到成功注冊到 Consul 中。

img

img

提一下,如果要注銷掉某個服務,可以通過如下 API 命令操作,例如注銷上邊添加的 node-exporter 服務

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

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 下查看是否配置成功。

img

可以看到,在 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 標簽,所以我們能夠在頁面看到該標簽。

img

詳細 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 這個服務了。

img

問題二和問題三可以歸為一類,就是將系統默認標簽或者用戶自定義標簽轉換成可視化標簽,方便查看及后續 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

注冊完畢,通過 Consul Web 管理頁面可以查看到已注冊成功,並且包含了 Meta 信息。

img

然后修改 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 服務,可以看到新增了對應了三個自定義標簽。

img

問題四,將自動發現的服務進行分類,本質上跟上邊的處理方式一致,可以添加自定義的標簽方式,通過標簽來區分,二可以通過服務 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 控制台可以看到成功注冊了這兩個服務。

img

最后,我們修改 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 服務,可以看到服務已經按照類型分類了,方便查看。

img

參考資料


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM