如何用Prometheus采集K8s Pod中HTTP/HTTPS双容器的指标?
这个坑我之前踩过!同一Pod里多个容器用不同协议暴露指标的时候,默认的Pod注解确实搞不定——因为prometheus.io/scheme和prometheus.io/port都是全局针对整个Pod的,没法给每个容器单独配置,所以才会出现要么只能采HTTPS容器、要么只能采HTTP容器,另一个返回400的情况。给你几个靠谱的解决办法:
1. 为每个容器创建独立的PodMonitor(最推荐)
这是最清晰、最稳定的方案,通过自定义PodMonitor资源,分别为每个容器配置专属的采集规则,完全隔离两个容器的采集逻辑。
步骤:
首先确保你的Pod里每个容器的端口都定义了name字段(方便PodMonitor精准匹配),比如Pod的YAML片段:
spec: containers: - name: https-container image: your-image ports: - name: metrics-https containerPort: 443 - name: http-container image: your-image ports: - name: metrics-http containerPort: 8080
然后创建针对HTTPS容器的PodMonitor:
apiVersion: monitoring.coreos.com/v1 kind: PodMonitor metadata: name: app-https-monitor labels: release: prometheus # 这个标签要和你的Prometheus实例的匹配标签一致 spec: selector: matchLabels: app: your-app-name # 匹配你的Pod的标签 podMetricsEndpoints: - port: metrics-https # 对应上面Pod里HTTPS容器的端口name scheme: https path: /metrics tlsConfig: insecureSkipVerify: true # 如果是自签证书需要开启这个,生产环境建议配置CA证书
再创建针对HTTP容器的PodMonitor:
apiVersion: monitoring.coreos.com/v1 kind: PodMonitor metadata: name: app-http-monitor labels: release: prometheus spec: selector: matchLabels: app: your-app-name podMetricsEndpoints: - port: metrics-http # 对应HTTP容器的端口name scheme: http path: /metrics
创建完成后,Prometheus会自动发现这两个PodMonitor,分别采集两个容器的指标。
2. 用Relabel规则动态切换协议
如果不想手动创建多个Monitor,可以通过修改Prometheus的采集配置,添加relabel规则,根据目标容器的端口自动切换scheme。
步骤:
首先在Pod的注解里只保留开启采集的配置,不要指定port和scheme:
annotations: prometheus.io/scrape: "true"
然后在Prometheus的scrape配置中(比如kube-prometheus-stack的values.yaml里的additionalScrapeConfigs)添加自定义的job:
- job_name: 'multi-container-pods' kubernetes_sd_configs: - role: pod relabel_configs: # 只保留开启了prometheus.io/scrape=true的Pod - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] action: keep regex: true # 根据端口设置scheme:443端口用https,8080端口用http - source_labels: [__meta_kubernetes_pod_container_port_number] action: replace target_label: __scheme__ regex: '443' replacement: 'https' - source_labels: [__meta_kubernetes_pod_container_port_number] action: replace target_label: __scheme__ regex: '8080' replacement: 'http' # 保留默认的标签映射,方便后续查询 - source_labels: [__meta_kubernetes_pod_name] action: replace target_label: pod - source_labels: [__meta_kubernetes_pod_container_name] action: replace target_label: container metric_relabel_configs: # 可以在这里添加指标过滤规则(可选)
这个方法会让Prometheus自动发现Pod里的所有容器端口,然后根据端口号自动切换采集协议,适合批量处理多个类似Pod的场景。
3. 尝试多端口/多Scheme注解(版本依赖)
部分较新的Prometheus自动发现组件支持用逗号分隔的方式,为多个端口指定对应的scheme,比如在Pod注解里这样配置:
annotations: prometheus.io/scrape: "true" prometheus.io/port: "443,8080" prometheus.io/scheme: "https,http"
注意:这个特性不是所有版本都支持,需要确认你的Prometheus(以及kube-prometheus-stack)版本是否在v30以上,或者对应的自动发现组件是否支持这种一一映射的逻辑。如果版本不兼容,这个方法会失效。
内容的提问来源于stack exchange,提问作者croeck

