天天看点

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 都可以从页面上看到,非常直观。

Prometheus 通过 consul 实现自动服务发现

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 中。

Prometheus 通过 consul 实现自动服务发现
Prometheus 通过 consul 实现自动服务发现

提一下,如果要注销掉某个服务,可以通过如下 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 下查看是否配置成功。

Prometheus 通过 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 标签,所以我们能够在页面看到该标签。

Prometheus 通过 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

这个服务了。

Prometheus 通过 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-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
           

注册完毕,通过 Consul Web 管理页面可以查看到已注册成功,并且包含了 Meta 信息。

Prometheus 通过 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-boot

team=appgroup

project=bigdata

三个标签。重启 Prometheus 服务,可以看到新增了对应了三个自定义标签。

Prometheus 通过 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 控制台可以看到成功注册了这两个服务。

Prometheus 通过 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
           
  • Consule Docs
  • Consule Service API
  • Prometheus configurations