Prometheus基于k8s的动态服务发现实战

当初做了一个支持springboot的插拔式微服务监控组件,各个微服务只需要加入依赖,就能暴露prometheus可以识别的接口。但是公司的微服务数量太多,在prometheus中一个个配置数据收集job也不太现实,而且现在的微服务都部署在k8s容器中,每重新发布一次,你的节点信息都会发生变化。这时候,我们会想到,k8s中是有提供apiserver这个组件的,所有的微服务信息理应都可以从k8s的serviceapi拿到,prometheus既然具备这么丰富的生态,应该就会对k8s的服务发现有着良好的支持,所以我们今天就来实战一下k8s的动态服务发现。

一.基本用法

Promethues通过K8s的apiservice目前可以支持5种服务发现模式,分别是:Node、Service、Pod、Endpoints、Ingress。我们可以通过对配置文件prometheus.yml添加以下内容实现k8s中信息的获取。

  - job_name: 'kubernetes-pods'
    kubernetes_sd_configs: //相当于数据源类型,更多数据源请参考官网
    - role: pod //获取的资源名
      api_server: 'https://10.110.73.213:6443' //k8s的apiservice接口
      tls_config:
        insecure_skip_verify: true //如果部署在k8s集群中,可以不用配置认证,自动抓取所在k8s集群的信息

二.标签管理

在连接k8s之后,有些指标会自动生成一些标签,有时候我们可能会需要重命名这些标签,可能会丢弃一部分无用的标签,还可能会通过这些标签过滤出我们需要监控的资源,因此在job_name子属性中,还有一个叫做relabel_configs的配置,这个配置可以使我们通过一些正则表达式,来满足我们对标签的各种自定义。

relabel_configs的常用配置:

#原标签(需要被替换的标签),以","进行分隔
[ source_labels: '['  [, ...] ']' ]

# 连接多个资源标签的分隔符
[ separator:  | default = ; ]

# 将替换结果写入到的目标标签
[ target_label:  ]

# 对原标签进行分割的正则表达式
[ regex:  | default = (.*) ]

# 按照正则分隔后的结果进行替换的模板,会根据这个模板生成替换结果
[ replacement:  | default = $1 ]

# 基于正则表达式匹配执行的操作。
#replace:通过正则对原标签分组之后,类似(${1},${2},...),用replacement的值对其替换,正则匹配不到的不替换。
#keep:只保留regex与目标source_labels匹配的指标。
#drop:删除regex与目标source_labels匹配的指标。
#hashmod:设置target_label为的modulus哈希值的source_labels。
#labelmap:regex与所有原标签做匹配,并且将捕获到的内容作为为新的标签名称,通过replacement替换值。
#labeldrop:regex与所有原标签做匹配。任何匹配的标签将从标签集中删除。
#labelkeep:regex与所有原标签做匹配。只保留匹配的标签集。
[ action:  | default = replace ]

我们以POD资源为例,看下有哪些自动生成source_labels(更多资源请参考官网:https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kubernetes_sd_config
):

  • __meta_kubernetes_namespace:pod对象的名称空间。
  • __meta_kubernetes_pod_name:pod对象的名称。
  • __meta_kubernetes_pod_ip:pod对象的pod IP。
  • __meta_kubernetes_pod_label_:来自pod对象的每个标签。
  • __meta_kubernetes_pod_labelpresent_true用于pod对象中的每个标签。
  • __meta_kubernetes_pod_annotation_:来自pod对象的每个注释。
  • __meta_kubernetes_pod_annotationpresent_:包含某个注解则为true。
  • __meta_kubernetes_pod_container_init:如果容器是[InitContainer]则为true。
  • __meta_kubernetes_pod_container_name:容器的名称。
  • __meta_kubernetes_pod_container_port_name:容器端口的名称。
  • __meta_kubernetes_pod_container_port_number:容器端口号。
  • __meta_kubernetes_pod_container_port_protocol:容器端口的协议。
  • __meta_kubernetes_pod_ready:pod的就绪状态。
  • __meta_kubernetes_pod_phase:pod的声明周期,(PendingRunningSucceededFailedUnknown
  • __meta_kubernetes_pod_node_name:将Pod所在的节点的名称。
  • __meta_kubernetes_pod_host_ip:pod对象的当前主机IP。
  • __meta_kubernetes_pod_uid:pod对象的UID。
  • __meta_kubernetes_pod_controller_kind:pod控制器的对象种类。
  • __meta_kubernetes_pod_controller_name:pod控制器的名称。

三.实战

Prometheus的k8s完整配置:

- job_name: 'kubernetes-pods'
    kubernetes_sd_configs:
    - role: pod
      api_server: http://172.16.xx.xx:xxxx
      tls_config:
        insecure_skip_verify: true
    relabel_configs:
    - source_labels: [__meta_kubernetes_namespace]#只对命名空间为order的pod资源进行监控
      regex: order
      action: keep
    - source_labels: [__metrics_path__]#替换指示获取的路径
      action: replace
      replacement: /hellgate/prometheus#这个是每个微服务暴露出数据收集的URI
      target_label: __metrics_path__
      regex: (.+)
    - source_labels: [__address__,__meta_kubernetes_pod_annotation_prometheus_io_port]#替换ip和端口
      action: replace
      regex: (.*);(.*)
      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

之后,在prometheus的target看板中会出现我们的监控资源:


image.png

Nice!自己的自定义监控终于出来了:


image.png

你可能感兴趣的:(Prometheus基于k8s的动态服务发现实战)