基于 Kubernetes 的 Prometheus Service Discovery:自动监控 Pod 指标
基于 Kubernetes 的 Prometheus Service Discovery:自动监控 Pod 指标
在云原生时代,动态性是 Kubernetes 集群的重要特征。Pod 的创建、销毁和更新频繁发生,手动维护 Prometheus 的抓取目标配置既繁琐又容易出错。Prometheus 的 Service Discovery(SD)机制,尤其是基于 Kubernetes 的 SD,为我们提供了一种自动化、动态化的解决方案,能够自动发现并监控 Kubernetes 集群内部 Pod 暴露的自定义应用指标。
1. Prometheus Service Discovery 简介
Prometheus 的 Service Discovery 允许 Prometheus 自动发现需要监控的目标。它支持多种 SD 机制,包括:
- 静态配置: 手动维护 targets 列表,适用于少量、静态的目标。
- 基于文件的 SD: 从文件中读取 targets 配置,适用于需要脚本生成 targets 的场景。
- 基于云平台的 SD: 自动发现云平台上的服务实例,例如 AWS EC2、Google Compute Engine 等。
- 基于 Kubernetes 的 SD: 自动发现 Kubernetes 集群中的 Pod、Service、Endpoints 等。
在 Kubernetes 环境下,基于 Kubernetes 的 SD 是最常用的方式,它可以根据 Kubernetes 的 API 对象自动发现需要监控的目标,并根据标签、注解等信息进行过滤和配置。
2. Kubernetes SD 的类型
Prometheus 提供了多种 Kubernetes SD 的类型,以适应不同的监控需求:
- pod: 发现 Kubernetes 集群中的所有 Pod。
- service: 发现 Kubernetes 集群中的所有 Service。
- endpoints: 发现 Kubernetes 集群中的所有 Endpoints。
- ingress: 发现 Kubernetes 集群中的所有 Ingress。
每种 SD 类型都提供不同的元数据和过滤选项,可以根据实际需求选择合适的类型。
3. 配置 Prometheus Kubernetes SD
以下是一个使用 pod SD 类型,监控 Kubernetes 集群中所有 Pod 的 Prometheus 配置示例:
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: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
action: replace
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
target_label: __address__
- action: labelmap
regex: __meta_kubernetes_pod_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: namespace
- source_labels: [__meta_kubernetes_pod_name]
action: replace
target_label: pod_name
配置项说明:
job_name: Prometheus 任务的名称,可以自定义。kubernetes_sd_configs: Kubernetes SD 配置。role: SD 类型,这里使用pod。
relabel_configs: 重标签配置,用于过滤和修改 targets 的标签。- 第一个
relabel_config用于过滤掉prometheus.io/scrape注解不为true的 Pod。 - 第二个
relabel_config用于从prometheus.io/path注解中获取 metrics 路径,并设置到__metrics_path__标签。 - 第三个
relabel_config用于从prometheus.io/port注解中获取端口号,并设置到__address__标签。 - 第四个
relabel_config用于将 Pod 的所有标签添加到 target 的标签中。 - 第五个
relabel_config和第六个relabel_config用于将 Pod 的 namespace 和 name 添加到 target 的标签中。
- 第一个
Pod 注解:
为了让 Prometheus 能够发现并抓取 Pod 的 metrics,需要在 Pod 的 metadata 中添加以下注解:
apiVersion: v1
kind: Pod
metadata:
name: my-app
labels:
app: my-app
annotations:
prometheus.io/scrape: 'true'
prometheus.io/path: '/metrics'
prometheus.io/port: '8080'
spec:
containers:
- name: my-app
image: my-app:latest
ports:
- containerPort: 8080
prometheus.io/scrape: 设置为true表示允许 Prometheus 抓取该 Pod 的 metrics。prometheus.io/path: 指定 metrics 的路径,默认为/metrics。prometheus.io/port: 指定 metrics 的端口号,默认为80。
4. 使用 Service 发现 Pod
除了直接发现 Pod,还可以通过 Service 来发现 Pod。这种方式的优点是,即使 Pod 的 IP 地址发生变化,Service 的 IP 地址通常不会变化,从而保证了监控的稳定性。
以下是一个使用 service SD 类型,监控 Kubernetes 集群中所有 Service 的 Prometheus 配置示例:
scrape_configs:
- job_name: 'kubernetes-service-endpoints'
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_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__
- action: labelmap
regex: __meta_kubernetes_service_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: namespace
- source_labels: [__meta_kubernetes_service_name]
action: replace
target_label: service_name
配置项说明:
与 pod SD 类型类似,只是 role 设置为 endpoints,并且 relabel 配置中的标签也对应 Service 的注解和标签。
Service 注解:
为了让 Prometheus 能够发现并抓取 Service 对应的 Pod 的 metrics,需要在 Service 的 metadata 中添加以下注解:
apiVersion: v1
kind: Service
metadata:
name: my-app-service
labels:
app: my-app
annotations:
prometheus.io/scrape: 'true'
prometheus.io/path: '/metrics'
prometheus.io/port: '8080'
spec:
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
prometheus.io/scrape: 设置为true表示允许 Prometheus 抓取该 Service 对应的 Pod 的 metrics。prometheus.io/path: 指定 metrics 的路径,默认为/metrics。prometheus.io/port: 指定 metrics 的端口号,默认为8080,这里需要与 Pod 的containerPort保持一致。
5. 使用 Relabeling 进行高级配置
Relabeling 是 Prometheus SD 中非常强大的功能,它允许我们根据各种条件过滤、修改和添加 targets 的标签。通过 Relabeling,我们可以实现更精细的监控配置。
示例:根据 Pod 标签过滤 targets
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_environment]
action: keep
regex: 'production'
该配置只会抓取 environment 标签值为 production 的 Pod 的 metrics。
示例:根据 Namespace 过滤 targets
relabel_configs:
- source_labels: [__meta_kubernetes_namespace]
action: drop
regex: 'kube-system|kube-public'
该配置会忽略 kube-system 和 kube-public 命名空间下的 Pod 的 metrics。
示例:添加自定义标签
relabel_configs:
- action: replace
target_label: job
replacement: 'my-app'
该配置会为所有 targets 添加一个 job 标签,值为 my-app。
6. 最佳实践
- 使用 Service 发现 Pod: 尽量使用 Service 来发现 Pod,以保证监控的稳定性。
- 使用 Relabeling 进行精细配置: 使用 Relabeling 过滤、修改和添加 targets 的标签,以实现更精细的监控配置。
- 合理设置注解: 在 Pod 或 Service 中添加合适的注解,以便 Prometheus 能够正确发现和抓取 metrics。
- 定期检查配置: 定期检查 Prometheus 的配置,确保其能够正确发现和监控 Kubernetes 集群中的应用。
- 使用 Prometheus Operator: 考虑使用 Prometheus Operator 来简化 Prometheus 的部署和管理,Prometheus Operator 可以自动管理 Prometheus 的配置和升级。
7. 总结
Prometheus 的 Service Discovery 机制,尤其是基于 Kubernetes 的 SD,为我们提供了一种自动化、动态化的解决方案,能够自动发现并监控 Kubernetes 集群内部 Pod 暴露的自定义应用指标,极大地简化了监控配置和维护工作。通过合理配置 Kubernetes SD 和 Relabeling,我们可以实现更精细、更灵活的监控方案,从而更好地保障 Kubernetes 集群的稳定运行。
掌握 Prometheus Service Discovery,你就能轻松应对 Kubernetes 集群的动态性,实现自动化监控,提升运维效率。希望本文能帮助你更好地理解和应用 Prometheus Kubernetes SD,为你的云原生之旅保驾护航!