Prometheus 支持哪些服务发现机制?如何配置?
Prometheus 支持多种服务发现机制,用于在动态环境中自动发现监控目标,无需手动维护目标列表。下面逐一说明各机制的原理、配置方式与适用场景。
静态配置
静态配置是最简单的方式,直接在 prometheus.yml 中写死目标地址,适合小规模或目标固定的场景:
yamlscrape_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 会监听文件变化并自动更新:
yamlscrape_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 发现集群资源:
yamlscrape_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 背后端点 |
| endpoints | Service 的 Endpoints | 最常用,配合注解使用 |
| endpointslices | EndpointSlices | K8s 1.21+ 替代 Endpoints |
| node | 所有 Node | 采集节点级指标 |
| ingress | 所有 Ingress | 监控 Ingress 延迟 |
通过注解控制采集
在 Pod 模板中添加注解即可被 Prometheus 自动发现:
yamlmetadata: annotations: prometheus.io/scrape: "true" prometheus.io/port: "8080" prometheus.io/path: "/metrics"
RBAC 权限
Prometheus 需要 ClusterRole 权限才能访问 K8s API:
yamlrules: - apiGroups: [""] resources: - nodes - services - endpoints - pods verbs: ["get", "list", "watch"]
命名空间过滤
限制发现范围,只采集特定命名空间的目标:
yamlkubernetes_sd_configs: - role: pod namespaces: names: - production - staging
Prometheus Operator 的 CRD 方式
在 Kubernetes 环境中,Prometheus Operator 提供了更声明式的方式,通过 ServiceMonitor、PodMonitor 和 Probe 三种 CRD 定义采集目标,无需直接编写 relabel 配置:
yamlapiVersion: 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 获取服务实例:
yamlscrape_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 记录的内网环境:
yamlscrape_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:
yamlscrape_configs: - job_name: 'http' http_sd_configs: - url: 'http://config-server/targets' refresh_interval: 1m
这是对文件服务发现的动态替代,适合通过自建配置中心或 CMDB API 提供目标的场景。
云平台服务发现
AWS EC2
yamlscrape_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
yamlscrape_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
yamlscrape_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 查询当前服务发现结果:
bashcurl -s http://prometheus:9090/api/v1/targets | jq '.data.activeTargets[] | {job: .labels.job, discoveredLabels: .discoveredLabels}'
查看服务发现过程中丢弃的目标(DISCOVERED 状态):
bashcurl -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 是最核心的组合。