一、prometheus的动态服务发现------基于consul的服务发现
1.1、基于consul的服务发现
Consul 是基于GO语言开发的开源工具,提供服务注册、服务发现、健康检查、Key/Value存储、多数据中心和分布式一致性保证等功能。之前我们通过 Prometheus 实现监控,当新增一个 Target 时,需要变更服务器上的配置文件(即:基于文件的服务发现------使用 file_sd_configs 配置),但是需要登录服务器修改对应 json或yml 文件,还是比较麻烦。不过 Prometheus 官方支持多种自动服务发现的类型,其中就支持 Consul。
1.2、安装consul
consul的安装是较为方便的,consul开源项目提供了各个系统版本的二进制安装包,可直接下来解压安装就行。也可以通过Docker来快速安装。
红帽系、银河麒麟V10系统中成功安装部署Docker-ce引擎与Docker-Compose保姆级教程
https://blog.csdn.net/xiaochenXIHUA/article/details/154187536银河麒麟高级服务器中Docker容器的安装部署与管理实操保姆级教程_银河麒麟 服务器版 容器管理是什么
https://blog.csdn.net/xiaochenXIHUA/article/details/155027993
bash
#在Dokcer容器中快速安装consul
#1-先查看docker容器宿主机的8500端口是否被占用,不被占用才可使用,否则需要修改
netstat -antlp | grep 8500
#2-直接在docker容器中下载运行consul容器
docker run -d \
-p 8500:8500 \
--restart=always \
-v /data/consul/data:/consul/data \
-v /etc/localtime:/etc/localtime:ro \
-v /etc/timezone:/etc/timezone:ro \
--name=consul \
hashicorp/consul:1.22.3 \
agent -server -bootstrap -ui -node=ck-dc1 -client='0.0.0.0'
#3-查看当前运行的consul容器
docker ps | grep consul
#4-在浏览器访问该Docker宿主机的8500端口(能够正常显示consul的管理web界面则表示安装成功)
ip a
#5-查看consul容器的日志
#1-查看consul容器的所有日志
docker logs consul
#2-查看consul容器最新的60行日志
docker logs --tail 60 consul
#3-实时跟踪consul容器的日志
docker logs -f consul
#4-实时跟踪consule容器最新 60 行日志
docker logs -f --tail 60 consul
#5-查看最近N分钟/小时的日志
docker logs --since 15m consul
docker logs --since 1h consul
#6-查看指定时间段的日志(精确到时间戳)
docker logs --since "2026-01-28T10:30:00" --until "2026-01-28T10:35:00" consul
#7-查看容器的全部日志(包括启动失败的报错)并输出到文件中
docker logs --details consul > consul-logs.txt
|--------|-----------------------------------------|---------------------------------------------------------------------------------------------------------------|
| 序号 | docker核心运行参数 | 说明 |
| 1 | docker run | Docker 启动容器的基础命令 |
| 2 | -d | 后台运行容器(守护进程模式),不会占用当前终端 |
| 3 | -p 8500:8500 | 端口映射:将宿主机的 8500 端口映射到容器内的 8500 端口(Consul UI 和 HTTP API 默认端口) 注意:-p后的第一个8500是宿主机的端口,需要确保该端口不被占用 |
| 4 | --restart=always | 容器重启策略:无论容器退出码是什么,Docker 都会始终重启该容器(宿主机重启、容器异常退出时自动恢复) |
| 5 | -v /data/consul/data:/consul/data | 数据卷挂载:将宿主机 /data/consul/data 目录挂载到容器内 /consul/data,实现 Consul 数据持久化(容器删除后数据不丢失) |
| 6 | -v /etc/localtime:/etc/localtime:ro | 挂载宿主机时区文件(ro 表示只读),保证容器内时区与宿主机一致 |
| 7 | -v /etc/timezone:/etc/timezone:ro | 挂载宿主机时区配置文件,进一步确保时区同步 |
| 8 | --name=consul | 给容器命名为 consul,方便后续通过 docker ps/stop/restart 等命令管理 |
| 9 | hashicorp/consul:1.22.3 | 指定要运行的镜像:HashiCorp 官方的 Consul 镜像,版本为 1.22.3(固定版本避免自动更新导致兼容问题) |
| |||
| 序号 | consul启动参数 | 说明 |
| 1 | agent | Consul 的核心运行模式(启动 Consul 代理) |
| 2 | -server | 以服务器节点模式运行(Consul 集群的核心节点,负责数据存储、选举等) |
| 3 | -bootstrap | 表示这个节点是 Server-Leader ,每个数据中心只能运行一台服务器。技术角度上讲 Leader 是通过 Raft 算法选举的,但是集群第一次启动时需要一个引导 Leader,在引导群集后,建议不要使用此标志。 |
| 4 | -ui | 表示启动 Web UI 管理器,默认开放端口 8500,所以上面使用 Docker 命令把 8500 端口对外开放。 |
| 5 | -node=ck-dc1 | 设置该 Consul 节点的名称为 ck-dc1(集群内该节点名称必须唯一) |
| 6 | -client='0.0.0.0' | consul服务侦听地址,这个地址提供HTTP、DNS、RPC等服务,默认是127.0.0.1所以不对外提供服务,若你要对外提供服务则改成0.0.0.0 |
[docker核心运行参数与consul启动参数说明]




1.3、使用consul api注册或删除服务
consul服务注册提供了两种方法:《1》是定义配置文件服务注册(即:在配置文件中定义服务来进行注册)。《2》是HTTP API服务注册(即:通过调用consul api进行自我注册)。
bash
#使用consul api注册服务
#1-先编写一个需要注册服务的文件
vi test.json
#【test.json】文件的内容如下(注意:每个需要注册服务的id必须唯一,若相同则会被覆盖):
{
"id": "node-exporter",
"name": "node-exporter-192.168.1.37",
"address": "192.168.1.37",
"port": 9100,
"tags": ["test"],
"checks": [{
"http": "http://192.168.1.37:9100/metrics",
"interval": "5s"
}]
}
#2-调用consul api注册服务
curl --request PUT --data @test.json http://192.168.1.25:8500/v1/agent/service/register
#3-在consul的web界面的【services】选项内即可看到最新添加的服务
#注意:若想删除consul内的指定服务,则执行如下命令(令最后是服务的id)
curl --request PUT http://192.168.1.25:8500/v1/agent/service/deregister/node-exporter1



1.4、配置prometheus实现consul所有服务的自动发现
目前consul服务已经启动完成,且我们已经手动调用consul api成功注册了一个服务;接下来我们需要配置prometheus来使用consul自动服务发现,目的就是能够将上面添加的服务自动发现到prometheus的Targets中。
bash
#配置prometheus.yml实现使用consul所有服务的自动发现
#1-进入prometheus路径编辑其配置文件【prometheus.yml】
cd /usr/local/prometheus-3.5.0/
vi prometheus.yml
#2-在【prometheus.yml】的最后【scrape_configs】下添加名为consul-prometheus的内容
- job_name: "consul-prometheus"
consul_sd_configs:
- server: '192.168.1.25:8500'
services: []
#3-验证修改后的prometheus.yml文件的语法是否正确(结果显示SUCCESS则表示正确)
./promtool check config prometheus.yml
#4-验证prometheus.yml文件中的语法正确后热重载让配置生效
curl -XPOST localhost:9090/-/reload
#5-打开浏览器进入Prometheus Server的Web界面【IP:9090】查看【Status-->Target health】即可看到添加的【consul prometheus】节点下的多个地址及其状态【up】表示在线【down】表示离线。
#6-使用consul api注册一个服务到consul中然后在打开浏览器进入Prometheus Server的Web界面【IP:9090】查看【Status-->Target health】下【consul prometheus】节点是否存在刚注册的这个服务
vi test1.json
#【test1.json】文件如下
{
"id": "node-exporter1",
"name": "node-exporter-192.168.1.39",
"address": "192.168.1.39",
"port": 9100,
"tags": ["cktest"],
"checks": [{
"http": "http://192.168.1.39:9100/metrics",
"interval": "5s"
}]
}
|--------|-----------------------|-------------------------|
| 序号 | consul服务发现参数 | 说明 |
| 1 | consul_sd_configs | 表示使用 consul 服务发现类型 |
| 2 | server | 表示 consul 服务地址 |
| 3 | services: [] | 表示匹配 consul 中的所有service |
[prometheus配置文件新增consul所有服务自动发现参数解析]






prometheus是可以自动获取到consul的所有服务了,但是consul默认的服务不是我们需要的,也不需要prometheus采集,需要过滤掉,可执行如下《1.5、使用relabel_configs将自动发现的服务进行分类》实现。
二、使用relabel_configs将自动发现的服务进行分类
2.1、修改原来的test.json文件,新增Meta属性
bash
#修改原来的test.json文件,新增Meta属性(其他的如test1.json文件也是一样的修改)
vi test.json
#【test.json】的完整内容如下:
{
"ID": "node-exporter",
"Name": "node-exporter-192.168.1.37",
"Tags": ["test"],
"Address": "192.168.1.37",
"Port": 9100,
"Meta": {
"app": "hadoop",
"team": "coffeemilk",
"project": "bigdataserver"
},
"EnableTagOverride": false,
"Check": {
"http": "http://192.168.1.37:9100/metrics",
"interval": "5s"
},
"Weights": {
"passing": 10,
"warning": 1
}
}
#更新已经注册的服务
curl --request PUT --data @test.json http://192.168.1.25:8500/v1/agent/service/register?replace-existing-checks=1




2.2、修改prometheus.yml配置实现过滤
bash
#修改prometheus.yml配置实现过滤
#1-进入prometheus路径编辑其配置文件【prometheus.yml】
cd /usr/local/prometheus-3.5.0/
vi prometheus.yml
#2-在【prometheus.yml】的最后【scrape_configs】下名为consul-prometheus的内容新增过滤
- job_name: "consul-prometheus"
consul_sd_configs:
- server: '192.168.1.25:8500'
services: []
relabel_configs:
- source_labels: [__meta_consul_tags]
regex: .*test.*
action: keep
- regex: __meta_consul_service_metadata_(.+)
action: labelmap
#3-验证修改后的prometheus.yml文件的语法是否正确(结果显示SUCCESS则表示正确)
./promtool check config prometheus.yml
#4-验证prometheus.yml文件中的语法正确后热重载让配置生效
curl -XPOST localhost:9090/-/reload
#5-打开浏览器进入Prometheus Server的Web界面【IP:9090】查看【Status-->Target health】即可看到添加的【consul prometheus】节点下的多个地址及其状态【up】表示在线【down】表示离线。



2.3、实现对注册服务的分类
2.3.1、需要对注册服务的tags先进行修改更新
bash
#1-修改原来的test.json文件,修改Tags属性的值为需要分类的名称(如:node-exporter),其他的(如:test1.json也是一样的修改)
vi test.json
#【test.json】的完整内容如下:
{
"ID": "node-exporter",
"Name": "node-exporter-192.168.1.37",
"Tags": ["node-exporter"],
"Address": "192.168.1.37",
"Port": 9100,
"Meta": {
"app": "hadoop",
"team": "coffeemilk",
"project": "bigdataserver"
},
"EnableTagOverride": false,
"Check": {
"http": "http://192.168.1.37:9100/metrics",
"interval": "5s"
},
"Weights": {
"passing": 10,
"warning": 1
}
}
#1.1-更新已经注册的服务
curl --request PUT --data @test.json http://192.168.1.25:8500/v1/agent/service/register?replace-existing-checks=1
#2-新增一个test2.json文件,修改Tags属性的值为需要分类的名称(如:cadvisor-exporter)
vi test2.json
#【test2.json】的完整内容如下:
{
"ID": "cadvisor-exporter",
"Name": "cadvisor-exporter-192.168.1.25",
"Tags": ["cadvisor-exporter"],
"Address": "192.168.1.25",
"Port": 8090,
"Meta": {
"app": "docker",
"team": "ckcloud",
"project": "dockerserver"
},
"EnableTagOverride": false,
"Check": {
"http": "http://192.168.1.25:8090/metrics",
"interval": "5s"
},
"Weights": {
"passing": 10,
"warning": 1
}
}
#1.1-更新已经注册的服务
curl --request PUT --data @test2.json http://192.168.1.25:8500/v1/agent/service/register?replace-existing-checks=1








2.3.2、修改prometheus.yml的配置实现分类
bash
#修改prometheus.yml配置实现过滤
#1-进入prometheus路径编辑其配置文件【prometheus.yml】
cd /usr/local/prometheus-3.5.0/
vi prometheus.yml
#2-在【prometheus.yml】的最后【scrape_configs】下配置需要分为多个类型的job_name(如下分为两个)
- job_name: "consul-node-exporter"
consul_sd_configs:
- server: '192.168.1.25:8500'
services: []
relabel_configs:
- source_labels: [__meta_consul_tags]
regex: .*node-exporter.*
action: keep
- regex: __meta_consul_service_metadata_(.+)
action: labelmap
- job_name: "consul-docker-exporter"
consul_sd_configs:
- server: '192.168.1.25:8500'
services: []
relabel_configs:
- source_labels: [__meta_consul_tags]
regex: .*cadvisor-exporter.*
action: keep
- regex: __meta_consul_service_metadata_(.+)
action: labelmap
#3-验证修改后的prometheus.yml文件的语法是否正确(结果显示SUCCESS则表示正确)
./promtool check config prometheus.yml
#4-验证prometheus.yml文件中的语法正确后热重载让配置生效
curl -XPOST localhost:9090/-/reload
#5-打开浏览器进入Prometheus Server的Web界面【IP:9090】查看【Status-->Target health】即可看到添加的【consul-node-exporter】【consul-docker-exporter】两个节点下的对应地址及其状态【up】表示在线【down】表示离线。




三、编写shell脚本实现自动去consul注册或删除服务
目前虽然实现了在 prometheus 使用 consul 的服务发现做监控,不用对 prometheus 做修改了,但是,每次还要手动去注册服务,是比较麻烦的,因此这里编写了一个shell脚本,实现自动去consul注册服务,自动检测服务状态,还能删除 consul 里面的服务。
3.1、自动去consul注册或删除服务的shell脚本
bash
#自动去consul注册或删除服务的shell脚本
vi prometheus-consul.sh
#【prometheus-consul.sh】shell脚本的完整内容如下:
#!/bin/bash
#usage:
#param1:check_service or register_service or deregister_service
#param2: an exist file,and the file content format is as follows,pay attention to remove the first #
#group_name cluster/category_name service_ip service_port
#注册服务
function register_service()
{
cat $1 | while read line
do
group_name=$(echo $line | awk '{print $1}')
cluster_name=$(echo $line | awk '{print $2}')
service_ip=$(echo $line | awk '{print $3}')
service_port=$(echo $line | awk '{print $4}')
cat >service-$service_ip-$service_port.json<<EOF
{
"id":"service-${service_ip}-${service_port}",
"name":"service-${service_ip}-${service_port}",
"address":"${service_ip}",
"port":${service_port},
"tags":["$cluster_name"],
"meta":{"group":"$group_name","cluster":"$cluster_name","instance_name":"$service_ip:$service_port"},
"checks":[{
"http":"http://${service_ip}:$service_port/metrics",
"interval":"5s"
}],
"Weights": {
"Passing": 10,
"Warning": 1
},
"EnableTagOverride": false
}
EOF
curl --request PUT --data @service-$service_ip-$service_port.json \
http://${consul_host}:${consul_http_api_port}/v1/agent/service/register?replace-existing-checks=1
rm -rf service-$service_ip-$service_port.json
done
}
#注销服务
function deregister_service()
{
cat $1 | while read line
do
service_ip=$(echo $line | awk '{print $3}')
service_port=$(echo $line | awk '{print $4}')
#let service_port=redis_port+10000
consul_service_id="service-$service_ip-$service_port"
curl --request PUT http://${consul_host}:${consul_http_api_port}/v1/agent/service/deregister/${consul_service_id}
done
}
#检查服务
check_service()
{
cat $1 | while read line
do
service_ip=$(echo $line | awk '{print $3}')
service_port=$(echo $line | awk '{print $4}')
#let service_port=redis_port+10000
consul_service_id="service-$service_ip-$service_port"
ret1=$(curl -s http://${consul_host}:${consul_http_api_port}/v1/agent/service/$consul_service_id?pretty)
if [[ $ret1 =~ "unknown proxy service ID" ]];then
echo "不存在服务$consul_service_id"
else
ret2=$(curl -s http://${consul_host}:${consul_http_api_port}/v1/health/service/service-$service_ip-$service_port?pretty \
| grep "$service_ip:$service_port/metrics: 200 OK")
if [[ -z "$ret2" ]];then
echo -e "\033[5;34m服务$consul_service_id已注册,但服务状态异常 <---\033[0m"
else
echo "服务$consul_service_id已注册,且服务状态正常"
fi
fi
done
}
function main()
{
if [[ $# -ne 2 ]];then
echo -e "must two parameters:\nfirst exec_command(check_service or register_service or deregister_service)\nsecond filename"
exit
else
case $1 in
check_service)
shift 1
check_service $1
;;
register_service)
shift 1
register_service $1
;;
deregister_service)
shift 1
deregister_service $1
;;
*)
echo "无效的指令"
esac
fi
}
consul_host="192.168.1.25"
consul_http_api_port=8500
main $1 $2
3.2、自动去consule注册或删除服务shell脚本的使用
bash
#自动去consule注册或删除服务shell脚本的使用
#1-直接运行该shell脚本即可查看到提示信息(脚本后面需要两个参数)
#第一个参数可从【check_service】 【register_service】 【deregister_service】三选一(即:对应检测服务、注册服务、注销服务)。
#第二个参数对应一个文件,文件名随便,内容格式为【group_name cluster/category_name service_ip service_port】
bash prometheus-consul.sh
#2-使用示例
#2.1-编写需要注册的服务信息
vi consul-service.txt
#【consul-service.txt】的内容如下(每个内容使用空格分开):
coffeemilk node-exporter 192.168.1.39 9100
ckdba redis-exporter 192.168.1.37 9121
#2.2-使用脚本批量注册consul服务
bash prometheus-consul.sh register_service consul-service.txt
#2.2-使用脚本批量检查consul服务
bash prometheus-consul.sh check_service consul-service.txt
#2.3-修改prometheus.yml的新增配置分类
cd /usr/local/prometheus-3.5.0/
vi prometheus.yml
#2-在【prometheus.yml】的最后【scrape_configs】下配置需要分为多个类型的job_name(如下分为两个)
- job_name: "consul-node-exporter"
consul_sd_configs:
- server: '192.168.1.25:8500'
services: []
relabel_configs:
- source_labels: [__meta_consul_tags]
regex: .*node-exporter.*
action: keep
- regex: __meta_consul_service_metadata_(.+)
action: labelmap
- job_name: "consul-docker-exporter"
consul_sd_configs:
- server: '192.168.1.25:8500'
services: []
relabel_configs:
- source_labels: [__meta_consul_tags]
regex: .*cadvisor-exporter.*
action: keep
- regex: __meta_consul_service_metadata_(.+)
action: labelmap
- job_name: "consul-redis-exporter"
consul_sd_configs:
- server: '192.168.1.25:8500'
services: []
relabel_configs:
- source_labels: [__meta_consul_tags]
regex: .*redis-exporter.*
action: keep
- regex: __meta_consul_service_metadata_(.+)
action: labelmap
#3-验证修改后的prometheus.yml文件的语法是否正确(结果显示SUCCESS则表示正确)
./promtool check config prometheus.yml
#4-验证prometheus.yml文件中的语法正确后热重载让配置生效
curl -XPOST localhost:9090/-/reload
#5-打开浏览器进入Prometheus Server的Web界面【IP:9090】查看【Status-->Target health】即可看到添加的【consul-node-exporter】【consul-docker-exporter】【consul-redis-exporter】三节点下的对应地址及其状态【up】表示在线【down】表示离线。








