Prometheus监控基础

举报
可以交个朋友 发表于 2023/12/12 15:28:11 2023/12/12
【摘要】 Prometheus 入门使用指导

一、 背景

与Kubernetes项目一样,Prometheus项目也源自于谷歌的Borg体系,原型系统叫作BorgMon;随着Kubernetes在社区越来越活跃,以及各个厂商使用kubernetes,容器的监控体系已经完全演变成以Prometheus项目为核心的一套统一的方案;
与传统zabbix、nagios相比,Prometheus可以自动发现K8S中的各类资源并配置对应的标签、查询速度更快的时序型数据库、监控系统自身的集群部署方案等。
Prometheus已经成为云原生领域监控的事实标准,所以本文会着重介绍Prometheus的安装使用以及告警配置。


二、监控

2.1 Prometheus介绍

Prometheus是一个拥有数据指标采集、数据查询、数据存储的工具;配合grafana进行图形化展示,配合AlertManager进行告警,组成一套完整的监控系统 Prometheus的特点:

  • 多维的数据模型(基于时间序列的Key、Value键值对标签)
  • 灵活的查询和聚合语言PromQL
  • 提供本地存储和分布式存储
  • 通过基于HTTP的Pull模型采集时间序列数据
  • 可利用Pushgateway(Prometheus的可选中间件)实现Push模式
  • 可通过动态服务发现或静态配置发现目标机器

架构如下:
image.png
从以上架构图中可知,Prometheus由以下组件构成:

  • Prometheus Server:Prometheus Server是Prometheus组件中的核心部分,负责实现对监控数据的获取,存储以及查询。Prometheus Server可以从其他的Prometheus Server实例中获取数据。
  • Exporter:Exporter将监控数据采集的端点通过HTTP服务的形式暴露给Prometheus Server,Prometheus Server通过访问该Exporter提供的restful api接口中获取实时数据
  • AlertManager:在Prometheus Server中支持基于PromQL创建告警规则,如果满足PromQL定义的规则,则会产生一条告警,而告警的后续处理流程则由AlertManager进行管理,告警方式支持email、短信、钉钉、微信等。
  • PushGateway:Prometheus默认采用pull的方式主动从exporter中拉去数据,但如果exporter对象是一个job类型的目标,就需要在job执行完成后主动将自己的数据推送到PushGateway中,PushGateway再将数据通过http服务暴露出来,Prometheus再去pull

指标数据类型:
Prometheus采集到的指标数据可分为以下4个类型:

  • Counter:一种累加的数据,典型的应用如:http请求的次数,结束的任务数, 出现的错误数等等
  • Gauge:瞬时数据,典型的应用如:CPU、内存使用率等
  • Histogram:统计指定区间内数据,类似柱状图,比如成绩分布;不及格人数多少,60-80分的人数多少,80分以上的人有多少。
  • Summary:和Histogram一样也是统计区间值,但Summary是统计百分比,比如分数小于60的占全班人数的百分之几。

在Exporter返回的样本数据中,其注释中也包含了该样本的类型。例如:
image.png


数据格式
样本数据格式由三个部分构成:

  • 指标(metric):metric name和描述当前样本特征的labels;
  • 时间戳(timestamp):一个精确到毫秒的时间戳(从1970开始计算,不写默认为当前时间);
  • 样本值(value): 一个float64的浮点型数据表示当前样本的值。

这里的label和K8S中的label相似,后续通过PromQl查询指标数据的时候可以通过label排除指定的数据,比如:
image.png
只查询code为200的数据
image.png
在实际应用中,如果我们想统计所有pod的request配额总和,但是要排除kube-system命名空间下的pod,就可以通过namespace这个标签来完成.


发现方式
Prometheus拉取数据的方式是调用被监控目标的http restful接口,Prometheus会为每个监控目标设置三个隐藏标签 __scheme__:可选值为http/https,默认为http __address__:被监控目标的ip与端口,格式为ip:port __metrics_path__:被监控目标指标暴露的url路径,默认为/metrics Prometheus拉取指标数据时,将这三个字段组合成一个完整的api接口路径http://ip:port/metrics

  • 静态发现: 直接在prometheus.yml文件中添加target的ip:port,并配置_metrics_path;每新增一个监控目标就要修改一次yml文件
    # my global config
    global:  
      scrape_interval:     15s 
      evaluation_interval: 15s 
    scrape_configs:
      - job_name: 'node'
        static_configs: 
        - targets: ['localhost:9090','192.168.0.187:9100']   #每新增一个监控目标就需要添加对应的ip:port,这里配置的其实就是__address__标签的值 
    
    
  • 动态发现:通过服务发现(service discovery)模块实现,sd模块专门负责去发现需要监控的target信息,Prometheus去从sd模块订阅该信息,有target信息时会推送给Prometheus,然后Prometheus拿到target信息后通过pull http地址拉取监控指标数据(常见sd有kubernetes、dns等);kubernetes_sd是针对kubernetes的服务发现,它会监控kube-apiserver,如果有新node节点加入集群,kubernetes_sd就可以拿到新节点的信息并推送给Prometheus,配置样例如下
    global: 
      scrape_interval:     15s 
      evaluation_interval: 15s 
    scrape_configs: 
      - job_name: 'prometheus' 
          static_configs:                            #静态配置方式 
          - targets: ['localhost:9090']              #默认监控自己 
    
      - job_name: kubernetes-nodes 
        kubernetes_sd_configs:                     #使用kubernetes_sd作为服务发现 
        - role: node                               #监控node资源,其他可选值为service,pod,endpoint 
          api_server: https://192.168.0.182:5443   #被监控集群的kube-apiserver的地址 
          bearer_token: $token                      #访问集群需要的token认证信息,token可以通过describe指定的secret获取 
          tls_config:                   
            insecure_skip_verify: true             #跳过客户端对服务端的认证
        relabel_configs:                           #对标签进行操作
        - regex: (.+)                              #用正则表达式匹配__meta_kubernetes_node_name标签的值,华为云nodename为ip形式,此处匹配ip
          replacement: $1:9100                     #$1表示匹配结果,匹配结果只有ip,所以需要加上端口,并将$1:9100赋给__address__标签,其中9100是nodeexport服务端口,nodeexport为daemonset部署在每个节点上的监控组件,通过节点ip:9100暴露服务,9100可配置。 
          source_labels: 
          - __meta_kubernetes_node_name 
          target_label: __address__         #将__address__ label值修改为节点ip:9100。__scheme__值默认为http,__metrics_path__值默认为/metrics http://ip:9100/metrics 
        - target_label: __metrics_path__    #示例 
          replacement: /metrics/cadvisor    #示例 本结构效果为:__metrics_path__值修改为/metrics/cadvisor。 http://ip:9100/metrics/cadvisor 
        - target_label: node                #新增一个标签node,并将instance标签的值赋给node 
          source_labels: [instance]
    

2.2 kubernetes集群监控实验

实验案例是在kubernetes集群外部安装Prometheus,获取集群内部指标。


  • 安装Prometheus
    tar zxvf prometheus-2.23.0.linux-amd64.tar.gz 
    cd prometheus-2.23.0.linux-amd64 
    nohup ./prometheus --storage.tsdb.retention=90d  --storage.tsdb.path=./data/ --web.enable-lifecycle> prometheus.log 2>&1 &
    

  • 在目标集群配置Prometheus的权限和安装指标监控插件
    1. 创建ServiceAccount
      apiVersion: v1 
      kind: ServiceAccount 
      metadata: 
        labels: 
          app: prometheus 
          component: server 
        name: prometheus 
        namespace: monitoring
      
    2. 创建clusterrolebinding
      apiVersion: rbac.authorization.k8s.io/v1 
      kind: ClusterRoleBinding 
      metadata: 
        labels: 
          app: prometheus 
          component: server 
        name: prometheus 
      roleRef: 
        apiGroup: rbac.authorization.k8s.io 
        kind: ClusterRole 
        name: cluster-admin
      subjects: 
      - kind: ServiceAccount 
        name: prometheus 
        namespace: monitoring
      
    3. 创建node-exporter
      apiVersion: apps/v1
      kind: DaemonSet
      metadata:
        labels:
          app.kubernetes.io/component: exporter
          app.kubernetes.io/name: node-exporter
          app.kubernetes.io/part-of: kube-prometheus
          app.kubernetes.io/version: 1.7.0
        name: node-exporter
        namespace: monitoring
      spec:
        selector:
          matchLabels:
            app.kubernetes.io/component: exporter
            app.kubernetes.io/name: node-exporter
            app.kubernetes.io/part-of: kube-prometheus
        template:
          metadata:
            annotations:
              kubectl.kubernetes.io/default-container: node-exporter
            labels:
              app.kubernetes.io/component: exporter
              app.kubernetes.io/name: node-exporter
              app.kubernetes.io/part-of: kube-prometheus
              app.kubernetes.io/version: 1.7.0
          spec:
            automountServiceAccountToken: true
            containers:
            - args:
              - --web.listen-address=127.0.0.1:9100
              - --path.sysfs=/host/sys
              - --path.rootfs=/host/root
              - --path.udev.data=/host/root/run/udev/data
              - --no-collector.wifi
              - --no-collector.hwmon
              - --no-collector.btrfs
              - --collector.filesystem.mount-points-exclude=^/(dev|proc|sys|run/k3s/containerd/.+|var/lib/docker/.+|var/lib/kubelet/pods/.+)($|/)
              - --collector.netclass.ignored-devices=^(veth.*|[a-f0-9]{15})$
              - --collector.netdev.device-exclude=^(veth.*|[a-f0-9]{15})$
              image: quay.io/prometheus/node-exporter:v1.7.0
              name: node-exporter
              resources:
                limits:
                  cpu: 250m
                  memory: 180Mi
                requests:
                  cpu: 102m
                  memory: 180Mi
              securityContext:
                allowPrivilegeEscalation: false
                capabilities:
                  add:
                  - SYS_TIME
                  drop:
                  - ALL
                readOnlyRootFilesystem: true
              volumeMounts:
              - mountPath: /host/sys
                mountPropagation: HostToContainer
                name: sys
                readOnly: true
              - mountPath: /host/root
                mountPropagation: HostToContainer
                name: root
                readOnly: true
            - args:
              - --secure-listen-address=[$(IP)]:9100
              - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
              - --upstream=http://127.0.0.1:9100/
              env:
              - name: IP
                valueFrom:
                  fieldRef:
                    fieldPath: status.podIP
              image: quay.io/brancz/kube-rbac-proxy:v0.15.0
              name: kube-rbac-proxy
              ports:
              - containerPort: 9100
                hostPort: 9100
                name: https
              resources:
                limits:
                  cpu: 20m
                  memory: 40Mi
                requests:
                  cpu: 10m
                  memory: 20Mi
              securityContext:
                allowPrivilegeEscalation: false
                capabilities:
                  drop:
                  - ALL
                readOnlyRootFilesystem: true
                runAsGroup: 65532
                runAsNonRoot: true
                runAsUser: 65532
                seccompProfile:
                  type: RuntimeDefault
            hostNetwork: true
            hostPID: true
            nodeSelector:
              kubernetes.io/os: linux
            priorityClassName: system-cluster-critical
            securityContext:
              runAsNonRoot: true
              runAsUser: 65534
            serviceAccountName: node-exporter
            tolerations:
            - operator: Exists
            volumes:
            - hostPath:
                path: /sys
              name: sys
            - hostPath:
                path: /
              name: root
        updateStrategy:
          rollingUpdate:
            maxUnavailable: 10%
          type: RollingUpdate
      

  • 加载Prometheus监控配置
    1. 获取token并存入文件,将文件移动到Prometheus的安装目录
      在K8S集群节点上执行命令获取Prometheus访问K8S集群需要的token
      kubectl get secrets -n monitoring|grep prometheus-token |awk '{print $1}' |xargs
      kubectl -n monitoring describe secrets |grep -i token: |awk '{print $2}'
      在1.25及以上k8s版本的集群中,ServiceAccount将不会自动创建对应的Secret。如果业务中需要一个永不过期的Token,可以选择手动管理ServiceAccount的Secret: https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-service-account/#manually-create-an-api-token-for-a-serviceaccount

    2. 修改Prometheus配置文件

      # my global config
      global: 
          scrape_interval:     15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. 
          evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. 
      
      scrape_configs: 
        - job_name: 'prometheus' 
          static_configs: 
          - targets: ['localhost:9090'] 
      
        - bearer_token: token              #指定访问需要的token,在上一步骤中通过命令获取 
          job_name: kubernetes-cadvisor 
          kubernetes_sd_configs: 
          - role: node 
            api_server: https://192.168.0.182:5443    #被监控集群的kube-apiserver地址 
            bearer_token: token                       #在上一步骤中获取的token 
            tls_config: 
              insecure_skip_verify: true              #跳过对服务端的认证 
          relabel_configs: 
          - replacement: 192.168.0.182:5443           #将__address__标签的值设为kube-apiserver的地址 
            target_label: __address__ 
          - regex: (.+) 
            replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor      #该url路径为K8S集群对node上端口的代理路径 
            source_labels: 
            - __meta_kubernetes_node_name 
            target_label: __metrics_path__ 
          metric_relabel_configs: 
          - source_labels: [ pod ] 
            target_label: pod_name 
          - source_labels: [ container ]
            target_label: container_name 
          scheme: https                               #表示监控目标的指标数据通过https暴露 
          tls_config: 
            insecure_skip_verify: true
      
         - job_name: kubernetes-nodes 
           kubernetes_sd_configs: 
           - role: node 
             api_server: https://192.168.0.182:5443 
             bearer_token_file: token_file 
             tls_config: 
               insecure_skip_verify: true 
           relabel_configs: 
           - regex: (.+) 
             replacement: $1:9100 
             source_labels: 
             - __meta_kubernetes_node_name 
             target_label: __address__ 
           - target_label: node 
             source_labels: [instance] 
      
    3. 使prometheus配置生效
      curl -X POST http://localhost:9090/-/reload
      查看监控页面:
      image.png

推荐

华为开发者空间发布

让每位开发者拥有一台云主机

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。