服务发现与 Relabeling
服务发现解决“采谁”,Relabeling 决定“保留谁、用什么地址抓取、样本带哪些标签”。它是 Prometheus 在云原生环境中自动化采集的核心能力,也是最容易因规则顺序或正则写错导致 Target 消失的部分。
1. 服务发现生命周期

- 服务发现产生内部标签,例如 Kubernetes 的
__meta_kubernetes_*。 relabel_configs在抓取前执行,可以筛选 Target、改写__address__、添加业务标签。metric_relabel_configs在抓取后执行,可以丢弃已采到的指标;它不能降低网络和解析成本。
在 Prometheus Targets 页面展开目标,可同时查看 discovered labels 与最终 labels,这是调试 Relabeling 的首选方法。
2. Static 与 File Discovery
Static 适合固定少量目标:
scrape_configs:
- job_name: node-exporter
static_configs:
# 每项是 Prometheus 实际连接的 host:port
- targets: ["node-01.internal.example:9100", "node-02.internal.example:9100"]
labels:
# 统一附加稳定业务维度,避免由 Dashboard 手工猜测环境
environment: production
team: platform
File Discovery 适合由 CMDB、Terraform 或自动化生成清单:
scrape_configs:
- job_name: node-exporter
file_sd_configs:
# Prometheus 自动监视目录内 JSON/YAML 文件变化
- files: ["/etc/prometheus/targets/*.json"]
[
{
"targets": ["node-01.internal.example:9100"],
"labels": {"environment": "production", "team": "platform"}
}
]
生成程序应先写入临时文件再原子替换,避免 Prometheus 读取到半写入 JSON;同时为生成任务本身建立失败告警。
3. DNS Discovery
DNS 适合目标由稳定 DNS 记录管理的场景:
scrape_configs:
- job_name: api
dns_sd_configs:
# 解析 A/AAAA 记录;端口需与服务实际 metrics 端口一致
- names: ["api-metrics.internal.example"]
type: A
port: 8080
DNS TTL、解析结果与 Prometheus 刷新间隔共同影响目标更新速度。解析失败时检查 Prometheus 所在网络的 resolver,而不是只在个人电脑执行 dig。
4. Kubernetes Discovery
原生发现从 Kubernetes API 获取元数据,生产中必须同时配置 RBAC。下面示例只抓取带注解的 Service Endpoint:
scrape_configs:
- job_name: kubernetes-service-endpoints
kubernetes_sd_configs:
# endpoints 角色发现每个 Service 后端端点
- role: endpoints
relabel_configs:
# 仅保留显式声明需要采集的 Service
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
action: keep
regex: "true"
# 将 Namespace 写入最终标签,方便权限、Dashboard 和告警按域聚合
- source_labels: [__meta_kubernetes_namespace]
target_label: namespace
# 将 Service 名称写入最终标签,保留业务可读的目标身份
- source_labels: [__meta_kubernetes_service_name]
target_label: service
使用 Prometheus Operator 时,优先选择 ServiceMonitor/PodMonitor;它们将常用发现与选择关系声明为 CRD。详见 Prometheus Kubernetes 监控。
5. Relabeling 常用 Action
| Action | 用途 | 常见场景 |
|---|---|---|
replace | 写入或改写目标标签 | 从元数据生成 namespace、service |
keep | 仅保留匹配 Target | 只抓取有特定注解的 Pod/Service |
drop | 丢弃匹配 Target | 排除测试 Namespace 或无效端口 |
labelmap | 批量映射标签名 | 转换有限的 Kubernetes Label |
labeldrop | 删除匹配的标签名 | 移除内部或高风险标签 |
hashmod | 按哈希分片 | 大规模环境中将目标分配给多个 Prometheus |
改写抓取地址
当指标端口来自注解时,可把发现地址替换为指定端口:
relabel_configs:
# 输入为默认地址和注解端口,例如 10.0.0.5:80;8080
- source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
action: replace
target_label: __address__
regex: "([^:]+)(?::\\d+)?;(\\d+)"
# $1 为主机,$2 为注解端口,结果为 10.0.0.5:8080
replacement: "$1:$2"
选择性映射 Kubernetes 标签
不要无差别 labelmap 所有 Pod Label,容易引入高基数。只映射明确需要的稳定标签:
relabel_configs:
# 将 app.kubernetes.io/name 映射为业务标签 app
- source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_name]
target_label: app
# 丢弃内部临时标签,避免它们进入最终时间序列标签集
- action: labeldrop
regex: "__meta_.*"
6. Metric Relabeling 与调试
metric_relabel_configs:
# 丢弃确认无用的 Go 运行时细粒度指标;先在预发评估影响
- source_labels: [__name__]
action: drop
regex: "go_memstats_.*"
调试顺序:检查配置语法,检查 Service Discovery 页面 discovered labels,检查 Targets 最终 labels,最后检查 up 和 scrape_samples_scraped。修改 relabel 后先在预发验证,错误的 keep/drop 可一次性移除整类生产 Target。