环境信息
kubectl version
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"}
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/exporter
cd /u01/repo/exporter
vim prom-blackbox.yaml
kubectl create -f prom-blackbox.yaml
kubectl apply -f prom-blackbox.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: blackbox-exporter
name: blackbox-exporter
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
app: blackbox-exporter
template:
metadata:
labels:
app: blackbox-exporter
spec:
containers:
- image: prom/blackbox-exporter
imagePullPolicy: IfNotPresent
name: blackbox-exporter
---
apiVersion: v1
kind: Service
metadata:
labels:
app: blackbox-exporter
name: blackbox-exporter
namespace: kube-system
spec:
ports:
- name: blackbox
port: 9115
protocol: TCP
selector:
app: blackbox-exporter
几点需要注意:
- 此处的命名空间是
kube-system
,那么,在Prometheus抓取任务中,K8S服务发现需要添加这个命名空间,否则无法抓取 - Service维度可以通过两种方式实现:
- 通过
apiserver proxy URLs
代理方式访问(本例采用此种方案) - 通过
NodePort
方式暴露blackbox-exporter
的指标端口:30115
- 通过
- 抓取任务端点设置为:
/probe
- 抓取任务协议设置为:
http
Service准备
mkdir -p /u01/repo/exporter
cd /u01/repo/exporter
vim prom-redis.yaml
kubectl create -f prom-redis.yaml
kubectl apply -f prom-redis.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: kube-system
labels:
app: redis
spec:
selector:
matchLabels:
app: redis
template:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/path: "/metrics"
prometheus.io/port: "9121"
labels:
app: redis
spec:
containers:
- name: redis
image: redis:4
resources:
requests:
cpu: 100m
memory: 100Mi
ports:
- containerPort: 6379
- name: redis-exporter
image: oliver006/redis_exporter:latest
resources:
requests:
cpu: 100m
memory: 100Mi
ports:
- containerPort: 9121
---
kind: Service
apiVersion: v1
metadata:
annotations:
prometheus.io/probe: "true"
name: redis
namespace: kube-system
spec:
selector:
app: redis
ports:
- name: redis
port: 6379
targetPort: 6379
- name: prom
port: 9121
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 | |
最终抓取任务配置
- job_name: K8S-SERVICES
honor_timestamps: true
params:
module:
- http_2xx
scrape_interval: 1m
scrape_timeout: 10s
metrics_path: /probe
scheme: https
file_sd_configs:
- files:
- /u01/prometheus/target/nodes/K8S-SERVICES_targets_hosts.json
refresh_interval: 5m
kubernetes_sd_configs:
- api_server: https://172.23.16.106:8443
role: service
bearer_token: <secret>
tls_config:
insecure_skip_verify: true
namespaces:
names:
- default
- kube-system
bearer_token: <secret>
tls_config:
insecure_skip_verify: true
relabel_configs:
- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_probe]
separator: ;
regex: "true"
replacement: $1
action: keep
- source_labels: [__address__]
separator: ;
regex: (.*)
target_label: __param_target
replacement: $1
action: replace
- separator: ;
regex: (.*)
target_label: __address__
replacement: 172.23.16.106:8443
action: replace
- separator: ;
regex: (.*)
target_label: __metrics_path__
replacement: /api/v1/namespaces/kube-system/services/http:blackbox-exporter:9115/proxy/metrics
action: replace
- source_labels: [__param_target]
separator: ;
regex: (.*)
target_label: instance
replacement: $1
action: replace
- separator: ;
regex: __meta_kubernetes_service_label_(.+)
replacement: $1
action: labelmap
- source_labels: [__meta_kubernetes_namespace]
separator: ;
regex: (.*)
target_label: kubernetes_namespace
replacement: $1
action: replace
- source_labels: [__meta_kubernetes_service_name]
separator: ;
regex: (.*)
target_label: kubernetes_name
replacement: $1
action: replace
- separator: ;
regex: (.*)
target_label: PersonNum
replacement: hops
action: replace
- separator: ;
regex: (.*)
target_label: _tenant_id
replacement: "0"
action: replace
验证预览
结论
此种方案适合于通过blackbox-exporter
探测各个服务的HTTP状态情况。其实就是自动发现Service,然后重写发现Service之后的探测地址为blackbox-exporter
地址(此处是通过apiserver proxy URLs
方式进行构造的),同时,将target
参数设置为Service
的原始地址作为探测目标。