Prometheus 与 Kubernetes 服务发现及标签重写机制详解
一、Prometheus 数据采集模式与服务发现
Prometheus 默认采用主动拉取(pull)方式获取监控指标。每个被监控目标需暴露一个 HTTP 接口(如 /metrics),Prometheus 定时访问该接口抓取数据。传统静态配置通过 scrape_configs 中的 job 显式列出目标地址,但无法应对动态变化的环境。
为适应容器化场景中频繁变更的服务实例,Prometheus 引入了多种服务发现机制,实现自动感知新目标:
- kubernetes_sd_configs:对接 Kubernetes API,动态发现集群内节点、Pod、服务等资源。
- static_configs:手动指定目标列表,适用于固定不变的主机。
- dns_sd_configs:基于 DNS 记录动态解析目标 IP 地址。
- consul_sd_configs:集成 Consul 注册中心进行服务发现。
- file_sd_configs:从外部文件读取目标信息,支持热更新而无需重启 Prometheus。
这些机制让 Prometheus 能实时同步基础设施状态,避免频繁修改配置和重启服务。
二、标签重写机制(Relabeling)
在服务发现过程中,Prometheus 会为每个目标生成一组元数据标签(metadata labels)。这些标签可用于后续的数据过滤、分类或展示。通过 relabel_configs 和 metric_relabel_configs,可在不同阶段对标签进行操作。
1. 两个重写阶段
- relabel_configs:在采集前处理目标实例的元信息,决定是否保留该目标以及如何修改其连接参数(如地址、路径)。
- metric_relabel_configs:在采集后处理实际抓取到的指标数据,可删除或重命名某些时间序列,减少存储开销。
2. 核心字段说明
| 字段名 | 作用 |
| source_labels | 指定要操作的一组源标签 |
| target_label | 目标标签名称,用于替换或新建标签 |
| regex | 正则表达式,匹配源标签值 |
| replacement | 替换模板,支持分组引用(如 $1, $2) |
| action | 执行动作类型 |
3. 常见 action 类型
- replace:根据正则匹配结果,将
source_labels的值替换为replacement并赋给target_label。 - keep:仅保留满足
regex条件的目标,其余丢弃。 - drop:丢弃满足
regex的目标,保留其他。 - hashmod:对标签值哈希后取模,常用于分片采集。
- labelmap:将匹配
regex的标签复制为新的标签,常用于提取 Kubernetes 标签。 - labelkeep / labeldrop:保留或删除符合正则的标签键名。
示例:端口重定向
relabel_configs:
- source_labels: [__address__]
regex: (.+):10250
replacement: $1:9100
target_label: __address__
action: replace
此规则将原本指向 :10250(kubelet 端口)的目标地址改为 :9100(node-exporter 监听端口),从而正确抓取节点指标。
三、Kubernetes 服务发现详解
Prometheus 可直接调用 Kubernetes API 获取集群中各类资源的状态,并将其转化为监控目标。这一过程由 kubernetes_sd_configs 配置驱动。
1. 支持的角色类型(role)
node:集群节点service:Service 对象pod:Pod 实例endpoints:Endpoint 列表endpointslice:Endpoint 分片(提升大规模场景性能)ingress:Ingress 规则
2. 示例:监控 kube-apiserver
kube-apiserver 通常以默认命名空间下的 Service 形式存在,可通过以下配置自动发现:
- job_name: 'k8s-apiserver'
kubernetes_sd_configs:
- role: endpoints
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
regex: default;kubernetes;https
action: keep
上述配置表示:仅当命名空间为 default、服务名为 kubernetes 且端口名为 https 时才保留该目标。
3. 使用注解控制采集行为
Kubernetes 中可通过 Service 或 Pod 的注解来声明是否应被 Prometheus 抓取:
prometheus.io/scrape: "true":启用采集prometheus.io/port:指定采集端口prometheus.io/path:自定义指标路径(默认为/metrics)prometheus.io/scheme:使用 http 或 https 协议
结合 relabeling,可以灵活构建通用采集规则:
- job_name: 'k8s-services'
kubernetes_sd_configs:
- role: endpoints
relabel_configs:
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
action: replace
target_label: __scheme__
regex: (https?)
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
action: replace
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
target_label: __address__
此配置实现了基于注解的全自动服务识别与采集。
4. Node 指标采集
通过 role: node 发现所有节点,并结合 node-exporter 抓取系统指标:
- job_name: 'k8s-nodes'
kubernetes_sd_configs:
- role: node
relabel_configs:
- source_labels: [__address__]
regex: (.+):10250
replacement: $1:9100
target_label: __address__
action: replace
- action: labelmap
regex: __meta_kubernetes_node_label_(.+)
常见输出指标包括:
node_cpu_seconds_total:CPU 使用统计node_memory_MemAvailable_bytes:可用内存node_disk_io_time_seconds_total:磁盘 I/O 时间node_network_receive_bytes_total:网络接收字节数node_load1:1 分钟平均负载
5. Pod 指标采集
使用 role: pod 可发现所有 Pod,常用于监控应用自身暴露的指标或 cAdvisor 提供的容器运行时数据:
- job_name: 'k8s-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- action: labelmap
regex: __meta_kubernetes_pod_label_(.+)
- 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, __meta_kubernetes_pod_annotation_prometheus_io_port]
action: replace
regex: (.+);(\d+)
replacement: $1:$2
target_label: __address__
6. 控制平面组件监控
对于调度器(kube-scheduler)和控制器管理器(kube-controller-manager),通常运行于主节点并通过 HTTPS 暴露指标。
kube-scheduler 示例:
- job_name: 'k8s-scheduler'
kubernetes_sd_configs:
- role: node
scheme: https
tls_config:
insecure_skip_verify: true
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_node_role]
regex: .*(master|control-plane).*
action: keep
- source_labels: [__meta_kubernetes_node_address_InternalIP]
regex: (.+)
replacement: $1:10259
target_label: __address__
类似地,kube-proxy 若开启了 metricsBindAddress: 0.0.0.0,也可通过 :10249 端口进行采集。
