kube-prometheus 持久化实战:Prometheus 与 Grafana 数据不丢失配置指南

发布时间:2026/10/12 19:33:16
kube-prometheus 持久化实战:Prometheus 与 Grafana 数据不丢失配置指南 1. 为什么默认部署的监控栈一重启就“失忆”如果你用 Helm 或 Operator 部署过 kube-prometheus 这套监控组合大概率经历过这样的场景辛辛苦苦调好的 Grafana 面板、配好的告警规则、攒了两周的监控数据一次 Pod 重启或者节点漂移之后全部归零。这不是 bug而是默认配置下这套栈的存储设计就是“用完即弃”的。kube-prometheus 本质上是把 Prometheus、Alertmanager、Grafana 以及一堆 Exporter 和规则打包在一起的一套编排方案。它默认用 emptyDir 作为存储卷Pod 一重建数据就跟着没了。对于只是想跑个 Demo 的人来说这没什么但只要你想把它用在稍微正式一点的场景里——哪怕只是个人实验室的长期监控——持久化就是绕不过去的第一道坎。这篇文章要解决的就是两个核心问题Prometheus 的时序数据怎么持久化以及Grafana 的配置和面板怎么持久化。前者关系到你的历史监控数据能不能留存后者关系到你花几个小时调出来的仪表盘会不会白费。我会从存储选型、配置改法、参数计算到踩坑排查把整套流程拆开讲清楚让你看完就能直接抄作业。适合的读者是已经用 kube-prometheus 跑起来一套监控、但还没做持久化的运维或开发人员或者正准备部署、想一步到位把存储规划好的朋友。不需要你对 Prometheus 内部原理有多深的理解但至少要能看懂 Kubernetes 的 YAML 和 PVC 的基本概念。2. 存储方案选型别一上来就上分布式存储在动手改配置之前先想清楚一件事你的数据要存到哪里。这个决定会直接影响后面的配置方式和运维复杂度。我见过不少人一上来就想着上 Ceph 或者某分布式存储结果为了监控持久化搭进去一整套存储集群本末倒置。2.1 三种常见存储方案的取舍逻辑选存储的核心就三个维度数据重要性、性能要求、运维成本。把这三个维度套进去方案基本就清晰了。方案类型典型实现适用场景优点代价本地盘hostPath、local PV单节点、个人实验室性能最好、零额外依赖节点故障数据丢失、无法漂移网络块存储各类云盘、iSCSI中小规模生产可漂移、性能尚可依赖存储后端、有网络延迟分布式文件/对象各类分布式存储大规模、多副本要求高可用、可扩展运维复杂、成本高我的建议很直接个人或小团队场景优先用网络块存储实在没有本地盘也能用但要接受数据可能丢的风险。Prometheus 的时序数据写入是顺序追加为主对随机 IO 要求不高但对磁盘的持续写入能力有要求所以选存储时别只看容量要看 IOPS 和吞吐。2.2 容量到底要留多少一个能算的公式很多人配 PVC 的时候是拍脑袋填个 50Gi 或者 100Gi结果要么不够用要么浪费。Prometheus 的存储占用其实是可以估算的核心公式是所需容量 每秒采集样本数 × 每个样本字节数 × 保留时间(秒) × 副本系数每个样本在 Prometheus 的 TSDB 里压缩后大约占 1~2 字节但考虑到索引、WAL 和压缩过程中的临时空间工程上一般按每个样本 2 字节来估。举个例子假设你有 1000 个活跃时间序列采集间隔 15 秒那么每秒样本数约为 1000/15 ≈ 67 个。保留 15 天67 × 2 字节 × 15 × 86400 秒 ≈ 173 MB看起来很小对吧但实际场景里时间序列数量往往远不止 1000加上各种 Exporter 的指标、标签组合爆炸轻松上到几万甚至几十万序列。所以更实用的做法是先跑一周看 Prometheus 实际占用了多少再按比例推算保留期所需的容量最后留 30% 余量。提示Prometheus 的--storage.tsdb.retention.time和--storage.tsdb.retention.size可以同时设置谁先触发谁生效。生产环境建议两个都设避免磁盘被写满导致进程崩溃。2.3 Grafana 的持久化为什么和 Prometheus 不一样这里有个容易混淆的点Prometheus 持久化的是时序数据而 Grafana 持久化的是配置数据——包括数据源、面板、用户、告警配置等。Grafana 默认用 SQLite 数据库存在容器里Pod 一重建就没了。Grafana 的持久化有两种思路一是把 SQLite 文件挂到 PVC 上简单直接二是换成外部数据库如 MySQL、PostgreSQL适合多副本部署。对于绝大多数场景挂 PVC 就够了没必要为了一个 Grafana 上外部数据库。但要注意如果你打算跑多个 Grafana 副本SQLite 会有并发写入问题这时候才需要考虑外部数据库。3. Prometheus 数据持久化实操从 emptyDir 到 PVC搞清楚了选型和容量接下来动手改。kube-prometheus 的 Prometheus 实例是通过一个名为Prometheus的自定义资源CRD来定义的持久化配置就写在这个资源里。3.1 定位并修改 Prometheus 自定义资源先找到当前的 Prometheus 资源kubectl get prometheus -n monitoring假设输出里有个叫k8s的实例用下面的命令看它的完整配置kubectl get prometheus k8s -n monitoring -o yaml你会看到spec.storage字段默认可能是空的或者写着emptyDir: {}。要改成 PVC需要这样写apiVersion: monitoring.coreos.com/v1 kind: Prometheus metadata: name: k8s namespace: monitoring spec: retention: 15d storage: volumeClaimTemplate: spec: storageClassName: your-storage-class accessModes: - ReadWriteOnce resources: requests: storage: 50Gi这里有几个关键点要解释清楚。volumeClaimTemplate是一个模板Operator 会用它为每个 Prometheus Pod 生成一个独立的 PVC。storageClassName必须填你集群里实际存在的存储类用kubectl get storageclass可以查。accessModes一般用ReadWriteOnce因为 Prometheus 是单副本写入不需要多节点同时挂载。改完之后直接kubectl apply应用Operator 会滚动重建 Prometheus Pod并自动创建 PVC。你可以用下面的命令确认 PVC 是否绑定成功kubectl get pvc -n monitoring3.2 保留时间与容量的联动配置retention字段控制数据保留多久默认是 24 小时这个值对于正经监控来说太短了。常见的设置是15d到30d具体取决于你的容量和查询需求。这里有个实操经验保留时间不要设得太长历史数据的查询频率其实很低。如果你需要长期留存更好的做法是用远程写入remote write把数据转发到专门的长存储系统而不是让 Prometheus 本地扛着。本地保留 15 天足够覆盖绝大多数排障和趋势分析场景。另外retention和 PVC 容量要匹配。如果你设了 30 天保留但只给了 20GiPrometheus 会在写满后开始删除旧数据甚至可能因为磁盘压力触发告警。所以改保留时间的时候一定回头检查容量够不够。3.3 验证持久化是否真正生效改完配置不代表就成功了得验证。最直接的方法是这样记录当前 Prometheus Pod 的名字和它挂载的 PVC。手动删除这个 Pod等它重建。重建后进入 Pod检查历史数据是否还在。具体命令# 查看 Pod 和 PVC 的绑定关系 kubectl get pod -n monitoring -l app.kubernetes.io/nameprometheus -o wide kubectl get pvc -n monitoring # 删除 Pod 触发重建 kubectl delete pod prometheus-pod-name -n monitoring # 等新 Pod 起来后查询一个历史时间点的数据 kubectl exec -it new-prometheus-pod -n monitoring -- \ promtool query instant http://localhost:9090 up --time某个过去的时间戳如果新 Pod 能查到删除前的数据说明持久化生效了。如果查不到八成是 PVC 没绑上或者挂载路径不对。注意Prometheus Operator 在重建 Pod 时如果发现原来的 PVC 还在会复用如果 PVC 被删了就会新建一个空的。所以千万别手贱去删 PVC。4. Grafana 配置持久化别让调好的面板白费Grafana 的持久化比 Prometheus 简单但有个坑很多人会踩只挂了数据卷却没处理配置的初始化逻辑导致重启后虽然数据在但配置被覆盖了。4.1 通过 Deployment 挂载 PVC 的标准做法kube-prometheus 默认用 Deployment 部署 Grafana。要持久化需要做两件事创建一个 PVC然后在 Deployment 里挂载它。先创建 PVCapiVersion: v1 kind: PersistentVolumeClaim metadata: name: grafana-storage namespace: monitoring spec: storageClassName: your-storage-class accessModes: - ReadWriteOnce resources: requests: storage: 5GiGrafana 的配置数据量很小5Gi 绰绰有余主要是 SQLite 数据库和插件。然后在 Grafana 的 Deployment 里找到volumes和volumeMounts加上挂载volumeMounts: - name: grafana-storage mountPath: /var/lib/grafana volumes: - name: grafana-storage persistentVolumeClaim: claimName: grafana-storage/var/lib/grafana是 Grafana 默认存放数据库和插件的地方挂上这个路径配置就持久了。4.2 用 Helm 部署时的 values 覆盖技巧如果你是用 Helm 部署的 kube-prometheus-stack直接改 Deployment 会被下次helm upgrade覆盖掉。正确做法是在 values 文件里配置grafana: persistence: enabled: true storageClassName: your-storage-class size: 5Gi accessModes: - ReadWriteOnce这样 Helm 渲染出来的 Deployment 就会自动带上 PVC 挂载。改完执行helm upgrade即可。这里的关键是不要手动去改 Operator 或 Helm 管理的资源否则下次同步就丢了所有改动都要通过 values 或 CRD 来做。4.3 数据源和面板的“配置即代码”思路挂 PVC 解决了持久化但还有个更深层的问题如果 PVC 也丢了怎么办。这时候就需要“配置即代码”的思路把 Grafana 的配置用声明式的方式管理起来。Grafana 支持通过 ConfigMap 挂载数据源和面板的 provisioning 配置。你可以在 values 里这样写grafana: additionalDataSources: - name: Prometheus type: prometheus url: http://prometheus-operated:9090 access: proxy isDefault: true面板也可以通过dashboardProviders和 ConfigMap 来预置。这样一来即使 PVC 全丢了重新部署时配置会自动恢复。PVC 负责运行时数据用户、临时改动provisioning 负责基线配置两者配合才是完整的持久化方案。提示provisioning 的配置默认是只读的在 Grafana 界面上改不了。如果你需要界面编辑就别把面板放进 provisioning或者接受“界面改动重启后丢失”的设定。5. 常见问题与排查技巧实录持久化这件事配起来不难难的是出问题的时候怎么快速定位。下面这些是我在实际操作中踩过的坑和对应的排查思路。5.1 PVC 一直 Pending 怎么办这是最常见的问题PVC 创建后卡在 Pending 状态Pod 也就起不来。排查顺序是这样的排查项检查命令常见原因StorageClass 是否存在kubectl get sc名字写错或没装存储插件是否有可用 PVkubectl get pv静态供应模式下没有匹配的 PV容量是否满足看 PVC 的 events请求容量超过后端限制访问模式是否支持看 StorageClass 定义后端不支持 ReadWriteOnce用kubectl describe pvc name -n monitoring看 Events 部分通常会有明确的原因提示。如果是动态供应重点看 StorageClass 的 provisioner 是否正常工作。5.2 Pod 起来了但数据没持久化这种情况通常是挂载路径不对或者挂载被覆盖了。比如 Prometheus 的数据目录默认是/prometheus如果你挂到了别的路径数据还是写在容器层。验证方法进入 Pod用df -h看挂载点确认目标路径确实挂的是 PVC 而不是 overlay。另外检查一下securityContext里的fsGroup如果权限不对Prometheus 可能写不进去日志里会有 permission denied。5.3 Grafana 重启后配置回滚这个问题的根源往往是 provisioning 和数据库的冲突。如果你既挂了 PVC又配了 provisioning重启后 provisioning 的配置会覆盖数据库里的同名配置。解决办法是要么统一用 provisioning 管理要么统一用界面管理别混着来。还有一种可能是 Helm 的helm upgrade把 Deployment 的挂载改回去了。检查一下 values 文件里的 persistence 配置是否真的生效用helm get values确认。5.4 存储写满后的应急处理Prometheus 磁盘写满会导致进程崩溃Pod 反复重启。应急处理是先进 Pod 删掉部分旧数据或者临时调小 retention。但更根本的做法是提前配好告警监控 PVC 的使用率。- alert: PrometheusStorageAlmostFull expr: | (kubelet_volume_stats_used_bytes{persistentvolumeclaim~prometheus.*} / kubelet_volume_stats_capacity_bytes{persistentvolumeclaim~prometheus.*}) 0.85 for: 10m labels: severity: warning annotations: summary: Prometheus 存储使用率超过 85%这条告警规则建议直接加上能帮你避免半夜被磁盘写满叫醒。6. 几个我踩过之后才明白的细节最后分享几个文档里不太会写、但实际很关键的经验点。第一PVC 的回收策略要留意。动态供应的 PV 默认回收策略是 Delete意味着你删了 PVC底层存储也会被删。如果你只是想重建 Pod 而不是丢数据千万别删 PVC。可以在 StorageClass 里把reclaimPolicy设成 Retain给自己留条后路。第二Prometheus 的 WAL 目录也要持久化。有些人只挂了数据目录忽略了 WAL。WAL 是预写日志用于崩溃恢复如果它在容器层Pod 异常重启后可能丢失最近几分钟的数据。确保整个/prometheus目录都挂上。第三Grafana 的插件目录值得单独考虑。如果你装了很多插件插件文件也占空间而且重装麻烦。可以把/var/lib/grafana/plugins单独挂一个卷或者用 initContainer 在启动时自动安装。第四别忽略备份。持久化不等于备份。PVC 可能因为误删、存储故障而丢失重要的 Grafana 面板建议定期导出 JSON 存档Prometheus 的关键数据可以考虑远程写入到另一个存储。持久化解决的是“重启不丢”备份解决的是“彻底丢了能恢复”两码事。这套配置我在几个不同规模的集群上都跑过从单节点实验室到几十个节点的小集群核心逻辑是一样的选对存储、配对容量、验证生效、做好监控。真正花时间的往往不是配置本身而是排查那些“看起来配了但没生效”的细节。把上面这些点都过一遍基本就能睡个安稳觉了。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询