23.1 k8s监控中标签relabel的应用和原理

本节重点介绍 :

  • relabel的源码在 7.7节做过详细的解读
  • 强大的relabel能力 在k8s中的应用
    • 应用1: labelmap 在采集cadvisor指标时 对服务发现标签key名字截取
    • 应用2: 采集pod自定义指标中replace 和 keep的应用
    • 应用3: k8s服务组件采集时的endpoint过滤
    • 应用4: hashmod 解决k8s大集群采集问题
    • 应用5: drop 去掉不想要采集的指标

强大的relabel能力 做标签截取、变换、静态分片

prometheus relabel说明

action_name 含义
replace 将 source_labels 中正则匹配的结果赋值到 target_label中
keep 保留source_labels 中正则 匹配的目标
drop 去掉source_labels 中正则 匹配的目标
hashmod 将source_labels 中正则 匹配的目标 做分片
labelmap 将正则匹配到的所有标签名称做替换
labeldrop 去掉正则匹配到的标签
labelkeep 保留正则匹配到的标签

在采集k8s中relabel的应用

应用1: labelmap 在采集cadvisor指标时 对服务发现标签key名字截取

  • 在采集cadvisor时可以看到服务发现源给添加了很多__meta_kubernetes_node_label_开头的标签
  • /service-discovery页面查看 kubernetes-nodes-cadvisor的结果
  • 但是这些标签名字太长了,需要精简。我们使用如下的relabel配置
yaml 复制代码
relabel_configs:
- separator: ;
  regex: __meta_kubernetes_node_label_(.+)
  replacement: $1
  action: labelmap
  • 以这个标签为例,__meta_kubernetes_node_label_kubernetes_io_os="linux"
  • 上面的配置代表匹配_meta_kubernetes_node_label_开头的key,只保留后面的部分
  • 所以在最终的标签看到的就是kubernetes_io_os="linux"
  • labelmap代表匹配到的标签赋值给目标标签
  • 源码位置 D:\go_path\src\github.com\prometheus\prometheus\pkg\relabel\relabel.go
go 复制代码
func relabel(lset labels.Labels, cfg *Config) labels.Labels {
	case LabelMap:
		for _, l := range lset {
			if cfg.Regex.MatchString(l.Name) {
				res := cfg.Regex.ReplaceAllString(l.Name, cfg.Replacement)
				lb.Set(res, l.Value)
			}
		}
}

应用2: 采集pod自定义指标中replace 和 keep的应用

  • 我们在使用pod自定义指标时在pod yaml 的spec.template.metadata.annotations中需要定义三个以prometheus.io开头的配置
  • 分别代表是否需要prometheus采集、metrics暴露的端口、metrics的http path信息
  • 我们之前写的go代码 ink8s_pod_metrics项目中的deployment配置如下
yaml 复制代码
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ink8s-pod-metrics
  template:
    metadata:
      labels:
        app: ink8s-pod-metrics
      annotations:
        prometheus.io/scrape: 'true'
        prometheus.io/port: '8080'
        prometheus.io/path: 'metrics'
  • 在采集pod自定义指标时采用如下(job=kubernetes-pods)
yaml 复制代码
  relabel_configs:
  - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
    separator: ;
    regex: "true"
    replacement: $1
    action: keep
  - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
    separator: ;
    regex: (.+)
    target_label: __metrics_path__
    replacement: $1
    action: replace
  - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
    separator: ;
    regex: ([^:]+)(?::\d+)?;(\d+)
    target_label: __address__
    replacement: $1:$2
    action: replace
其中keep的应用
  • 配置如下
yaml 复制代码
  - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
    separator: ;
    regex: "true"
    replacement: $1
    action: keep
  • 含义是保留 __meta_kubernetes_pod_annotation_prometheus_io_scrape这个标签为true的pod
  • 也就是pod的yaml中 spec.template.metadata.annotations 配置prometheus.io/scrape: 'true'的才需要采集
  • 其余的pod不采集
其中replace的应用
  • 设置__metrics_path__标签
yaml 复制代码
  - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
    separator: ;
    regex: (.+)
    target_label: __metrics_path__
    replacement: $1
    action: replace
  • 意思是将__meta_kubernetes_pod_annotation_prometheus_io_path赋值给__metrics_path__
  • 设置__address__标签
yaml 复制代码
  - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
    separator: ;
    regex: ([^:]+)(?::\d+)?;(\d+)
    target_label: __address__
    replacement: $1:$2
    action: replace
  • 意思是将相关__meta_kubernetes_pod_annotation_prometheus_io_port作为端口赋值给__address__
  • 也就是是告诉prometheus 这个pod的采集地址为 ${pod_ip}:${pod_port}/${path}

应用3: k8s服务组件采集时的endpoint过滤

  • endpoint资源是暴露一个服务的ip地址和port的列表
  • 代表采用k8s服务发现 endpoint,endpoint会非常多,所以需要过滤apiserver的
yaml 复制代码
kubernetes_sd_configs:
- role: endpoints
  • 相应的relabel配置为
yaml 复制代码
relabel_configs:
-   source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
    separator: ;
    regex: default;kubernetes;https
    replacement: $1
    action: keep
解读一下
  • 过滤手段为

    • 标签 __meta_kubernetes_namespace=default
    • 并且 __meta_kubernetes_service_name=kubernetes
    • 并且 __meta_kubernetes_endpoint_port_name 匹配https,
  • 最后的动作为keep,也就是只采集满足上面三个标签组的endpoint

  • k8s 会在default namespace中创建apiserver的 service

shell 复制代码
$ kubectl get svc -A |grep  443
default         kubernetes                                     ClusterIP   10.96.0.1       <none>        443/TCP                  9d
  • 最后获取到的endpoint转换为采集路径为:https://masterip:6443/metrics

应用4 :hashmod 解决k8s大集群采集问题

场景说明
  • 有的k8s集群数据量太大了,一个prometheus采集会导致内存消耗过多,采集效率下降
  • 此时需要启动多个prometheus,使用hashmod做静态分片
  • hashmod需要和keep或drop做配合
配置说明
  • 第1个prometheus配置
yaml 复制代码
relabel_configs:
  - source_labels: [__address__]
    regex: (.*)
    modulus: 2
    target_label: __tmp_hash
    replacement: $1
    action: hashmod
  - source_labels: [__tmp_hash]
    regex: ^0$
    replacement: $1
    action: keep
  • 第2个prometheus配置
yaml 复制代码
relabel_configs:
  - source_labels: [__address__]
    regex: (.*)
    modulus: 2
    target_label: __tmp_hash
    replacement: $1
    action: hashmod
  - source_labels: [__tmp_hash]
    regex: ^1$
    replacement: $1
    action: keep
  • 解读一下,两个prometheus的 modulus=2代表一共两个分片
  • 其中第1个 regex: ^0 第二个 regex: \^1 ,然后通过action: keep做保留
  • 意思是target的__address__做hash之后对2取模
  • =0由第1个prometheus采集,=1由第2个prometheus采集
源码解读
go 复制代码
	case HashMod:
		mod := sum64(md5.Sum([]byte(val))) % cfg.Modulus
		lb.Set(cfg.TargetLabel, fmt.Sprintf("%d", mod))

应用5 :drop 去掉不想要采集的指标

场景说明
  • 有些指标数据量很大,可以达到百万的量级,这种指标对监控系统是很大的压力
  • 有些指标我们不关心
  • 所以我们就可以使用drop将这些指标去掉
  • 配置样例,如下面的例子:drop掉以kubelet_|apiserver_|storage_开头的指标
yaml 复制代码
- source_labels: [__name__]
    separator: ;
    # 标签key前缀匹配到的drop
    regex: '(kubelet_|apiserver_|container_fs_).*'
    replacement: $1
    action: drop

本节重点总结 :

  • relabel的源码在 7.7节做过详细的解读
  • 强大的relabel能力 在k8s中的应用
    • 应用1: labelmap 在采集cadvisor指标时 对服务发现标签key名字截取
    • 应用2: 采集pod自定义指标中replace 和 keep的应用
    • 应用3: k8s服务组件采集时的endpoint过滤
    • 应用4: hashmod 解决k8s大集群采集问题
    • 应用5: drop 去掉不想要采集的指标
相关推荐
xcl092541 分钟前
北京24小时自助健身房系统软件开发实战:从架构到部署全流程指南
java·spring boot·架构
一 乐2 小时前
动漫书销售商城|基于springboot + vue动漫书销售商城(源码+数据库+文档)
java·数据库·vue.js·spring boot·毕业设计
卓怡学长3 小时前
w214基于jsp知道特产网
java·intellij-idea
步行cgn3 小时前
Spring 注解使用详解
java·spring
一条小小yu3 小时前
Spring IoC的理解
java·后端·spring
落魄实习生3 小时前
Agent Scope Java 2.x 系列【7】工具使用
java·开发语言·ai
旺仔学长 哈哈4 小时前
springboot钓鱼爱好者交流平台APP设计与实现
java·spring boot·mysql·充电桩管理系统
bloglin999994 小时前
vmware部署centos7启动docker容器后无法访问服务
运维·docker·容器
自强的小白5 小时前
核心功能(Service接口)
java·mybatis