5月27日 17:41

Prometheus 支持哪些服务发现机制?如何配置?

Prometheus 支持多种服务发现机制,用于在动态环境中自动发现监控目标,无需手动维护目标列表。下面逐一说明各机制的原理、配置方式与适用场景。

静态配置

静态配置是最简单的方式,直接在 prometheus.yml 中写死目标地址,适合小规模或目标固定的场景:

yaml
scrape_configs: - job_name: 'node' static_configs: - targets: ['192.168.1.10:9100', '192.168.1.11:9100'] labels: datacenter: 'dc1'

目标变动时需要重启或 reload Prometheus,不适合频繁变化的动态环境。

基于文件的服务发现

file_sd_configs 通过读取外部 JSON 或 YAML 文件获取目标列表,Prometheus 会监听文件变化并自动更新:

yaml
scrape_configs: - job_name: 'file' file_sd_configs: - files: - '/etc/prometheus/targets/*.json' refresh_interval: 5m

JSON 文件格式示例:

json
[ { "targets": ["10.0.0.1:9100", "10.0.0.2:9100"], "labels": {"env": "prod"} } ]

这种方式适合由外部脚本或 CMDB 系统定期生成目标列表的场景,Prometheus 不需要重启。

Kubernetes 服务发现

Kubernetes 是 Prometheus 最常用的部署环境,通过 kubernetes_sd_configs 直接调用 Kubernetes API 发现集群资源:

yaml
scrape_configs: - job_name: 'kubernetes-pods' kubernetes_sd_configs: - role: pod relabel_configs: - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] action: keep regex: true - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path] action: replace target_label: __metrics_path__ regex: (.+) - source_labels: [__meta_kubernetes_pod_ip] action: replace target_label: __address__ replacement: $1:9104

Kubernetes 角色类型

角色发现资源典型场景
pod所有 Pod直接采集 Pod 指标
service所有 Service采集 Service 背后端点
endpointsService 的 Endpoints最常用,配合注解使用
endpointslicesEndpointSlicesK8s 1.21+ 替代 Endpoints
node所有 Node采集节点级指标
ingress所有 Ingress监控 Ingress 延迟

通过注解控制采集

在 Pod 模板中添加注解即可被 Prometheus 自动发现:

yaml
metadata: annotations: prometheus.io/scrape: "true" prometheus.io/port: "8080" prometheus.io/path: "/metrics"

RBAC 权限

Prometheus 需要 ClusterRole 权限才能访问 K8s API:

yaml
rules: - apiGroups: [""] resources: - nodes - services - endpoints - pods verbs: ["get", "list", "watch"]

命名空间过滤

限制发现范围,只采集特定命名空间的目标:

yaml
kubernetes_sd_configs: - role: pod namespaces: names: - production - staging

Prometheus Operator 的 CRD 方式

在 Kubernetes 环境中,Prometheus Operator 提供了更声明式的方式,通过 ServiceMonitor、PodMonitor 和 Probe 三种 CRD 定义采集目标,无需直接编写 relabel 配置:

yaml
apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: my-app spec: selector: matchLabels: app: my-app endpoints: - port: metrics path: /metrics interval: 30s

Operator 自动将这些 CRD 转换为 Prometheus 的 scrape_configs,是 Kubernetes 环境下的推荐方式。

Consul 服务发现

Consul 是常用的服务注册中心,Prometheus 通过 consul_sd_configs 查询 Consul Catalog 获取服务实例:

yaml
scrape_configs: - job_name: 'consul' consul_sd_configs: - server: 'consul.example.com:8500' services: ['web', 'api'] tag_separator: ',' scheme: http token: 'your-acl-token'

Consul 服务实例的元数据通过 __meta_consul_service_metadata_* 标签暴露,可以在 relabel 阶段提取为 Prometheus 标签。适合已有 Consul 基础设施的微服务架构。

DNS SRV 服务发现

通过 DNS SRV 记录发现目标,无需额外依赖,适合支持 SRV 记录的内网环境:

yaml
scrape_configs: - job_name: 'dns' dns_sd_configs: - names: ['_prometheus._tcp.example.com'] type: SRV port: 9100

也支持 A/AAAA 记录查询,将域名解析为 IP 列表。配置简单但不适用于频繁变化的场景。

HTTP 服务发现

Prometheus 2.28+ 引入的 http_sd_configs,通过 HTTP 端点获取目标列表,返回格式与 file_sd 相同的 JSON:

yaml
scrape_configs: - job_name: 'http' http_sd_configs: - url: 'http://config-server/targets' refresh_interval: 1m

这是对文件服务发现的动态替代,适合通过自建配置中心或 CMDB API 提供目标的场景。

云平台服务发现

AWS EC2

yaml
scrape_configs: - job_name: 'ec2' ec2_sd_configs: - region: us-east-1 access_key: AKIA... secret_key: xxx... filters: - name: tag:Environment values: [production]

可以通过 filters 按 EC2 标签过滤实例,元标签 __meta_ec2_tag_* 提供 EC2 标签信息。

Azure VM

yaml
scrape_configs: - job_name: 'azure' azure_sd_configs: - subscription_id: 'your-subscription-id' tenant_id: 'your-tenant-id' client_id: 'your-client-id' client_secret: 'your-client-secret'

GCE

yaml
scrape_configs: - job_name: 'gce' gce_sd_configs: - project: 'my-gcp-project' - zone: 'us-central1-a'

Relabel 配置详解

Relabel 是服务发现的核心能力,在目标进入采集队列前对标签进行加工和过滤:

动作作用常用场景
keep保留匹配的目标只采集带特定注解的 Pod
drop丢弃匹配的目标排除 kube-system 命名空间
replace替换标签值修改 address 加端口
labelmap批量映射标签将元标签映射为业务标签
hashmod哈希取模分片采集,多实例分担负载
labeldrop删除标签清理不需要的 __ 前缀标签
labelkeep保留匹配的标签只保留特定模式的标签

常用元标签

Kubernetes 环境中最常用的元标签:

  • __meta_kubernetes_pod_name — Pod 名称
  • __meta_kubernetes_namespace — 命名空间
  • __meta_kubernetes_pod_annotation_prometheus_io_scrape — 采集注解
  • __meta_kubernetes_pod_annotation_prometheus_io_path — 指标路径注解
  • __meta_kubernetes_pod_annotation_prometheus_io_port — 端口注解
  • __meta_kubernetes_service_name — Service 名称

Consul 环境中的元标签:

  • __meta_consul_service_metadata_* — 服务元数据
  • __meta_consul_tags — 服务标签
  • __meta_consul_dc — 数据中心

调试服务发现

当目标未按预期出现时,可以通过以下方式排查:

在 Prometheus UI 的 Status → Targets 页面查看已发现的目标和标签。

通过 API 查询当前服务发现结果:

bash
curl -s http://prometheus:9090/api/v1/targets | jq '.data.activeTargets[] | {job: .labels.job, discoveredLabels: .discoveredLabels}'

查看服务发现过程中丢弃的目标(DISCOVERED 状态):

bash
curl -s http://prometheus:9090/api/v1/targets | jq '.data.droppedTargets | length'

如何选择服务发现方式

选择依据主要看部署环境:

  • Kubernetes 集群内:优先用 kubernetes_sd_configs 或 Prometheus Operator CRD
  • 有 Consul 注册中心:用 consul_sd_configs
  • 云平台原生:用对应的云 SD(ec2/azure/gce)
  • 有 CMDB 或配置中心:用 http_sd_configs 或 file_sd_configs
  • 小规模静态环境:直接用 static_configs
  • 支持 SRV 的内网:可用 dns_sd_configs

实际生产中,Kubernetes 环境占绝大多数,Kubernetes SD + Relabel 是最核心的组合。

标签:Prometheus