环境信息
kubectl versionClient Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.9", GitCommit:"a17149e1a189050796ced469dbd78d380f2ed5ef", GitTreeState:"clean", BuildDate:"2020-04-16T11:44:51Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}Server Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.9", GitCommit:"a17149e1a189050796ced469dbd78d380f2ed5ef", GitTreeState:"clean", BuildDate:"2020-04-16T11:36:15Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}
术语解释
- Endpoint:抓取目标实际访问的抓取地址,组成为:
__scheme__+__address__+__metrics_path__。因此,很多标签重写都是重写的其中之一,或者全部,例如,__address_以及__metrics_path_两个是高频重写点
原理解析
blackbox-exporter是一个黑盒探测工具,可以对服务的http、tcp、icmp等进行网络探测。
Prometheus自动发现K8S的服务地址,然后统一通过blackbox-exporter进行监控,因此,每发现一个Service,均需要重写默认生成的__address__为blackbox-exporter地址及端口;同时,将服务的地址(默认的__address)作为blackbox-exporter的target参数使用(这是黑盒监控本身的原理)。
监控准备
黑盒探测Service准备
mkdir -p /u01/repo/exportercd /u01/repo/exportervim prom-blackbox.yamlkubectl create -f prom-blackbox.yamlkubectl apply -f prom-blackbox.yaml
apiVersion: apps/v1kind: Deploymentmetadata:labels:app: blackbox-exportername: blackbox-exporternamespace: kube-systemspec:replicas: 1selector:matchLabels:app: blackbox-exportertemplate:metadata:labels:app: blackbox-exporterspec:containers:- image: prom/blackbox-exporterimagePullPolicy: IfNotPresentname: blackbox-exporter---apiVersion: v1kind: Servicemetadata:labels:app: blackbox-exportername: blackbox-exporternamespace: kube-systemspec:ports:- name: blackboxport: 9115protocol: TCPselector:app: blackbox-exporter
几点需要注意:
- 此处的命名空间是
kube-system,那么,在Prometheus抓取任务中,K8S服务发现需要添加这个命名空间,否则无法抓取 - Service维度可以通过两种方式实现:
- 通过
apiserver proxy URLs代理方式访问(本例采用此种方案) - 通过
NodePort方式暴露blackbox-exporter的指标端口:30115
- 通过
- 抓取任务端点设置为:
/probe - 抓取任务协议设置为:
http
Service准备
mkdir -p /u01/repo/exportercd /u01/repo/exportervim prom-redis.yamlkubectl create -f prom-redis.yamlkubectl apply -f prom-redis.yaml
apiVersion: apps/v1kind: Deploymentmetadata:name: redisnamespace: kube-systemlabels:app: redisspec:selector:matchLabels:app: redistemplate:metadata:annotations:prometheus.io/scrape: "true"prometheus.io/path: "/metrics"prometheus.io/port: "9121"labels:app: redisspec:containers:- name: redisimage: redis:4resources:requests:cpu: 100mmemory: 100Miports:- containerPort: 6379- name: redis-exporterimage: oliver006/redis_exporter:latestresources:requests:cpu: 100mmemory: 100Miports:- containerPort: 9121---kind: ServiceapiVersion: v1metadata:annotations:prometheus.io/probe: "true"name: redisnamespace: kube-systemspec:selector:app: redisports:- name: redisport: 6379targetPort: 6379- name: promport: 9121targetPort: 9121
几点需要注意:
- 此处的命名空间是
kube-system,那么,在Prometheus抓取任务中,K8S服务发现需要添加这个命名空间,否则无法抓取 - Service维度需要增加一个元数据标签注解,注意,此处是
probe而不是POD时的scrape:- prometheus.io/probe: “true”
核心配置项解析
抓取任务配置
| 任务编码 | 指标路径 | 协议 | 请求参数 | 认证授权及TLS | 说明 |
|---|---|---|---|---|---|
| K8S-SERVICES | /probe | https | module: [http_2xx] | Token认证,禁用验证服务器端证书 | 注意,此处是https协议,后续会使用apiserver proxy URLs方式代理访问,路径为/probe,需要指定blackbox-exporter使用的module |
K8S服务发现配置
| 资源类型 | API Server地址 | 命名空间 | 认证授权及TLS | 说明 |
|---|---|---|---|---|
| service | https://172.23.16.106:8443 | default,kube-system | Token认证,禁用验证服务器端证书 | API Server地址此处配置的是负载均衡地址,命名空间正常讲应该留空,代表所有空间;此处因为实例中准备的服务都在kube-system命名空间下,因此,此处将其纳入进来 |
标签重写配置
K8S-SERVICES
Service上需要增加如下元数据标签主机:
- prometheus.io/probe: true
标签重写主要关注如下几点:
- 需要过滤掉不需要监控的端点,仅保留
prometheus.io/probe: true - 指定blackbox-exporter的target为
__address__,也即原始待监控的服务端点信息 - 最终的抓取目标地址
__address__实际上是apiserver的地址 - 最终的抓取目标指标路径
__metrics_path__,此处设置为通过apiserver proxy URLs方式汇总的services/proxy形式来进行,因为需要指定服务blackbox-exporter的命名空间、服务名、服务端口,显然通过pods/proxy形式是不行的(因为POD名称是动态生成的,并不是配置指定的,无法手工指定);另外,因为使用services/proxy形式的代理方式,因此,认证Token所对应的ServiceAccount被授予的角色需要具备services/proxy子资源的相关权限,否则一样会报403错误 - 替换
instance标签的值为实际待监控的服务地址:因为默认如果不修改,那么,instance地址就会变成apiserver抓取目标的地址了,因此,我们也看不到实际探测的目标服务了,需要重写保留 - 添加额外的富有含义的指标
- 生成
命名空间标签 - 生成
服务名标签 | 序号 | 重写动作 | 来源标签名称 | 分隔符 | 正则匹配 | Hash模数 | 目标标签名称 | 目标标签替换值 | | —- | —- | —- | —- | —- | —- | —- | —- | | 1 | 保持 |[__meta_kubernetes_service_annotation_prometheus_io_probe]| | true | | | | | 2 | 替换 |[__address__]| | | |__param_target| | | 3 | 替换 | | | | |__address__| 172.23.16.106:8443 | | 4 | 替换 | | | | |__metrics_path__|/api/v1/namespaces/kube-system/services/http:blackbox-exporter:9115/proxy/metrics| | 5 | 替换 |[__param_target]| | | |instance| | | 6 | 标签映射 | | | |__meta_kubernetes_service_label_(.+)| | | | 7 | 替换 |[__meta_kubernetes_namespace]| | | | kubernetes_namespace | | | 8 | 替换 |[__meta_kubernetes_service_name]| | | | kubernetes_name | |
最终抓取任务配置
- job_name: K8S-SERVICEShonor_timestamps: trueparams:module:- http_2xxscrape_interval: 1mscrape_timeout: 10smetrics_path: /probescheme: httpsfile_sd_configs:- files:- /u01/prometheus/target/nodes/K8S-SERVICES_targets_hosts.jsonrefresh_interval: 5mkubernetes_sd_configs:- api_server: https://172.23.16.106:8443role: servicebearer_token: <secret>tls_config:insecure_skip_verify: truenamespaces:names:- default- kube-systembearer_token: <secret>tls_config:insecure_skip_verify: truerelabel_configs:- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_probe]separator: ;regex: "true"replacement: $1action: keep- source_labels: [__address__]separator: ;regex: (.*)target_label: __param_targetreplacement: $1action: replace- separator: ;regex: (.*)target_label: __address__replacement: 172.23.16.106:8443action: replace- separator: ;regex: (.*)target_label: __metrics_path__replacement: /api/v1/namespaces/kube-system/services/http:blackbox-exporter:9115/proxy/metricsaction: replace- source_labels: [__param_target]separator: ;regex: (.*)target_label: instancereplacement: $1action: replace- separator: ;regex: __meta_kubernetes_service_label_(.+)replacement: $1action: labelmap- source_labels: [__meta_kubernetes_namespace]separator: ;regex: (.*)target_label: kubernetes_namespacereplacement: $1action: replace- source_labels: [__meta_kubernetes_service_name]separator: ;regex: (.*)target_label: kubernetes_namereplacement: $1action: replace- separator: ;regex: (.*)target_label: PersonNumreplacement: hopsaction: replace- separator: ;regex: (.*)target_label: _tenant_idreplacement: "0"action: replace
验证预览

结论
此种方案适合于通过blackbox-exporter探测各个服务的HTTP状态情况。其实就是自动发现Service,然后重写发现Service之后的探测地址为blackbox-exporter地址(此处是通过apiserver proxy URLs方式进行构造的),同时,将target参数设置为Service的原始地址作为探测目标。
