在Kubernetes下部署Prometheus

使用ConfigMaps管理应用配置

当使用Deployment管理和部署应用程序时,用户可以方便了对应用进行扩容或者缩容,从而产生多个Pod实例。为了 能够统一管理这些Pod的配置信息,在Kubernetes中可以使用ConfigMaps资源定义和管理这些配置,并且通过环境 变量或者文件系统挂载的方式让容器使用这些配置。 这里将使用ConfigMaps管理Prometheus的配置文件,创建prometheus-config.yml文件,并写入以下内容:

apiVersion: v1
data:
  prometheus.yml: |-
    global:
      scrape_interval: 15s
      evaluation_interval: 15s
    scrape_configs:
    - job_name: ''prometheus''
      static_configs:
      - targets: ['localhost:9090']




kind: ConfigMap
metadata:
  name: prometheus-config

使用kubectl命令行工具,在命名空间default创建ConfigMap资源:

 kubectl create -f prometheus-config.yml
 configmap "prometheus-config" created

使用Deployment部署Prometheus

当ConfigMap资源创建成功后,我们就可以通过Volume挂载的方式,将Prometheus的配置文件挂载到容器中。 这 里我们通过Deployment部署Prometheus Server实例,创建prometheus-deployment.yml文件,并写入以下 内容:

apiVersion: v1
kind: "Service"
metadata:
  name: prometheus
  labels:
    name: prometheus
spec:
  ports:
  - name: prometheus
    protocol: TCP
    port: 9090
    targetPort: 9090
  selector:
    app: prometheus
  type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    name: prometheus
  name: prometheus
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prometheus
  template:
    metadata:
      labels:
        app: prometheus
    spec:
      serviceAccountName: prometheus
      serviceAccount: prometheus
      containers:
      - name: prometheus
        image: prom/prometheus:v2.2.1
        command:
        - "/bin/prometheus"
        args:
        - "--config.file=/etc/prometheus/prometheus.yml"
        ports:
        - containerPort: 9090
          protocol: TCP
        volumeMounts:
        - mountPath: "/etc/prometheus"
          name: prometheus-config
      volumes:
      - name: prometheus-config
        configMap:
          name: prometheus-config

该文件中分别定义了Service和Deployment,Service类型为NodePort,这样我们可以通过虚拟机IP和端口访问 到Prometheus实例。为了能够让Prometheus实例使用ConfigMap中管理的配置文件,这里通过volumes声明了一 个磁盘卷。并且通过volumeMounts将该磁盘卷挂载到了Prometheus实例的/etc/prometheus目录下。

使用以下命令创建资源,并查看资源的创建情况:

 $ kubectl create -f prometheus-deployment.yml
 service "prometheus" created
 deployment "prometheus" created
$ kubectl get pods

NAME                               READY   STATUS    RESTARTS   AGE
prometheus-7f57d48b8d-fxm9j        1/1     Running   0          8m31s
$ kubectl get svc
[root@k8s-01 ~]#  kubectl get svc
NAME                TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)          AGE
kubernetes          ClusterIP   10.1.0.1     <none>        443/TCP          29d
prometheus          NodePort    10.1.67.80   <none>        9090:30880/TCP   5h1m

至此,我们可以通过虚拟机的IP地址和端口3xxxx访问到Prometheus的服务。

Kubernetes下的服务发现

目前为止,我们已经能够在Kubernetes下部署一个简单的Prometheus实例,不过当前来说它并不能发挥其监控系 统的作用,除了Prometheus,暂时没有任何的监控采集目标。在第7章中,我们介绍了Prometheus的服务发现能 力,它能够与通过与“中间代理人“的交互,从而动态的获取需要监控的目标实例。而在Kubernetes下Prometheus 就是需要与Kubernetes的API进行交互,从而能够动态的发现Kubernetes中部署的所有可监控的目标资源。

Kubernetes的访问授权

为了能够让Prometheus能够访问收到认证保护的Kubernetes API,我们首先需要做的是,对Prometheus进行访 问授权。在Kubernetes中主要使用基于角色的访问控制模型(Role-Based Access Control),用于管理 Kubernetes下资源访问权限。首先我们需要在Kubernetes下定义角色(ClusterRole),并且为该角色赋予响应 的访问权限。同时创建Prometheus所使用的账号(ServiceAccount),最后则是将该账号与角色进行绑定 (ClusterRoleBinding)。这些所有的操作在Kubernetes同样被视为是一系列的资源,可以通过YAML文件进行 描述并创建,这里创建prometheus-rbac-setup.yml文件,并写入以下内容:

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: prometheus
rules:
- apiGroups: [""]
  resources:
  - nodes
  - nodes/proxy
  - services
  - endpoints
  - pods
  verbs: ["get", "list", "watch"]
- apiGroups:
  - extensions
  resources:
  - ingresses
  verbs: ["get", "list", "watch"]
- nonResourceURLs: ["/metrics"]
  verbs: ["get"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: prometheus
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: prometheus
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: prometheus
subjects:
- kind: ServiceAccount
  name: prometheus
  namespace: default

其中需要注意的是ClusterRole是全局的,不需要指定命名空间。而ServiceAccount是属于特定命名空间的资 源。通过kubectl命令创建RBAC对应的各个资源:

 $ kubectl create -f prometheus-rbac-setup.yml
 clusterrole "prometheus" created
 serviceaccount "prometheus" created
 clusterrolebinding "prometheus" created

在完成角色权限以及用户的绑定之后,就可以指定Prometheus使用特定的ServiceAccount创建Pod实例。修改 prometheus-deployment.yml文件,并添加serviceAccountName和serviceAccount定义:

spec:
  replicas: 1
  selector:
    matchLabels:
      app: prometheus
  template:
    metadata:
      labels:
        app: prometheus
    spec:
      serviceAccountName: prometheus
      serviceAccount: prometheus

通过kubectl apply对Deployment进行变更升级:

 $ kubectl apply -f prometheus-deployment.yml
 service "prometheus" configured
 deployment "prometheus" configured

 $ kubectl get pods
NAME READY STATUS RESTARTS AGE
prometheus-7f57d48b8d-n4sns        1/1     Running   0          4m19s

指定ServiceAccount创建的Pod实例中,会自动将用于访问Kubernetes API的CA证书以及当前账户对应的访问令 牌文件挂载到Pod实例的/var/run/secrets/kubernetes.io/serviceaccount/目录下,可以通过以下命令进 行查看:

[root@k8s-01 ~]# kubectl exec -it prometheus-7f57d48b8d-n4sns ls /var/run/secrets/kubernetes.io/serviceaccount/
ca.crt     namespace  token

服务发现

在Kubernetes下,Promethues通过与Kubernetes API集成目前主要支持5种服务发现模式,分别是:Node、 Service、Pod、Endpoints、Ingress。

通过kubectl命令行,可以方便的获取到当前集群中的所有节点信息:

    - job_name: 'kubernetes-nodes'
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      kubernetes_sd_configs:
      - role: node

通过指定kubernetes_sd_config的模式为node,Prometheus会自动从Kubernetes中发现到所有的node节点并 作为当前Job监控的Target实例。如下所示,这里需要指定用于访问Kubernetes API的ca以及token文件路径。

对于Ingress,Service,Endpoints, Pod的使用方式也是类似的,下面给出了一个完整Prometheus配置的示 例:

apiVersion: v1
data:
  prometheus.yml: |-
    global:
      scrape_interval: 15s
      evaluation_interval: 15s
    scrape_configs:
    - job_name: 'kubernetes-nodes'
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      kubernetes_sd_configs:
      - role: node

    - job_name: 'kubernetes-service'
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      kubernetes_sd_configs:
      - role: service

    - job_name: 'kubernetes-endpoints'
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      kubernetes_sd_configs:
      - role: endpoints

    - job_name: 'kubernetes-ingress'
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      kubernetes_sd_configs:
      - role: ingress

    - job_name: 'kubernetes-pods'
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      kubernetes_sd_configs:
      - role: pod

    - job_name: 'prometheus'
      static_configs:
      - targets: ['localhost:9090'] 

kind: ConfigMap
metadata:
  name: prometheus-config

更新Prometheus配置文件,并重建Prometheus实例:

1. $ kubectl apply -f prometheus-config.yml
2. configmap "prometheus-config" configured
3.
4. $ kubectl get pods
5. prometheus-69f9ddb588-rbrs2 1/1 Running 0 4m
6.
7. $ kubectl delete pods prometheus-69f9ddb588-rbrs2
8. pod "prometheus-69f9ddb588-rbrs2" deleted
9.
10. $ kubectl get pods
11. prometheus-69f9ddb588-rbrs2 0/1 Terminating 0 4m
12. prometheus-69f9ddb588-wtlsn 1/1 Running 0 14s

Prometheus使用新的配置文件重建之后,打开Prometheus UI,通过Service Discovery页面可以查看到当前 Prometheus通过Kubernetes发现的所有资源对象了:

 同时Prometheus会自动将该资源的所有信息,并通过标签的形式体现在Target对象上。如下所示,是Promthues 获取到的Node节点的标签信息:

目前为止,我们已经能够通过Prometheus自动发现Kubernetes集群中的各类资源以及其基本信息。不过,如果现 在查看Promtheus的Target状态页面,结果可能会让人不太满意:

虽然Prometheus能够自动发现所有的资源对象,并且将其作为Target对象进行数据采集。 但并不是所有的资源对 象都是支持Promethues的,并且不同类型资源对象的采集方式可能是不同的。因此,在实际的操作中,我们需要有 明确的监控目标,并且针对不同类型的监控目标设置不同的数据采集方式。

接下来,我们将利用Promtheus的服务发现能力,实现对Kubernetes集群的全面监控。

使用Prometheus监控Kubernetes集群

下表中,梳理了监控Kubernetes集群监控的各个维度以及策略:

从Kubelet获取节点运行状态

Kubelet组件运行在Kubernetes集群的各个节点中,其负责维护和管理节点上Pod的运行状态。kubelet组件的正 常运行直接关系到该节点是否能够正常的被Kubernetes集群正常使用。

基于Node模式,Prometheus会自动发现Kubernetes中所有Node节点的信息并作为监控的目标Target。 而这些 Target的访问地址实际上就是Kubelet的访问地址,并且Kubelet实际上直接内置了对Promtheus的支持。

修改prometheus.yml配置文件,并添加以下采集任务配置:

    - job_name: 'kubernetes-kubelet'
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      kubernetes_sd_configs:
      - role: node
      relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)
      - target_label: __address__
        replacement: kubernetes.default.svc:443
      - source_labels: [__meta_kubernetes_node_name]
        regex: (.+)
        target_label: __metrics_path__
        replacement: /api/v1/nodes/${1}/proxy/metrics

通过获取各个节点中kubelet的监控指标,用户可以评估集群中各节点的性能表现。例如,通过指标 kubelet_pod_start_latency_microseconds可以获得当前节点中Pod启动时间相关的统计数据。

 kubelet_pod_start_latency_microseconds{quantile="0.99"}

 Pod平均启动时间大致为42s左右(包含镜像下载时间):

kubelet_pod_start_latency_microseconds_sum / kubelet_pod_start_latency_microseconds_count

除此以外,监控指标kubeletdocker*还可以体现出kubelet与当前节点的docker服务的调用情况,从而可以反映 出docker本身是否会影响kubelet的性能表现等问题。

从Kubelet获取节点容器资源使用情况

各节点的kubelet组件中除了包含自身的监控指标信息以外,kubelet组件还内置了对cAdvisor的支持。 cAdvisor能够获取当前节点上运行的所有容器的资源使用情况,通过访问kubelet的/metrics/cadvisor地址可 以获取到cadvisor的监控指标,因此和获取kubelet监控指标类似,这里同样通过node模式自动发现所有的 kubelet信息,并通过适当的relabel过程,修改监控采集任务的配置。 与采集kubelet自身监控指标相似:

    - job_name: 'kubernetes-cadvisor'
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      kubernetes_sd_configs:
      - role: node
      relabel_configs:
      - target_label: __address__
        replacement: kubernetes.default.svc:443
      - source_labels: [__meta_kubernetes_node_name]
        regex: (.+)
        target_label: __metrics_path__
        replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)

使用NodeExporter监控集群资源使用情况

为了能够采集集群中各个节点的资源使用情况,我们需要在各节点中部署一个Node Exporter实例。在本章的“部署 Prometheus”小节,我们使用了Kubernetes内置的控制器之一Deployment。Deployment能够确保Prometheus 的Pod能够按照预期的状态在集群中运行,而Pod实例可能随机运行在任意节点上。而与Prometheus的部署不同的 是,对于Node Exporter而言每个节点只需要运行一个唯一的实例,此时,就需要使用Kubernetes的另外一种控制 器Daemonset。顾名思义,Daemonset的管理方式类似于操作系统中的守护进程。Daemonset会确保在集群中所有 (也可以指定)节点上运行一个唯一的Pod实例。

创建node-exporter-daemonset.yml文件,并写入以下内容:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter
spec:
  selector:
    matchLabels:
      app: node-exporter
  template:
    metadata:
      annotations:
        prometheus.io/scrape: 'true'
        prometheus.io/port: '9100'
        prometheus.io/path: 'metrics'
      labels:
        app: node-exporter
        name: node-exporter
    spec:
      containers:
      - image: prom/node-exporter
        imagePullPolicy: IfNotPresent
        name: node-exporter
        ports:
        - containerPort: 9100   
          hostPort: 9100
          name: scrape
      hostNetwork: true
      hostPID: true

由于Node Exporter需要能够访问宿主机,因此这里指定了hostNetwork和hostPID,让Pod实例能够以主机网络 以及系统进程的形式运行。同时YAML文件中也创建了NodeExporter相应的Service。这样通过Service就可以访 问到对应的NodeExporter实例。

 $ kubectl create -f node-exporter-daemonset.yml
 service "node-exporter" created
 daemonset "node-exporter" created

查看Daemonset以及Pod的运行状态

 $ kubectl get daemonsets
 NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
 node-exporter 1 1 1 1 1 <none> 15s

 $ kubectl get pods
 NAME READY STATUS RESTARTS AGE
 ...
 node-exporter-9h56z 1/1 Running 0 51s

由于Node Exporter是以主机网络的形式运行,因此直接访问虚拟机IP加上Pod的端口即可访问当前节 点上运行的Node Exporter实例:

[root@k8s-01 ~]# curl http://k8s-02:9100/metrics  |head
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0# HELP go_gc_duration_seconds A summary of the GC invocation durations.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 1.7503e-05
go_gc_duration_seconds{quantile="0.25"} 2.9973e-05
go_gc_duration_seconds{quantile="0.5"} 5.2475e-05
go_gc_duration_seconds{quantile="0.75"} 8.2703e-05
go_gc_duration_seconds{quantile="1"} 0.001951054
go_gc_duration_seconds_sum 0.067789147
go_gc_duration_seconds_count 834
# HELP go_goroutines Number of goroutines that currently exist.
100 44764    0 44764    0     0  1207k      0 --:--:-- --:--:-- --:--:-- 1248k

目前为止,通过Daemonset的形式将Node Exporter部署到了集群中的各个节点中。接下来,我们只需要通过 Prometheus的pod服务发现模式,找到当前集群中部署的Node Exporter实例即可。 需要注意的是,由于 Kubernetes中并非所有的Pod都提供了对Prometheus的支持,有些可能只是一些简单的用户应用,为了区分哪些 Pod实例是可以供Prometheus进行采集的,这里我们为Node Exporter添加了注解:

 prometheus.io/scrape: 'true'

由于Kubernetes中Pod可能会包含多个容器,还需要用户通过注解指定用户提供监控指标的采集端口:

prometheus.io/port: '9100'

而有些情况下,Pod中的容器可能并没有使用默认的/metrics作为监控采集路径,因此还需要支持用户指定采集路 径:

 prometheus.io/path: 'metrics'

为Prometheus创建监控采集任务kubernetes-pods,如下所示:

    - 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: kubernetes_namespace
      - source_labels: [__meta_kubernetes_pod_name]
        action: replace
        target_label: kubernetes_pod_name

通过以上relabel过程实现对Pod实例的过滤,以及采集任务地址替换,从而实现对特定Pod实例监控指标的采集。需 要说明的是kubernetes-pods并不是只针对Node Exporter而言,对于用户任意部署的Pod实例,只要其提供了对 Prometheus的支持,用户都可以通过为Pod添加注解的形式为其添加监控指标采集的支持。

从kube-apiserver获取集群运行监控指标

在开始正式内容之前,我们需要先了解一下Kubernetes中Service是如何实现负载均衡的,如下图所示,一般来说 Service有两个主要的使用场景:

代理对集群内部应用Pod实例的请求:当创建Service时如果指定了标签选择器,Kubernetes会监听集群中所 有的Pod变化情况,通过Endpoints自动维护满足标签选择器的Pod实例的访问信息;

代理对集群外部服务的请求:当创建Service时如果不指定任何的标签选择器,此时需要用户手动创建 Service对应的Endpoint资源。例如,一般来说,为了确保数据的安全,我们通常讲数据库服务部署到集群 外。 这是为了避免集群内的应用硬编码数据库的访问信息,这是就可以通过在集群内创建Service,并指向外 部的数据库服务实例。

kube-apiserver扮演了整个Kubernetes集群管理的入口的角色,负责对外暴露Kubernetes API。kubeapiserver组件一般是独立部署在集群外的,为了能够让部署在集群内的应用(kubernetes插件或者用户应用)能 够与kube-apiserver交互,Kubernetes会默认在命名空间下创建一个名为kubernetes的服务,如下所示:

[root@k8s-01 ~]# kubectl get svc kubernetes -o wide
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE   SELECTOR
kubernetes   ClusterIP   10.1.0.1     <none>        443/TCP   29d   <none>

而该kubernetes服务代理的后端实际地址通过endpoints进行维护,如下所示:

[root@k8s-01 ~]#  kubectl get endpoints kubernetes
NAME         ENDPOINTS            AGE
kubernetes   192.168.122.2:6443   29d

通过这种方式集群内的应用或者系统主机就可以通过集群内部的DNS域名kubernetes.default.svc访问到部署外 部的kube-apiserver实例。

因此,如果我们想要监控kube-apiserver相关的指标,只需要通过endpoints资源找到kubernetes对应的所有后 端地址即可。

如下所示,创建监控任务kubernetes-apiservers,这里指定了服务发现模式为endpoints。Promtheus会查找 当前集群中所有的endpoints配置,并通过relabel进行判断是否为apiserver对应的访问地址:

    - job_name: 'kubernetes-apiservers'
      kubernetes_sd_configs:
      - role: endpoints
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
      - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name,__meta_kubernetes_endpoint_port_name]
        action: keep
        regex: default;kubernetes;https
      - target_label: __address__
        replacement: kubernetes.default.svc:443 

在relabel_configs配置中第一步用于判断当前endpoints是否为kube-apiserver对用的地址。第二步,替换监 控采集地址到kubernetes.default.svc:443即可。重新加载配置文件,重建Promthues实例,得到以下结果。

对Ingress和Service进行网络探测

为了能够对Ingress和Service进行探测,我们需要在集群部署Blackbox Exporter实例。 如下所示,创建 blackbox-exporter.yaml用于描述部署相关的内容:

apiVersion: v1
kind: Service
metadata:
  labels:
    app: blackbox-exporter
  name: blackbox-exporter
spec:
  ports:
  - name: blackbox
    port: 9115
    protocol: TCP
  selector:
    app: blackbox-exporter
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: blackbox-exporter
  name: blackbox-exporter
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

通过kubectl命令部署Blackbox Exporter实例,这里将部署一个Blackbox Exporter的Pod实例,同时通过服 务blackbox-exporter在集群内暴露访问地址blackbox-exporter.default.svc.cluster.local,对于集 群内的任意服务都可以通过该内部DNS域名访问Blackbox Exporter实例:

[root@k8s-01 ~]#  kubectl get pods
NAME                               READY   STATUS    RESTARTS   AGE
blackbox-exporter-5574646b-4wjg5   1/1     Running   0          46m
prometheus-7f57d48b8d-n4sns        1/1     Running   0          26m
[root@k8s-01 ~]# kubectl get svc
NAME                TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)          AGE
blackbox-exporter   ClusterIP   10.1.70.11   <none>        9115/TCP         46m
kubernetes          ClusterIP   10.1.0.1     <none>        443/TCP          29d
prometheus          NodePort    10.1.67.80   <none>        9090:30880/TCP   5h30m

为了能够让Prometheus能够自动的对Service进行探测,我们需要通过服务发现自动找到所有的Service信息。 如下所示,在Prometheus的配置文件中添加名为kubernetes-services的监控采集任务:

    - job_name: 'kubernetes-services'
      metrics_path: /probe
      params:
        module: [http_2xx]
      kubernetes_sd_configs:
      - role: service
      relabel_configs:
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_probe]
        action: keep
        regex: true
      - source_labels: [__address__]
        target_label: __param_target
      - target_label: __address__
        replacement: blackbox-exporter.default.svc.cluster.local:9115
      - source_labels: [__param_target]
        target_label: instance
      - action: labelmap
        regex: __meta_kubernetes_service_label_(.+)
      - source_labels: [__meta_kubernetes_namespace]
        target_label: kubernetes_namespace
      - source_labels: [__meta_kubernetes_service_name]
        target_label: kubernetes_name   

在该任务配置中,通过指定kubernetes_sd_config的role为service指定服务发现模式:

 kubernetes_sd_configs:
   - role: service

为了区分集群中需要进行探测的Service实例,我们通过标签‘prometheus.io/probe: true’进行判断,从而过 滤出需要探测的所有Service实例:

 - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_probe]
   action: keep
   regex: true

并且将通过服务发现获取到的Service实例地址 __address__ 转换为获取监控数据的请求参数。同时 将 __address 执行Blackbox Exporter实例的访问地址,并且重写了标签instance的内容:

 - source_labels: [__address__]
   target_label: __param_target
 - target_label: __address__
   replacement: blackbox-exporter.default.svc.cluster.local:9115
 - source_labels: [__param_target]
   target_label: instance

最后,为监控样本添加了额外的标签信息:

 - action: labelmap
   regex: __meta_kubernetes_service_label_(.+)
 - source_labels: [__meta_kubernetes_namespace]
   target_label: kubernetes_namespace
 - source_labels: [__meta_kubernetes_service_name]
   target_label: kubernetes_name

对于Ingress而言,也是一个相对类似的过程,这里给出对Ingress探测的Promthues任务配置作为参考:

    - job_name: 'kubernetes-ingresses'
      metrics_path: /probe
      params:
        module: [http_2xx]
      kubernetes_sd_configs:
      - role: ingress
      relabel_configs:
      - source_labels: [__meta_kubernetes_ingress_annotation_prometheus_io_probe]
        action: keep
        regex: true
      - source_labels: [__meta_kubernetes_ingress_scheme,__address__,__meta_kubernetes_ingress_path]
        regex: (.+);(.+);(.+)
        replacement: ${1}://${2}${3}
        target_label: __param_target
      - target_label: __address__
        replacement: blackbox-exporter.default.svc.cluster.local:9115
      - source_labels: [__param_target]
        target_label: instance
      - action: labelmap
        regex: __meta_kubernetes_ingress_label_(.+)
      - source_labels: [__meta_kubernetes_namespace]
        target_label: kubernetes_namespace
      - source_labels: [__meta_kubernetes_ingress_name]
        target_label: kubernetes_name
原文地址:https://www.cnblogs.com/jiangwenhui/p/11978224.html