为什么说Prometheus是为云原生监控而生的?

 

 

  •  

想必你不止一次的地听说了prometheus是为云原生监控而生的,那你有没有想过这句话意味着什么呢?

我们知道在云原生中使用容器和k8s环境作为基础运行环境一体化架构被拆分成众多分散的微服务,而微服务的变更和扩缩容是特别频繁的,也就导致采集的目标信息变化频繁。这就给时序监控系统提出了两个要求:

    • 1.需要采集运行在跨多个宿主机上的海量pod容器

    • 2.同时要及时感知到他们的变化

    • 3.同时要构建完整的k8s监控生态

其实说白了就是在云原生环境中监控变得更难了,更复杂了。所以需要一个在设计之初就适合云原生监控场景的系统,而prometheus就是这么设计的。

 

Prometheus到底做了哪些改进,能配得上k8s ?

 

k8s中应该关注哪些指标?在下面的表格中简单列举了下我们在k8s需要关注的四大块指标:

适配1

适配1.  sdk+指标自暴露+pull模型:构建k8s监控的整个生态

 

  • 在上面的列举的表格中我们看到在k8s需要关注的四大块指标

  • 其实我们可以简单地把k8s的使用者分为两种角色:k8s集群管理员和普通用户。每种角色关注的指标不相同

自己采集岂不累死了?

  • 既然需求这么多,如果只是由监控系统自己采集,第一很累,第二构建不出这么完整的生态

奥妙

  • prometheus是pull模型采集的,各个被监控的源只需要将自身指标暴露在本地http端口中,prometheus就可以访问接口来采集指标

  • prometheus在k8s中也是这样的,组件需要暴露自身指标,如我们在容器基础资源指标中提到的kubelet 内置cadvisor指标就是暴露在10250端口下的/metrics/cadvisor下。

  • prometheus通过 k8s服务发现这些指标源完成采集

 

适配2

适配2. k8s服务发现

举例

  • 一、endpoint级别的服务发现 :举例 在采集apiserver、kube-controller-manager等

  •  

  •  

 

 

 

 

  •  
  • 二、node级别的服务发现 :举例 在采集cadvisor和kubelet自身指标时

  • 三、node级别的服务发现 :举例 在采集pod自打点指标时

解读:watch即时更新

  • 通过watch即时发现资源变化,就满足了我们一开始提出的云原生情况下监控的挑战之一,要及时感知到采集源的变化。

  • 同时在k8s大二层环境中,prometheus可以访问到发现出来的的 endpoint 、node、pod

适配3

适配3. 采集鉴权:token & 证书

k8s中很多接口都要鉴权,甚至还需要tls双向认证

  • 同时我们知道在k8s中很多接口都是带有访问鉴权的,比如我们直接访问k8s node上的kubelet的/metrics/cadvisor接口会返回未授权。

  • prometheus在采集cadvisor指标时同样面临鉴权问题

解决方法

  • 聪明的prometheus开发人员通过在采集中支持配置中相关token和证书来解决这个问题,如下面的配置代表有一个token文件,同时还有一个证书文件。

  • 我们在使用k8s时知道,k8s通过 service account,clusterrolebinding来解决token、证书挂载问题

  • 我们在创建相关prometheus 的statsfulset时需要在prometheus yaml中需要配置对应的serviceAccountNameserviceAccountName: prometheus

  • 配置好之后Kubernetes会将对应的token和证书文件挂载到pod中。

  • 我们exec进入prometheus的pod中就可以查看到相关文件在/var/run/secrets/kubernetes.io/serviceaccount/,如下图所示:

适配4

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

prometheus relabel说明

  • 文档地址 https://prometheus.io/docs/pr...

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

  • 在采集cadvisor时可以看到服务发现源给添加了很多__meta_kubernetes_node_label_开头的标签

  • 但是这些标签名字太长了,需要精简。我们使用如下的relabel配置

  • 以这个标签为例,__meta_kubernetes_node_label_kubernetes_io_os="linux",上面的配置代表匹配_meta_kubernetes_node_label_开头的key,只保留后面的部分,所以在最终的标签看到的就是beta_kubernetes_io_os="linux"

  • labelmap代表匹配到的标签赋值给目标标签

应用2:replace 在采集pod自定义指标 对标签进行赋值

  • 我们在使用pod自定义指标时在pod yaml 的spec.template.metadata.annotations中需要定义三个以prometheus.io开头的配置,分布代表是否需要prometheus采集、metrics暴露的端口、metrics的http path信息,详细配置如下:

 

应用2:keep 做过滤,在采集服务组件endpoint时

  • endpoint资源是暴露一个服务的ip地址和port的列表

  • 代表采用k8s服务发现 endpoint,endpoint会非常多,所以需要过滤apiserver的

  • 过滤手段为 标签 __meta_kubernetes_namespace匹配default并且 __meta_kubernetes_service_name 匹配kubernetes 并且 __meta_kubernetes_endpoint_port_name 匹配https,咋样呢 : keep

k8s 会在default namespace中创建apiserver的 service

  • 最后获取到的endpoint转换为采集路径为: https://masterip:6443/metrics

Prometheus为k8s监控做的适配工作: