当初做了一个支持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: '[' <labelname> [, ...] ']' ]
# 连接多个资源标签的分隔符
[ separator: <string> | default = ; ]
# 将替换结果写入到的目标标签
[ target_label: <labelname> ]
# 对原标签进行分割的正则表达式
[ regex: <regex> | default = (.*) ]
# 按照正则分隔后的结果进行替换的模板,会根据这个模板生成替换结果
[ replacement: <string> | 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: <relabel_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_<labelname>
:来自pod对象的每个标签。 -
__meta_kubernetes_pod_labelpresent_<labelname>
:true
用于pod对象中的每个标签。 -
__meta_kubernetes_pod_annotation_<annotationname>
:来自pod对象的每个注释。 -
__meta_kubernetes_pod_annotationpresent_<annotationname>
:包含某个注解则为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的声明周期,(Pending
,Running
,Succeeded
,Failed
,Unknown
) -
__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看板中会出现我们的监控资源:
Nice!自己的自定义监控终于出来了: