环境信息

  1. kubectl version
  2. Client 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"}
  3. 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-exportertarget参数使用(这是黑盒监控本身的原理)。

监控准备

黑盒探测Service准备

  1. mkdir -p /u01/repo/exporter
  2. cd /u01/repo/exporter
  3. vim prom-blackbox.yaml
  4. kubectl create -f prom-blackbox.yaml
  5. kubectl apply -f prom-blackbox.yaml
  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. labels:
  5. app: blackbox-exporter
  6. name: blackbox-exporter
  7. namespace: kube-system
  8. spec:
  9. replicas: 1
  10. selector:
  11. matchLabels:
  12. app: blackbox-exporter
  13. template:
  14. metadata:
  15. labels:
  16. app: blackbox-exporter
  17. spec:
  18. containers:
  19. - image: prom/blackbox-exporter
  20. imagePullPolicy: IfNotPresent
  21. name: blackbox-exporter
  22. ---
  23. apiVersion: v1
  24. kind: Service
  25. metadata:
  26. labels:
  27. app: blackbox-exporter
  28. name: blackbox-exporter
  29. namespace: kube-system
  30. spec:
  31. ports:
  32. - name: blackbox
  33. port: 9115
  34. protocol: TCP
  35. selector:
  36. app: blackbox-exporter

几点需要注意:

  • 此处的命名空间是kube-system,那么,在Prometheus抓取任务中,K8S服务发现需要添加这个命名空间,否则无法抓取
  • Service维度可以通过两种方式实现:
    • 通过apiserver proxy URLs代理方式访问(本例采用此种方案)
    • 通过NodePort方式暴露blackbox-exporter的指标端口:30115
  • 抓取任务端点设置为:/probe
  • 抓取任务协议设置为:http

Service准备

  1. mkdir -p /u01/repo/exporter
  2. cd /u01/repo/exporter
  3. vim prom-redis.yaml
  4. kubectl create -f prom-redis.yaml
  5. kubectl apply -f prom-redis.yaml
  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: redis
  5. namespace: kube-system
  6. labels:
  7. app: redis
  8. spec:
  9. selector:
  10. matchLabels:
  11. app: redis
  12. template:
  13. metadata:
  14. annotations:
  15. prometheus.io/scrape: "true"
  16. prometheus.io/path: "/metrics"
  17. prometheus.io/port: "9121"
  18. labels:
  19. app: redis
  20. spec:
  21. containers:
  22. - name: redis
  23. image: redis:4
  24. resources:
  25. requests:
  26. cpu: 100m
  27. memory: 100Mi
  28. ports:
  29. - containerPort: 6379
  30. - name: redis-exporter
  31. image: oliver006/redis_exporter:latest
  32. resources:
  33. requests:
  34. cpu: 100m
  35. memory: 100Mi
  36. ports:
  37. - containerPort: 9121
  38. ---
  39. kind: Service
  40. apiVersion: v1
  41. metadata:
  42. annotations:
  43. prometheus.io/probe: "true"
  44. name: redis
  45. namespace: kube-system
  46. spec:
  47. selector:
  48. app: redis
  49. ports:
  50. - name: redis
  51. port: 6379
  52. targetPort: 6379
  53. - name: prom
  54. port: 9121
  55. targetPort: 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 | |

最终抓取任务配置

  1. - job_name: K8S-SERVICES
  2. honor_timestamps: true
  3. params:
  4. module:
  5. - http_2xx
  6. scrape_interval: 1m
  7. scrape_timeout: 10s
  8. metrics_path: /probe
  9. scheme: https
  10. file_sd_configs:
  11. - files:
  12. - /u01/prometheus/target/nodes/K8S-SERVICES_targets_hosts.json
  13. refresh_interval: 5m
  14. kubernetes_sd_configs:
  15. - api_server: https://172.23.16.106:8443
  16. role: service
  17. bearer_token: <secret>
  18. tls_config:
  19. insecure_skip_verify: true
  20. namespaces:
  21. names:
  22. - default
  23. - kube-system
  24. bearer_token: <secret>
  25. tls_config:
  26. insecure_skip_verify: true
  27. relabel_configs:
  28. - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_probe]
  29. separator: ;
  30. regex: "true"
  31. replacement: $1
  32. action: keep
  33. - source_labels: [__address__]
  34. separator: ;
  35. regex: (.*)
  36. target_label: __param_target
  37. replacement: $1
  38. action: replace
  39. - separator: ;
  40. regex: (.*)
  41. target_label: __address__
  42. replacement: 172.23.16.106:8443
  43. action: replace
  44. - separator: ;
  45. regex: (.*)
  46. target_label: __metrics_path__
  47. replacement: /api/v1/namespaces/kube-system/services/http:blackbox-exporter:9115/proxy/metrics
  48. action: replace
  49. - source_labels: [__param_target]
  50. separator: ;
  51. regex: (.*)
  52. target_label: instance
  53. replacement: $1
  54. action: replace
  55. - separator: ;
  56. regex: __meta_kubernetes_service_label_(.+)
  57. replacement: $1
  58. action: labelmap
  59. - source_labels: [__meta_kubernetes_namespace]
  60. separator: ;
  61. regex: (.*)
  62. target_label: kubernetes_namespace
  63. replacement: $1
  64. action: replace
  65. - source_labels: [__meta_kubernetes_service_name]
  66. separator: ;
  67. regex: (.*)
  68. target_label: kubernetes_name
  69. replacement: $1
  70. action: replace
  71. - separator: ;
  72. regex: (.*)
  73. target_label: PersonNum
  74. replacement: hops
  75. action: replace
  76. - separator: ;
  77. regex: (.*)
  78. target_label: _tenant_id
  79. replacement: "0"
  80. action: replace

验证预览

image.png

结论

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