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

DevOps技术栈

共 6247字,需浏览 13分钟

 ·

2021-06-24 23:04

原文链接:https://segmentfault.com/a/1190000040150566

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


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

  • 我们知道在云原生中使用容器和k8s环境作为基础运行环境

  • 一体化架构被拆分成众多分散的微服务,而微服务的变更和扩缩容是特别频繁的,也就导致采集的目标信息变化频繁。这就给时序监控系统提出了两个要求:

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

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

    • 同时要构建完整的k8s监控生态,能有

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

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


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

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

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

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

自己采集岂不累死了?

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

奥妙

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

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

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

适配2. k8s服务发现

举例

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

kubernetes_sd_configs:
role: endpoints


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

  kubernetes_sd_configs:
- role: node

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

  kubernetes_sd_configs:
- role: pod
follow_redirects: true

解读:watch即时更新

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

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

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

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

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

[root@Kubernetes-node01 logs]# curl -k https://localhost:10250/metrics/cadvisor
Unauthorized
  • prometheus在采集cadvisor指标时同样面临鉴权问题

解决方法

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

bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecure_skip_verify: true
  • 我们在使用k8s时知道,k8s通过 service account,clusterrolebinding来解决token、证书挂载问题

  • prometheus也是利用了这一点,在创建prometheus容器是相关的service account,clusterrolebinding配置的示例如下:

apiVersion: rbac.authorization.k8s.io/v1 # api的version
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: kube-system # 命名空间
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: prometheus
roleRef: # 选择需要绑定的Role
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects: # 对象
- kind: ServiceAccount
name: prometheus
namespace: kube-system
  • 我们在创建相关prometheus 的statsfulset时需要在prometheus yaml中需要配置对应的serviceAccountNameserviceAccountName: prometheus

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

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

/ # ls /var/run/secrets/kubernetes.io/serviceaccount/ -l
total 0
lrwxrwxrwx 1 root root 13 Jan 7 20:54 ca.crt -> ..data/ca.crt
lrwxrwxrwx 1 root root 16 Jan 7 20:54 namespace -> ..data/namespace
lrwxrwxrwx 1 root root 12 Jan 7 20:54 token -> ..data/token
/ # df -h |grep service
tmpfs 7.8G 12.0K 7.8G 0% /var/run/secrets/kubernetes.io/serviceaccount
/
  • 在采集etcd时需要配置相关证书的secret

    kubectl create secret generic etcd-certs --from-file=/etc/kubernetes/pki/etcd/healthcheck-client.crt --from-file=/etc/kubernetes/pki/etcd/healthcheck-client.key --from-file=/etc/kubernetes/pki/etcd/ca.crt -n kube-system

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

prometheus relabel说明

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

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

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

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

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,只保留后面的部分,所以在最终的标签看到的就是beta_kubernetes_io_os="linux"

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

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

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

    spec:
    selector:
    matchLabels:
    name: fluentd-elasticsearch
    template:
    metadata:
    labels:
    name: fluentd-elasticsearch
    annotations:
    prometheus.io/scrape: 'true'
    prometheus.io/port: '9102'
    prometheus.io/path: 'metrics'
  • 在采集pod自定义指标时采用如下

    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
  • 意思是将__meta_kubernetes_pod_annotation_prometheus_io_path赋值给 __metrics_path__

  • 意思是将相关 __meta_kubernetes_pod_annotation_prometheus_io_port赋值给 __address__后面的端口

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

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

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

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

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
  • k8s 会在default namespace中创建apiserver的 service

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


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



长按扫描

系统学习Prometheus监控系统

- END -

 推荐阅读 

K8s运维架构师实战集训营【多个企业项目】 
Prometheus+Granafa构建高大上的MySQL监控平台
12年资深运维老司机的成长感悟
快速入门 Ansible 自动化运维工具 | 16张图
运维的工作边界,这次真的搞明白了!
最强整理!常用正则表达式速查手册
60道常见的 Kubernetes 面试题总结
不管你是开发还是运维,微服务这些你得知道!
从零开始搭建创业公司DevOps技术栈
2021年的DevOps趋势预测
搭建一套完整的企业级 K8s 集群(v1.20,kubeadm方式)




点亮,服务器三年不宕机

浏览 47
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报