Prometheus 基于 Consul 的服务发现完全指南:从原理到实战

Prometheus 基于 Consul 的服务发现完全指南:从原理到实战 前言Prometheus 基于 Consul 的服务发现完全指南从原理到实战在云原生与微服务架构中服务的动态伸缩、弹性部署已成为常态。面对频繁变化的实例 IP 和端口无论是静态配置还是基于文件的服务发现都显得力不从心——前者需要频繁修改配置并重启后者仍需手动维护目标文件。Consul 服务发现正是为解决这一痛点而生。Consul 作为专业的服务注册中心让服务实例自动注册、自动下线Prometheus 通过 Consul API 实时感知服务变化实现监控目标的全自动动态管理。本文将从零开始系统讲解 Consul 服务发现的完整工作流程——安装部署、服务注册、Prometheus 配置、脚本自动化以及服务下线管理并明确标注每个操作涉及的文件及其作用。一、Consul 服务发现与其他方式的对比1.1 不同服务发现方式的差异在开始之前我们先来理解 Consul 服务发现与其他方式的核心区别特性静态配置文件服务发现Consul 服务发现工作方式手动编辑prometheus.yml手动维护 JSON/YAML 文件服务自动注册到 Consul无需手动改配置服务自动注册/下线❌ 不支持❌ 不支持✅ 支持是否需要重启 Prometheus✅ 需要❌ 不需要❌ 不需要实时性无变化依赖刷新间隔实时同步 Consul 健康状态使用场景小型固定环境小型测试环境生产环境、微服务、Docker、K8s、大规模监控平台1.2 适用场景Consul 服务发现特别适合以下场景微服务架构服务实例频繁扩缩容需要自动发现新实例并移除已下线的实例Docker/Kubernetes 环境容器动态启停IP 频繁变化多云/混合云环境跨云平台统一服务注册与发现大规模监控平台监控目标数量大、变化频繁手动维护不可行1.3 核心工作流程Consul 服务发现的整体工作流程如下text┌─────────────┐ ①注册服务 ┌──────────────────┐ ②查询服务列表 ┌─────────────┐ │ Exporter │ ───────────────▶ │ Consul │ ◀───────────────── │ Prometheus │ │ /业务服务 │ (HTTP API) │ (注册中心) │ (consul_sd) │ (9090) │ └─────────────┘ └──────────────────┘ └─────────────┘ │ │ │ │ │ │ └──────────────────────────────────┴────────────────────────────────────┘ ③ Prometheus 周期性拉取服务列表 自动生成监控目标并采集指标[reference:10]二、环境准备项目说明操作系统LinuxCentOS 7/8 或 Ubuntu 20.04Consul待安装默认端口 8500Prometheus已安装并正常运行参考本系列之前的文章Node Exporter已安装并运行用于演示服务注册三、Consul 安装3.1 方式一二进制安装推荐生产环境步骤一下载 Consul 二进制包bash# 下载 Consul以 v1.15.0 为例 wget https://releases.hashicorp.com/consul/1.15.0/consul_1.15.0_linux_amd64.zip # 解压 unzip consul_1.15.0_linux_amd64.zip # 移动到系统路径 sudo mv consul /usr/local/bin/该文件的作用/usr/local/bin/consul是 Consul 的可执行二进制文件用于启动 Consul 服务和管理 Consul 集群。步骤二验证安装bashconsul --version步骤三创建专用系统用户bashsudo useradd --no-create-home --shell /bin/false consul步骤四创建配置文件操作文件/etc/consul.d/consul.hclConsul 核心配置文件bashsudo mkdir -p /etc/consul.d sudo tee /etc/consul.d/consul.hcl EOF # 数据存储目录 data_dir /opt/consul # 绑定地址生产环境改为实际 IP bind_addr 0.0.0.0 # 客户端地址允许外部访问 UI 和 API client_addr 0.0.0.0 # 数据中心名称 datacenter dc1 # 启用 UI 界面 ui true # 服务注册配置文件目录 config_entries { config_dir /etc/consul.d/services } EOF该文件的作用定义 Consul 的核心运行参数包括数据存储路径、网络绑定地址、是否启用 UI 界面等。步骤五创建 Systemd 服务文件操作文件/etc/systemd/system/consul.servicebashsudo tee /etc/systemd/system/consul.service EOF [Unit] DescriptionConsul Service Discovery Afternetwork.target [Service] Userconsul Groupconsul Typesimple ExecStart/usr/local/bin/consul agent -config-dir/etc/consul.d ExecReload/bin/kill -HUP $MAINPID Restartalways [Install] WantedBymulti-user.target EOF该文件的作用将 Consul 注册为 Systemd 服务实现开机自启和进程守护。步骤六启动 Consulbash# 创建数据目录 sudo mkdir -p /opt/consul sudo chown consul:consul /opt/consul # 重新加载 systemd sudo systemctl daemon-reload # 启动 Consul sudo systemctl start consul # 设置开机自启 sudo systemctl enable consul # 查看状态 sudo systemctl status consul步骤七验证 Consulbash# 查看 Consul 集群成员 consul members # 通过浏览器访问 Consul UI # http://服务器IP:8500Consul 默认监听8500 端口提供服务注册、发现和 UI 访问。步骤八配置防火墙bash# CentOS 7 sudo firewall-cmd --permanent --add-port8500/tcp sudo firewall-cmd --reload # Ubuntu sudo ufw allow 8500/tcp3.2 方式二Docker 安装推荐快速体验操作文件docker-compose.ymlyamlversion: 3 services: consul: image: hashicorp/consul:latest container_name: consul restart: always ports: - 8500:8500 volumes: - ./consul/data:/consul/data - ./consul/config:/consul/config command: agent -server -bootstrap-expect1 -ui -client0.0.0.0启动bashdocker-compose up -d或直接使用 Docker 命令bashdocker run -d --name consul -p 8500:8500 hashicorp/consul agent -dev -client0.0.0.0注意-dev模式仅适用于开发测试环境生产环境请使用完整的集群配置。四、Consul HTTP API 访问方式Consul 提供了完善的 RESTful HTTP API用于服务注册、查询和管理。4.1 API 端点概览API 端点方法说明/v1/agent/service/registerPUT注册服务到本地 Agent/v1/agent/service/deregister/:service_idPUT从本地 Agent 注销服务/v1/catalog/servicesGET获取所有已注册的服务列表/v1/health/service/:service_nameGET获取指定服务的健康实例列表/v1/kv/:keyGET/PUT/DELETE键值存储操作4.2 基础 API 测试bash# 查看 Consul 集群状态 curl http://localhost:8500/v1/agent/self # 查看所有已注册的服务 curl http://localhost:8500/v1/catalog/services # 查看所有节点 curl http://localhost:8500/v1/catalog/nodes五、通过 API 注册服务到 Consul5.1 临时注册测试用通过 curl 直接向 Consul API 发送注册请求bashcurl -X PUT \ -H Content-Type: application/json \ -d { ID: node_exporter-1, Name: node_exporter, Tags: [prometheus, node], Address: 192.168.1.101, Port: 9100, Check: { HTTP: http://192.168.1.101:9100/metrics, Interval: 10s, Timeout: 3s } } \ http://localhost:8500/v1/agent/service/register该命令的作用将一个 Node Exporter 实例注册到 Consul并配置健康检查。Consul 会定期检查/metrics端点是否可达如果不可达则标记该服务为不健康。5.2 持久化注册推荐将服务定义写入 JSON 文件通过 Consul 的配置目录自动加载。操作文件/etc/consul.d/services/node_exporter.jsonjson{ service: { id: node_exporter-192.168.1.101, name: node_exporter, tags: [prometheus, node, production], address: 192.168.1.101, port: 9100, check: { http: http://192.168.1.101:9100/metrics, interval: 10s, timeout: 3s, deregister_critical_service_after: 30s } } }该文件的作用定义服务注册的完整信息包括服务 ID、名称、标签、地址、端口和健康检查配置。Consul 启动时会自动加载config_entries.config_dir目录下的所有服务定义文件。重新加载配置bash# 重载 Consul 配置不重启服务 consul reload # 或使用 systemctl sudo systemctl reload consul5.3 注册多个 Exporter操作文件/etc/consul.d/services/mysql_exporter.jsonjson{ service: { id: mysql_exporter-192.168.1.101, name: mysql_exporter, tags: [prometheus, mysql, production], address: 192.168.1.101, port: 9104, check: { http: http://192.168.1.101:9104/metrics, interval: 10s, timeout: 3s } } }操作文件/etc/consul.d/services/redis_exporter.jsonjson{ service: { id: redis_exporter-192.168.1.101, name: redis_exporter, tags: [prometheus, redis, production], address: 192.168.1.101, port: 9121, check: { http: http://192.168.1.101:9121/metrics, interval: 10s, timeout: 3s } } }六、配置 Prometheus 对接 Consul6.1 修改 Prometheus 配置文件操作文件/etc/prometheus/prometheus.yml在scrape_configs部分添加 Consul 服务发现配置yamlscrape_configs: # ... 其他 job 配置 ... # # 基于 Consul 的服务发现 # - job_name: consul_services consul_sd_configs: # Consul 服务器地址[reference:26] - server: localhost:8500 # 可选按标签过滤服务[reference:27] tags: - prometheus # 刷新间隔[reference:28] refresh_interval: 30s # 重标签配置将 Consul 元数据转换为 Prometheus 标签[reference:29] relabel_configs: # 使用 Consul 中的服务名作为 job 标签 - source_labels: [__meta_consul_service] target_label: job # 使用服务地址作为 instance 标签 - source_labels: [__meta_consul_service_address] target_label: instance # 保留 Consul 中的服务标签 - source_labels: [__meta_consul_tags] target_label: consul_tags # 仅抓取健康的服务实例 - source_labels: [__meta_consul_service_health] regex: passing action: keep配置项说明配置项说明serverConsul 服务器的地址和端口tags可选只发现带有指定标签的服务refresh_interval从 Consul 刷新目标列表的频率relabel_configs将 Consul 元数据标签转换为 Prometheus 标签该文件的作用定义 Prometheus 如何从 Consul 获取监控目标。consul_sd_configs告诉 Prometheus 去哪个 Consul 服务器查询服务列表relabel_configs负责将 Consul 返回的元数据转换为 Prometheus 可用的标签。6.2 更多配置示例按服务名过滤yamlconsul_sd_configs: - server: localhost:8500 services: [node_exporter, mysql_exporter] # 只发现指定服务使用 Consul 的元数据标签Consul 会为每个服务生成以下元数据标签元数据标签说明__meta_consul_service服务名称__meta_consul_service_address服务地址__meta_consul_service_port服务端口__meta_consul_tags服务标签列表__meta_consul_service_id服务 ID__meta_consul_service_health服务健康状态6.3 使配置生效bash# 检查配置语法 promtool check config /etc/prometheus/prometheus.yml # 热加载配置推荐不中断服务 sudo systemctl reload prometheus # 或使用 API 热加载需启用 --web.enable-lifecycle curl -X POST http://localhost:9090/-/reload[reference:37]6.4 验证服务发现访问http://Prometheus_IP:9090/targets查看consul_services作业下的目标访问http://Prometheus_IP:9090/service-discovery查看 Consul 发现的所有目标在 Consul UIhttp://Consul_IP:8500中查看已注册的服务七、创建自动注册脚本在生产环境中通常需要编写脚本实现服务的自动注册与注销。7.1 Shell 注册脚本操作文件/opt/scripts/register_to_consul.shbash#!/bin/bash # 功能将服务注册到 Consul # 用法./register_to_consul.sh service_name service_port service_ip SERVICE_NAME${1:-node_exporter} SERVICE_PORT${2:-9100} SERVICE_IP${3:-$(hostname -I | awk {print $1})} CONSUL_URLhttp://localhost:8500/v1/agent/service/register # 构建服务注册 JSON SERVICE_JSON$(cat EOF { ID: ${SERVICE_NAME}-${SERVICE_IP}, Name: ${SERVICE_NAME}, Tags: [prometheus, production], Address: ${SERVICE_IP}, Port: ${SERVICE_PORT}, Check: { HTTP: http://${SERVICE_IP}:${SERVICE_PORT}/metrics, Interval: 10s, Timeout: 3s, DeregisterCriticalServiceAfter: 30s } } EOF ) # 发送注册请求 curl -X PUT -H Content-Type: application/json -d ${SERVICE_JSON} ${CONSUL_URL} if [ $? -eq 0 ]; then echo Service ${SERVICE_NAME} registered successfully at ${SERVICE_IP}:${SERVICE_PORT} else echo Failed to register service ${SERVICE_NAME} exit 1 fi该文件的作用通过脚本自动将指定服务注册到 Consul支持传入服务名、端口和 IP 参数。使用示例bashchmod x /opt/scripts/register_to_consul.sh # 注册 Node Exporter ./register_to_consul.sh node_exporter 9100 192.168.1.101 # 注册 MySQL Exporter ./register_to_consul.sh mysql_exporter 9104 192.168.1.1017.2 Python 注册脚本操作文件/opt/scripts/register_to_consul.pypython#!/usr/bin/env python3 # -*- coding: utf-8 -*- # 功能通过 Python 将服务注册到 Consul import json import requests import socket import sys CONSUL_URL http://localhost:8500/v1/agent/service/register def register_service(service_name, service_port, service_ipNone): 注册服务到 Consul if service_ip is None: service_ip socket.gethostbyname(socket.gethostname()) service_id f{service_name}-{service_ip} payload { ID: service_id, Name: service_name, Tags: [prometheus, production], Address: service_ip, Port: service_port, Check: { HTTP: fhttp://{service_ip}:{service_port}/metrics, Interval: 10s, Timeout: 3s, DeregisterCriticalServiceAfter: 30s } } response requests.put( CONSUL_URL, datajson.dumps(payload), headers{Content-Type: application/json} ) if response.status_code 200: print(f✅ Service {service_name} registered at {service_ip}:{service_port}) else: print(f❌ Failed to register: {response.text}) sys.exit(1) if __name__ __main__: if len(sys.argv) 3: print(Usage: python3 register_to_consul.py service_name port [ip]) sys.exit(1) service_name sys.argv[1] service_port int(sys.argv[2]) service_ip sys.argv[3] if len(sys.argv) 3 else None register_service(service_name, service_port, service_ip)该文件的作用Python 版本的服务注册脚本功能与 Shell 版本相同适合集成到 Python 应用或运维平台中。使用示例bashpython3 /opt/scripts/register_to_consul.py node_exporter 9100 192.168.1.1017.3 服务发现脚本查询已注册服务操作文件/opt/scripts/discover_services.shbash#!/bin/bash # 功能查询 Consul 中已注册的服务列表curl -s http://localhost:8500/v1/catalog/services | jq .该文件的作用快速查询 Consul 中所有已注册的服务用于验证注册是否成功。八、Consul 删除/注销服务8.1 通过 API 删除服务bash# 删除指定服务通过服务 ID curl -X PUT http://localhost:8500/v1/agent/service/deregister/service_id # 示例删除 node_exporter curl -X PUT http://localhost:8500/v1/agent/service/deregister/node_exporter-192.168.1.1018.2 通过 Consul 命令删除bash# 使用 consul 命令注销服务[reference:38] consul services deregister /etc/consul.d/services/node_exporter.json8.3 删除脚本操作文件/opt/scripts/deregister_from_consul.shbash#!/bin/bash # 功能从 Consul 注销服务 # 用法./deregister_from_consul.sh service_id SERVICE_ID${1} CONSUL_URLhttp://localhost:8500/v1/agent/service/deregister/${SERVICE_ID} if [ -z ${SERVICE_ID} ]; then echo Usage: $0 service_id echo Example: $0 node_exporter-192.168.1.101 exit 1 fi curl -X PUT ${CONSUL_URL} if [ $? -eq 0 ]; then echo Service ${SERVICE_ID} deregistered successfully else echo Failed to deregister service ${SERVICE_ID} exit 1 fi该文件的作用通过脚本快速注销 Consul 中的服务适用于服务下线或维护场景。使用示例bashchmod x /opt/scripts/deregister_from_consul.sh ./deregister_from_consul.sh node_exporter-192.168.1.1018.4 服务退出时自动注销在生产环境中服务进程退出时应自动从 Consul 注销避免产生“僵尸服务”。在服务的停止脚本中添加bash# 在服务停止时执行 curl -X PUT http://localhost:8500/v1/agent/service/deregister/node_exporter-192.168.1.101九、ConsulManager 简介在生产环境中手动编写 JSON 文件或 curl 命令来管理服务注册既繁琐又容易出错。ConsulManager正是为解决这一问题而生的 Web 管理工具。9.1 什么是 ConsulManagerConsulManager 是一个使用Flask Vue开发的 Consul Web 管理工具比官方自带的 Web UI 实现了更多的功能。它弥补了 Consul 官方 UI 对 Services 管理的不足。主要功能Consul Web Manager支持 Services 的增删改查、批量删除直观查看服务实例信息和健康状态便捷配置 Tags、Meta 和健康检查ECS Manager支持同步阿里云、腾讯云、华为云、AWS 的 ECS 主机信息到 Consul实现 Prometheus 监控目标的自动发现Blackbox Manager基于 Blackbox Exporter 实现站点与接口监控通过 Web 界面即可对监控目标增删改查支持批量删除和分类管理9.2 部署方式使用 Docker Compose 一键部署bash# 一键安装脚本 curl -s https://starsl.cn/static/img/all_install.sh | sudo bash安装路径为/opt/tensuns。安装完成后通过浏览器访问http://服务器IP:1026即可登录 ConsulManager 管理界面。使用 ConsulManager 的优势不用写 JSON、不用重启 Consul批量增删、改标签、改健康检查等等一切都可以在 Web 界面上完成。十、操作文件速查表文件路径作用/usr/local/bin/consulConsul 可执行二进制文件/etc/consul.d/consul.hclConsul 核心配置文件/etc/consul.d/services/*.json服务注册定义文件目录/etc/systemd/system/consul.serviceConsul Systemd 服务文件/opt/consul/Consul 数据存储目录/etc/prometheus/prometheus.ymlPrometheus 主配置文件添加consul_sd_configs/opt/scripts/register_to_consul.shShell 服务注册脚本/opt/scripts/register_to_consul.pyPython 服务注册脚本/opt/scripts/deregister_from_consul.shShell 服务注销脚本/opt/scripts/discover_services.sh服务查询脚本十一、总结本文系统介绍了 Prometheus 基于 Consul 的服务发现的完整知识体系与其他方式的区别Consul 服务发现实现了服务自动注册与下线无需手动维护配置文件是生产环境和大规模监控的首选方案适用场景微服务架构、容器环境、多云环境、大规模监控平台安装部署支持二进制安装生产推荐和 Docker 安装快速体验Consul HTTP API提供了完整的 RESTful API支持服务注册、查询、注销等操作服务注册支持通过 API 临时注册和 JSON 文件持久化注册两种方式Prometheus 配置通过consul_sd_configs对接 Consul实现监控目标的自动发现脚本自动化提供了 Shell 和 Python 两种注册/注销脚本便于集成到自动化运维体系ConsulManagerWeb 管理工具无需写 JSON 和重启 Consul即可在界面上完成服务的增删改查一句话总结Consul 服务发现让 Prometheus 的监控目标管理从“手动维护”进化到“全自动感知”——服务注册到 Consul 即被 Prometheus 自动发现并开始监控服务下线即自动停止抓取全程无需人工干预。