关于k8s:为什么说prometheus是为云原生监控而生的prometheus为k8s监控做的四大适配工作

前言

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

  • 想必你不止一次的地据说了prometheus是为云原生监控而生的,那你有没有想过这句话意味着什么呢?
  • 咱们晓得在云原生中应用容器和k8s环境作为根底运行环境
  • 一体化架构被拆分成泛滥扩散的微服务,而微服务的变更和扩缩容是特地频繁的,也就导致采集的指标信息变动频繁。这就给时序监控零碎提出了两个要求:

    • 须要采集运行在跨多个宿主机上的海量pod容器
    • 同时要及时感知到他们的变动
    • 同时要构建残缺的k8s监控生态,能有
  • 其实说白了就是在云原生环境中监控变得更难了,更简单了。所以须要一个在设计之初就适宜云原生监控场景的零碎,而prometheus就是这么设计的。

prometheus到底做了哪些改良,能配得上k8 ?

k8s中应该关注哪些指标

我在上面的表格中简略列举了下咱们在k8s须要关注的四大块指标:

指标类型 采集源 利用举例 发现类型 grafana截图
容器根底资源指标 kubelet 内置cadvisor metrics接口 查看容器cpu、mem利用率等 k8s_sd node级别间接拜访node_ip
k8s资源指标 kube-stats-metrics (简称ksm) 具体能够看从容器监控kube-stats-metrics看k8s泛滥组件
看pod状态如pod waiting状态的起因
数个数如:查看node pod按namespace散布状况
通过coredns拜访域名
k8s服务组件指标 服务组件 metrics接口 查看apiserver 、scheduler、etc、coredns申请提早等 k8s_sd endpoint级别
部署在pod中业务埋点指标 pod 的metrics接口 根据业务指标场景 k8s_sd pod级别,拜访pod ip的metricspath

适配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监控做的适配工作

适配名字 阐明 举例
各个组件metrics自裸露 所有组件将本身指标裸露在各自的服务端口上,prometheus通过pull过去拉取指标 apiserver:6443/metrics
k8s服务发现 通过watch即时发现资源变动 kubernetes_sd_configs:- role: node
鉴权 k8s的组件接口都是要鉴权的,所以k8s的采集器要反对配置鉴权 反对配置token和tls证书
标签relabel能力 过滤服务发现标的 labelmap去掉服务发现标签的长前缀
replace做替换
hashmod做动态分片

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理