资源配额基础:Requests 与 Limits 的概念及 Prometheus 组件配额设置

在 Kubernetes 中运行 Prometheus 时,资源配额是保障集群稳定性和服务质量的基石。理解 Requests(请求) 与 Limits(限制) 的差异,并正确为 Prometheus 各组件设置 CPU 和内存配额,是避免资源争抢、防止 OOMKill 和提升调度效率的关键。

Requests 与 Limits 核心概念

Kubernetes 通过两个维度管理容器资源:

  • Requests:容器启动时向集群保证的最小资源量。调度器依据 Requests 选择满足条件的节点,并确保容器至少能获得该资源量。
  • Limits:容器运行时允许使用的资源上限。当容器尝试超过 Limits 时,CPU 会被限流(Throttling),内存则可能触发 OOMKill。
关键原则:Requests ≤ Limits。若未显式设置 Limits,Kubernetes 默认将其与 Requests 相等(部分集群通过 LimitRange 或默认配置调整)。
属性 CPU 行为 内存行为 调度影响
Requests 保证最小 CPU 时间片 保证最小内存分配 调度器按 Requests 计算节点剩余容量
Limits 超过后 CPU 被限流(Throttle) 超过后容器被 OOMKill 不影响调度决策,但影响运行时稳定性
未设置 Limits 可突发使用节点空闲 CPU 可无限使用内存(风险极高) 可能因内存泄漏导致节点压力
实践建议:对于 Prometheus 这类有状态、内存敏感的服务,始终显式设置 Limits,避免因突发流量导致节点 OOM。

Requests 与 Limits 的调度与运行机制

下图展示了 Requests 和 Limits 在调度阶段与运行阶段的作用路径:

Requests 与 Limits 调度与运行机制 调度阶段(Scheduler) • 读取 Pod 中所有容器的 Requests 总和 • 检查节点剩余可分配资源 ≥ Requests • 忽略 Limits,仅以 Requests 为调度依据 运行阶段(Kubelet / CRI) • CPU:CFS 配额按 Limits 分配时间片 • 内存:cgroup memory.limit_in_bytes 硬限制 • 超过 Limits → CPU Throttle / OOMKill ⚠ 常见误区: 设置过大的 Requests 会导致节点资源碎片化,调度失败;不设置 Limits 则可能引发内存泄漏扩散。 推荐设置策略 • Requests = 稳态负载 × 1.2 • Limits = Requests × 1.5 ~ 2.0 避免策略 • Requests 与 Limits 差距过大(突发风险) • 所有组件使用相同配额(忽视差异)

Prometheus 组件资源特征分析

Prometheus 生态包含多个组件,每个组件的资源消耗模式不同:

组件 CPU 敏感度 内存敏感度 主要资源瓶颈
Prometheus Server 中(查询与 WAL 压缩) 高(TSDB 内存映射) 内存:活跃序列数 × 样本大小
Alertmanager 低 中(告警缓存) 内存:告警聚合与去重
Node Exporter 低 低 几乎无瓶颈,但需防突发
kube-state-metrics 中(指标生成) 中(对象缓存) 内存:集群资源对象数量
Grafana 低(面板渲染) 中(仪表板缓存) 内存:并发面板数量
注意:Prometheus Server 的内存消耗与 活跃时间序列数 强相关。每增加 100 万活跃序列,大约需要 1~2 GB 内存。设置 Limits 时需预留 20%~30% 的缓冲空间。

为 Prometheus 组件设置 CPU 和内存配额

以下示例展示如何在 Prometheus StatefulSet 中配置资源配额:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: prometheus-server
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prometheus
  template:
    metadata:
      labels:
        app: prometheus
    spec:
      containers:
      - name: prometheus
        image: prom/prometheus:v2.53.0
        args:
          - "--config.file=/etc/prometheus/prometheus.yml"
          - "--storage.tsdb.path=/prometheus"
          - "--storage.tsdb.retention.time=15d"
        resources:
          requests:
            memory: "4Gi"
            cpu: "2"
          limits:
            memory: "6Gi"
            cpu: "4"
        ports:
        - containerPort: 9090
          name: http
        volumeMounts:
        - name: prometheus-data
          mountPath: /prometheus
        - name: config-volume
          mountPath: /etc/prometheus
      volumes:
      - name: prometheus-data
        persistentVolumeClaim:
          claimName: prometheus-data-pvc
      - name: config-volume
        configMap:
          name: prometheus-config

组件配额推荐参考表

以下为中小规模集群(约 500 节点、50 万活跃序列)的推荐初始值:

组件 CPU Requests CPU Limits Memory Requests Memory Limits
Prometheus Server 2 4 4 Gi 6 Gi
Alertmanager 0.5 1 512 Mi 1 Gi
Node Exporter 0.1 0.2 128 Mi 256 Mi
kube-state-metrics 0.5 1 512 Mi 1 Gi
Grafana 0.5 1 512 Mi 1 Gi
调优建议:使用 Prometheus 内置的 /api/v1/status/tsdb 接口查看内存映射大小,结合 container_memory_working_set_bytes 指标动态调整 Requests 和 Limits。建议每季度重新评估一次配额。

配额设置常见陷阱与避坑指南

  • 陷阱 1:Requests 设置过高 → 导致节点资源碎片化,Pod 无法调度。解决方案:使用 requests = 实际稳态使用量 × 1.2。
  • 陷阱 2:Limits 未设置或过大 → 内存泄漏时影响同节点其他 Pod。解决方案:始终设置 Limits,且不超过节点内存的 60%。
  • 陷阱 3:CPU Limits 过小 → 查询高峰期出现 CPU Throttling,导致查询超时。解决方案:监控 container_cpu_cfs_throttled_seconds_total 指标。
  • 陷阱 4:所有组件使用相同配额 → 浪费资源或导致瓶颈。解决方案:按组件特征差异化配置。

验证配额生效的方法

部署后可通过以下命令验证配额是否生效:

# 查看 Pod 实际资源使用
kubectl top pod prometheus-server-0 -n monitoring

# 查看 cgroup 限制是否生效(需进入容器)
kubectl exec -it prometheus-server-0 -n monitoring -- cat /sys/fs/cgroup/memory/memory.limit_in_bytes

# 监控 CPU Throttling
kubectl exec -it prometheus-server-0 -n monitoring -- cat /sys/fs/cgroup/cpu/cpu.stat | grep throttled
最佳实践:将资源配额与 Vertical Pod Autoscaler(VPA) 结合使用,VPA 可根据历史使用数据自动调整 Requests 和 Limits,减少人工干预。