Prometheus operator 系统参数和监控数据抓取调优

一、部署环境

    prometheus 目前我们是使用operator 部署的单点实例,部署在k8s集群中的 10.53.7.138节点,这台机器专用于部署prometheus。业务容器不允许调度在这台机器上

二、使用场景

  1. 采集和存储线上k8s集群的所有监控数据,包含基础服务组件例如etcd、kubelet、coredns等,同时还有最主要的就是pod的监控以及k8s node节点的监控
  2. 存储业务打点数据,配置serviceMonitor 采集业务监控指标用于实现业务的监控展示以及报警
  3. 集群外自定义的exporter、例如nginx_exporter、以及非集群内的主机监控
  4. 告警rules配置

三、问题现象

3.1 prometheus 磁盘存储暴涨

3.2 prometheus 占用大量内存导致触发kubelet驱逐事件

四、优化方案

干货来了~

4.1 prometheus参数调优和数据抓取优化

4.1.1 operator 配置文件优化

我当前的版本是 version: v2.48.1

  spec:
    # additionalScrapeConfigs: 指定额外的抓取配置,通过 Kubernetes Secret 存储,并通过 key 指定文件名称。
    additionalScrapeConfigs:
      key: prometheus-additional.yaml
      name: additional-scrape-configs
    # 节点亲和性配置,要求 Pod 安排到具有 deploy: prometheus 标签的节点上
    affinity:
      nodeAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
          - matchExpressions:
            - key: deploy
              operator: In
              values:
              - prometheus
    alerting:
      alertmanagers:
      - apiVersion: v2
        name: uk8s-alertmanager
        namespace: uk8s-monitor
        pathPrefix: /
        port: web
    containers:
    - args:
      - --storage.tsdb.max-block-duration=1h
      - --storage.tsdb.min-block-duration=30m
      - --storage.tsdb.no-lockfile
      - --storage.tsdb.wal-compression
      - --web.console.templates=/etc/prometheus/consoles
      - --web.console.libraries=/etc/prometheus/console_libraries
      - --storage.tsdb.retention.size=900GB
      - --config.file=/etc/prometheus/config_out/prometheus.env.yaml
      - --storage.tsdb.path=/prometheus
      - --storage.tsdb.retention.time=10d
      - --web.enable-lifecycle
      - --web.external-url=http://prometheus.xxx.cn
      - --web.route-prefix=/
      - --web.config.file=/etc/prometheus/web_config/web-config.yaml
      - --query.timeout=2m
      - --query.max-concurrency=20
      - --query.max-samples=5000000
      - --web.max-connections=512
      name: prometheus
    enableAdminAPI: false
    evaluationInterval: 60s
    externalUrl: http://prometheus.xxx.cn
    image: quay.io/prometheus/prometheus
    listenLocal: false
    logFormat: logfmt
    logLevel: info
    paused: false
    podMetadata:
      labels:
        k8s-app: uk8s-monitor
    podMonitorNamespaceSelector: {}
    podMonitorSelector: {}
    portName: web
    replicas: 1
    resources:
      limits:
        cpu: 13
        memory: 55Gi
      requests:
        cpu: 13
        memory: 55Gi
    retention: 10d
    retentionSize: 900GB
    routePrefix: /
    ruleNamespaceSelector: {}
    ruleSelector: {}
    scrapeInterval: 60s
    scrapeTimeout: 10s
    secrets:
    - etcd-client-cert
    securityContext:
      fsGroup: 2000
      runAsGroup: 2000
      runAsNonRoot: true
      runAsUser: 1000
    serviceAccountName: prometheus
    serviceMonitorNamespaceSelector: {}
    serviceMonitorSelector: {}
    #  存储配置,使用 PVC(PersistentVolumeClaim)模版
    storage:
      volumeClaimTemplate:
        metadata:
          labels:
            k8s-app: uk8s-monitor
        spec:
          accessModes:
          - ReadWriteOnce
          resources:
            requests:
              storage: 1000Gi
          storageClassName: ssd-csi-udisk
    # 容忍性,允许 Pod 调度到具有 business=sre 污点的节点上,具有 NoSchedule 效应
    tolerations:
    - effect: NoSchedule
      key: business
      operator: Equal
      value: sre
    version: v2.48.1
    walCompression: true

重要的参数解释

  args启动参数解释

--storage.tsdb.max-block-duration=1h: 设置最大数据块持续时间为1小时。

--storage.tsdb.min-block-duration=30m: 设置最小数据块持续时间为30分钟。

--storage.tsdb.no-lockfile: 禁用锁文件。

--storage.tsdb.wal-compression: 启用 WAL(Write Ahead Log)压缩。

--storage.tsdb.retention.size=900GB: 数据保留大小为900GB。

--storage.tsdb.retention.time=10d: 数据保留时间为10天。

--web.enable-lifecycle: 启用生命周期管理。

--query.timeout=2m: 查询超时时间2分钟。

--query.max-concurrency=20: 最大并发查询数量20。

--query.max-samples=5000000: 单次查询的最大样本数5,000,000。

--web.max-connections=512: 最大 HTTP 连接数512。

 全局配置

  scrapeInterval: 60s  # 全局抓取间隔60秒
  scrapeTimeout: 10s  # 全局抓取超时10秒
  evaluationInterval: 60s  # 规则评估间隔时间,为60秒。

4.2 监控数据抓取优化

4.2.1 完整配置如下

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: xxx
  namespace: xxx
spec:
  endpoints:
  - interval: 30s
    path: /actuator/prometheus
    port: 9203tcp
    scheme: http
    scrapeTimeout: 10s
    relabelings:
    - action: labeldrop
      regex: 'namespace|container|endpoint|job|user'
  sampleLimit: 200000 # 限制每个抓取请求的样本数
  namespaceSelector:
    matchNames:
    - xxx
  selector:
    matchLabels:
      k8sapp: xxx

4.2.2 配置说明

spec: 定义 ServiceMonitor 的详细配置。

endpoints: 定义 Prometheus 如何抓取服务数据的一个或多个终端点。

interval: 30s: 抓取间隔时间,每 30 秒抓取一次数据。

path: /actuator/prometheus: URL 路径,Prometheus 使用这个路径来抓取指标数据。

port: 9203tcp: 服务的端口号,到这个端口发送请求抓取数据。

scheme: http: 使用的协议,这里是 HTTP。

scrapeTimeout: 10s: 抓取超时时间,如果超过 10 秒,请求将会超时。



relabelings: 标签重写规则,用于修改或删除标签。

action: labeldrop: 表示要删除标签。

regex: 'namespace|container|endpoint|job|user': 使用正则表达式匹配标签名称,这里匹配的标签包括 namespace, container, endpoint, job, 和 user。
  • spec: 定义 ServiceMonitor 的详细配置。
  • endpoints: 定义 Prometheus 如何抓取服务数据的一个或多个终端点。
    • interval: 30s: 抓取间隔时间,每 30 秒抓取一次数据。
    • path: /actuator/prometheus: URL 路径,Prometheus 使用这个路径来抓取指标数据。
    • port: 9203tcp: 服务的端口号,到这个端口发送请求抓取数据。
    • scheme: http: 使用的协议,这里是 HTTP。
    • scrapeTimeout: 10s: 抓取超时时间,如果超过 10 秒,请求将会超时。

relabelings: 标签重写规则,用于修改或删除标签。

  • action: labeldrop: 表示要删除标签。
  • regex: 'namespace|container|endpoint|job|user': 使用正则表达式匹配标签名称,这里匹配的标签包括 namespace, container, endpoint, job, 和 user
  • sampleLimit: 200000: 设置每次抓取请求允许的最大样本数,限制在 200,000 样本内。这是为了防止单次抓取请求产生过多样本,导致性能问题。

4.2.3 关键点总结

  1. 抓取配置:

    • 频率: 每 30 秒抓取一次。
    • 路径: 请求 /actuator/prometheus 路径。
    • 端口: 使用端口 9203tcp
    • 协议: 使用 HTTP 协议。
    • 超时: 请求超时时长为 10 秒。
  2. 标签重写:

    • 使用 labeldrop 操作和正则表达式删除不需要的标签 namespace, container, endpoint, job, user 以减少标签的基数。
  3. 样本限制:

    • sampleLimit 配置限制每次抓取请求的样本数,以防止因单一抓取请求导致的过高开销。

这份 ServiceMonitor 配置定义了 Prometheus 如何从指定服务中抓取指标数据,如何处理标签以减少存储压力,以及如何限制抓取请求的样本数来优化性能和资源使用。通过这些配置,可以确保 Prometheus 高效地监控符合条件的服务并合理管理资源。

4.3 业务方要遵守以下规则

4.3.1 基本命名规范

指标命名
  • 简洁明了:指标名称应当简洁、描述性强。避免使用复杂、难以理解的名称。
    http_requests_total
    
  • 使用标准前缀和单位:遵循 Prometheus 社区推荐的命名惯例,例如 _total 表示计数器, _duration_seconds 表示时间度量。
    request_duration_seconds

4.3.2 标签(Label)设计

标签名称
  • 规范化名称:标签应使用规范化的名称,避免大小写混用。
    service, region, method
    
控制基数
  • 避免高基数标签:不要使用会产生高基数的标签值,例如用户ID、IP地址、唯一请求ID等。高基数标签会导致大量时间序列,增加存储和检索的负担。
    // Bad: method is too granular
    status_code{method="/users/123/profile", service="user-service"}
    
    // Good: use generalized method
    status_code{method="GET", service="user-service"}
    

4.3.3. 衡量类型和用途

计数器(Counter)

计数器是单调递增的度量,用于记录事件的总数量。

httpRequestsTotal := prometheus.NewCounter(prometheus.CounterOpts{
  Name: "http_requests_total",
  Help: "Total number of HTTP requests.",
})
仪表(Gauge)

仪表用于记录能够增加和减少的数值,例如当前的内存使用。

memoryUsage := prometheus.NewGauge(prometheus.GaugeOpts{
  Name: "memory_usage_bytes",
  Help: "Current memory usage in bytes.",
})
直方图(Histogram)和摘要(Summary)

直方图和摘要用于分布统计,特别适合记录请求持续时间或响应大小等度量。

requestDurationHist := prometheus.NewHistogram(prometheus.HistogramOpts{
  Name:    "http_request_duration_seconds",
  Help:    "Duration of HTTP requests in seconds.",
  Buckets: prometheus.LinearBuckets(0.01, 0.05, 10), // 0.01s to 0.51s
})

4.3.4 合理模块化与封装

封装指标创建

将指标的创建与初始化封装在一个独立的模块中,使代码更具可维护性和重用性

package metrics

import (
  "github.com/prometheus/client_golang/prometheus"
)

var (
  HttpRequestsTotal = prometheus.NewCounter(prometheus.CounterOpts{
    Name: "http_requests_total",
    Help: "Total number of HTTP requests.",
  })
  MemoryUsage = prometheus.NewGauge(prometheus.GaugeOpts{
    Name: "memory_usage_bytes",
    Help: "Current memory usage in bytes.",
  })
  ...
)

func Init() {
  prometheus.MustRegister(HttpRequestsTotal, MemoryUsage)
}

4.3.5 优化打点性能

缓存和批处理

根据实际情况,适当缓存数据并进行批处理,减少对指标的频繁操作。

// Example of batch processing
func ProcessDataBatch(batch []Data) {
  start := time.Now()
  for _, data := range batch {
    process(data)
    metrics.DataProcessed.Inc()
  }
  duration := time.Since(start).Seconds()
  metrics.BatchProcessDuration.Observe(duration)
}
延迟操作

仅在必要时更新指标,尽量减少对性能的影响。

if needToUpdateMetrics {
  metrics.HttpRequestsTotal.Inc()
}

4.3.6 文档与注释

注释与文档

为每个指标添加适当的注释和文档,帮助其他开发者理解指标的用途和含义

// HttpRequestsTotal counts the total number of HTTP requests received.
var HttpRequestsTotal = prometheus.NewCounter(prometheus.CounterOpts{
  Name: "http_requests_total",
  Help: "Total number of HTTP requests received.",
})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cloud孙文波

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值