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 都可以從頁面上看到,非常直觀。
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 中。
提一下,如果要註銷掉某個服務,可以通過如下 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 下查看是否配置成功。
可以看到,在 Targets 中能夠成功的自動發現 Consul 中的 Services 信息,後期需要添加新的 Targets 時,只需要通過 API 往 Consul 中註冊服務即可,Prometheus 就能自動發現該服務,是不是很方便。
不過,我們會發現有如下幾個問題:
- 會發現 Prometheus 同時加載出來了默認服務 consul,這個是不需要的。
- 默認只顯示 job 及 instance 兩個標籤,其他標籤都默認屬於
before relabeling
下,有些必要的服務信息,也想要在標籤中展示,該如何操作呢? - 如果需要自定義一些標籤,例如 team、group、project 等關鍵分組信息,方便後邊 alertmanager 進行告警規則匹配,該如何處理呢?
- 所有 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 標籤,所以我們能夠在頁面看到該標籤。
詳細 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
這個服務了。
問題二和問題三可以歸爲一類,就是將系統默認標籤或者用戶自定義標籤轉換成可視化標籤,方便查看及後續 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-boot
,team=appgroup
,project=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 信息。
然後修改 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-boot
、team=appgroup
、project=bigdata
三個標籤。重啓 Prometheus 服務,可以看到新增了對應了三個自定義標籤。
問題四,將自動發現的服務進行分類,本質上跟上邊的處理方式一致,可以添加自定義的標籤方式,通過標籤來區分,二可以通過服務 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 控制檯可以看到成功註冊了這兩個服務。
最後,我們修改 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 服務,可以看到服務已經按照類型分類了,方便查看。
參考資料