服务发现
接下来我们将学习 Prometheus 中是如何使用服务发现来查找和抓取目标的。我们知道在 Prometheus 配置文件中可以通过一个 static_configs
来配置静态的抓取任务,但是在云环境下,特别是容器环境下,抓取目标地址是经常变动的,所以用静态的方式就不能满足这些场景了。所以我们需要监控系统能够动态感知这个变化,不可能每次变动都去手动重新配置的,为了应对复杂的动态环境,Prometheus 也提供了与基础设施中的服务发现集成的功能。
下面这张图可以看到支持k8s,consul,dns,zk,文件这些服务发现。
Prometheus 已经支持多种内置的服务发现机制:
- 发现云服务商的 VM 虚拟机
- Kubernetes 上的自动发现
- 通用的服务查找,例如 DNS、Consul、Zookeeper 或自定义发现机制
我们都可以通过 Prometheus 配置文件中的 scrape_config
部分进行配置,Prometheus 会不断更新动态的抓取目标列表,自动停止抓取旧的实例,开始抓取新的实例,Prometheus 特别适合运行于 Kubernetes 集群下面,可以自动发现监控目标。
此外大部分服务发现机制还会提供目标的一些元数据,通常都是带有 __
的前缀, 比如标签、注解、服务名等等,可以在 relabeling 阶段使用这些元数据来过滤修改目标,这些元信息标签在重新标记阶段后被删除。
基于 Consul 的服务发现
Consul 是由 HashiCorp 开发的一个支持多数据中心的分布式服务发现和键值对存储服务的开源软件,是一个通用的服务发现和注册中心工具,被大量应用于基于微服务的软件架构当中。
接下来我们就来尝试使用 Prometheus 基于 Consul 的服务发现来监控前面的 3 个 demo 服务:
我们将 demo 服务注册到 Consul,然后配置 Prometheus 从 Consul 中发现演示服务实例,并使用 Relabeling 操作来过滤调整目标标签。关于 Consul 本身的使用可以查看官方文档 Consul Tutorials - HashiCorp Learn 了解更多。
下面是consul发现的一个基本的方式,在Prometheus当中会去watch consul agent的变化,如果变化了会去更新target。
安装配置 Consul
在页面 Downloads | Consul by HashiCorp 下载符合自己系统的安装文件,比如我们这里是 Linux 系统,使用下面命令下载安装即可:
☸ ➜ wget https://releases.hashicorp.com/consul/1.10.2/consul_1.10.2_linux_amd64.zip
☸ ➜ unzip consul_1.10.2_linux_amd64.zip
# 将 consul 二进制移动到 PATH 路径下去
☸ ➜ mv consul /usr/local/bin
☸ ➜ consul version
Consul v1.10.2
Revision 3cb6eeedb
Protocol 2 spoken by default, understands 2 to 3 (agent will automatically use protocol >2 when speaking to compatible agents)
当执行 consul
命令后正常有命令提示,证明已经安装完成。接着创建一个用于注册 demo 服务的 Consul 配置文件 demo-service.json
: (现在需要将三个demo服务注册到consul当中去,需要去创建consul的配置文件)
[root@master ~]# ps -ef | grep demo
root 3022 1 2 14:13 pts/0 00:00:32 ./prometheus_demo_service --listen-address=:10000
root 3023 1 2 14:13 pts/0 00:00:32 ./prometheus_demo_service --listen-address=:10001
root 3024 1 2 14:13 pts/0 00:00:31 ./prometheus_demo_service --listen-address=:10002
{
"services": [
{
"id": "demo1",
"name": "demo",
"address": "192.168.100.5",
"port": 10000,
"meta": {
"env": "production"
}
},
{
"id": "demo2",
"name": "demo",
"address": "192.168.100.5",
"port": 10001,
"meta": {
"env": "production"
}
},
{
"id": "demo3",
"name": "demo",
"address": "192.168.100.5",
"port": 10002,
"meta": {
"env": "staging"
}
}
]
}
当然一般情况下我们也是在 Consul 中进行动态注册服务,但是这里我们只是简单演示 Prometheus 基于 Consul 的服务发现,这里只使用 Consul 配置文件静态注册服务即可。
Consul 允许使用 JSON 中的 meta
属性将 key-value 元数据与每个注册的服务实例相关联,比如这里我们配置的 env
属性和部署环境 production 或 staging 进行关联,后面我们可以通过使用 Prometheus 里面的 Relabeling 操作提取该字段并将其映射到每个抓取实例的标签中去。
为了查看更多的日志信息,我们可以在 dev 模式下运行 Consul,如下所示:
☸ ➜ consul agent -dev -config-file=demo-service.json -client 0.0.0.0
==> Starting Consul agent...
Version: '1.10.2'
Node ID: 'a4a9418c-7f7d-a2da-c81e-94d3d37601aa'
Node name: 'node2'
Datacenter: 'dc1' (Segment: '<all>')
Server: true (Bootstrap: false)
Client Addr: [0.0.0.0] (HTTP: 8500, HTTPS: -1, gRPC: 8502, DNS: 8600)
Cluster Addr: 127.0.0.1 (LAN: 8301, WAN: 8302)
Encrypt: Gossip: false, TLS-Outgoing: false, TLS-Incoming: false, Auto-Encrypt-TLS: false
==> Log data will now stream in as it occurs:
......
这里我们在启动命令后面使用 -client
参数指定了客户端绑定的 IP 地址,默认为 127.0.0.1
。除了我们注册的 3 个 demo 服务之外,Consul agent 还会将自己注册为一个名为 consul
的服务,我们可以在浏览器中访问 http://<nodeip>:8500
查看注册的服务。
访问8500,可以看到有两个service,一个是自带的,还有一个是刚刚我们注册的。
配置 Consul 自动发现
上面我们通过 Consul 注册了 3 个 demo 服务,接下来我们将配置 Prometheus 通过 Consul 来自动发现 demo 服务。
在 Prometheus 的配置文件 prometheus.yml
文件中的 scrape_configs
部分添加如下所示的抓取配置:
scrape_configs:
- job_name: "consul-sd-demo"
consul_sd_configs:
- server: "localhost:8500"
relabel_configs:
- action: keep
source_labels: [__meta_consul_service]
regex: demo
- action: labelmap
regex: __meta_consul_service_metadata_(.*)
replacement: consul_$1
这里我们添加了一个名为 consul-sd-demo
的抓取任务,通过 consul_sd_configs
配置用于自动发现的 Consul 服务地址,然后使用 relabel_configs
进行了重新标记配置,首先只保留服务名称为 demo
,且健康状态为 passing
的,否则也会抓取 Consul Agent 本身,而它自身是不提供 metrics 接口数据的,另外还使用 labelmap
进行了标签映射,将所有 Consul 元标签映射到 Prometheus 中以 consul_
为前缀的标签中。
这里面的这些标签其实就是relabel重新打标签之前可以用到的一些源标签,仔细观察一下这里都有
__meta_consul_service这样的源标签,有两个值一个demo和consul。所以只需要做一个keep操作将demo的保留下来就行。
- action: keep
source_labels: [__meta_consul_service]
regex: demo
还有一点在做配置的时候我们自定义了一些标签,如果能够将这些标签添加到抓取过后的标签当中来,那么使用promsql的时候就可以很方便的过滤生产环境或者staging环境。
可以将这个标签映射一下得到新的标签,值不变!
- action: labelmap
regex: __meta_consul_service_metadata_(.*)