资讯动态

Kubernetes监控实战:Prometheus + Grafana完整部署与避坑指南

发布时间:2026/10/22 23:36:04 来源:尧图企业网站定制
简介面向Kubernetes集群运维与开发者这套部署方案基于Prometheus和Grafana构建监控体系用来采集集群与应用指标、完成可视化展示并支持告警通知。压缩包仅3个YAML文件总大小5KB分别对应Prometheus服务端、Grafana面板和Node Exporter节点指标收集器配置简洁、便于修改。目前已有836人学习可直接按顺序应用到集群中。借助Prometheus的服务发现机制系统能自动发现新Pod抓取CPU、内存、网络I/O等关键数据Grafana将数据渲染为直观图表运维人员可快速掌握集群状态Node Exporter负责采集各节点的负载、磁盘与网络信息配合Prometheus的告警规则和Alertmanager能在故障发生时及时推送消息。整个方案麻雀虽小但五脏俱全省去了自行编写配置的麻烦特别适合刚开始尝试在Kubernetes中搭建监控体系的读者。1. Kubernetes 监控选型为什么是 Prometheus 和 Grafana集群刚上线那几天一切都很顺利。等业务一扩容Pod 在节点间来回调度旧的监控方案立刻翻车——IP 是死的目标列表是手写的节点一换图就断。后来我把监控栈整体迁到 Prometheus 和 Grafana 上才把“监控谁、从哪抓、怎么画”这件事真正交给集群自己回答。这个标题讲的就是在 Kubernetes 里部署一套以 Prometheus 为采集存储、Grafana 为可视化界面的监控系统让指标跟着服务发现走而不是跟着 IP 走。适合正在维护生产集群、被“扩容后监控失联”折磨的运维和平台工程师读完你能独立装出一套可用、可调、不埋雷的监控栈。2. 把监控链路拆开Prometheus 的拉模型与 Grafana 的展示层2.1 为什么 Prometheus 是 Kubernetes 监控的事实标准Kubernetes 里的 workload 是动态的Deployment 滚动更新、HPA 扩容、节点故障驱逐Pod 的 IP 和名字随时变。传统 Push 模式的 agent 采集方案需要提前知道目标在哪里这在容器环境里非常别扭。Prometheus 走的是 Pull 模型——由 Prometheus Server 主动发 HTTP 请求去抓取指标配合 Kubernetes 的服务发现机制它每隔一段时间向 API Server 询问“当前有哪些 Service、哪些 Pod 带着我要的标签”然后自动生成抓取目标列表。这一步解决的不只是 IP 漂移还包括新 Pod 上线后自动接入监控。这套设计的核心价值在于你不需要在业务容器里塞 Agent只需要暴露一个/metrics端口Prometheus 就能完成发现、拉取、存储、查询。这也是为什么云原生生态里几乎所有组件都自带 metrics 接口比如 kubelet、etcd、API Server都是天然被抓取的对象。2.2 拆开看这套系统由哪几块组成一套完整的 K8s 监控栈不是只有 Prometheus Server 和 Grafana 两个进程。按职责拆至少是四层组件角色部署形态Prometheus Server指标采集、TSDB 存储、PromQL 查询Deployment/StatefulSetExporters暴露指标如 node-exporter、kube-state-metricsDaemonSet / DeploymentAlertmanager接收告警规则做去重、分组、路由DeploymentGrafana数据可视化、告警展示、Dashboard 管理Deployment四个组件里Prometheus 是整个链路的数据中枢负责定时抓取各目标的/metrics把时序数据写入本地 TSDBGrafana 本身不存监控数据它通过数据源接口连接 Prometheus用 PromQL 查询出数据再画成图。需要强调的是很多新手以为“装上 Grafana 就等于监控完成”其实数据采集没通Grafana 只是一块漂亮的空屏幕。2.3 先看一套最小 Prometheus 配置长什么样在没有 Operator 介入之前Prometheus 核心就是一个 YAML 文件加一个启动命令。拿最原始的部署方式来理解它的工作逻辑global: scrape_interval: 30s # 全局抓取间隔默认 1 分钟 evaluation_interval: 30s # 告警规则评估间隔 scrape_configs: - job_name: kubernetes-nodes kubernetes_sd_configs: # 基于 Kubernetes 服务发现 - role: node # 发现所有节点 relabel_configs: - source_labels: [__metrics_path__] regex: /metrics action: replace target_label: __metrics_path__ replacement: /metrics这段配置看的不是命令而是两个关键设计scrape_interval决定数据粒度越短越占存储和内存kubernetes_sd_configs让 Prometheus 自己问 API Server “现在有哪些节点”而不是你在配置文件里写死三个 IP。实际生产里我们很少裸写scrape_configs而是用 Prometheus Operator 的 ServiceMonitor 抽象但底层原理仍然是这套拉取模型。2.4 Prometheus Operator把配置变成 Kubernetes 资源在生产环境里直接管理 Prometheus 的 YAML 配置是有风险的改一个抓取配置要进容器、改文件、重载多人协作时很容易互相覆盖。所以社区的主流做法是用 Prometheus Operator 这一层控制器把“抓取配置”抽象成 ServiceMonitor 这种 CRD 资源。你创建了一个 ServiceMonitorOperator 就自动帮你把对应的scrape_config渲染进 Prometheus 配置里。这套抽象带来一个好处开发自服务的团队可以自己提交 ServiceMonitor不用再去碰 Prometheus 实例的配置。后面我们部署的kube-prometheus-stack就是把 Operator、Prometheus、Grafana、各类 Exporter 打包在一起的完整方案。3. 在 Kubernetes 上部署 Prometheus用 Helm 一次性拉起整套监控栈3.1 部署前要确认的两件事RBAC 权限与存储规划Prometheus 要发现 Kubernetes 资源必须有权限访问 API Server。它的 ServiceAccount 需要能 list/watch nodes、services、endpoints、pods 这些资源。用裸 YAML 部署时最容易漏掉这块结果就是日志里刷kubelet 401 UnauthorizedTargets 页面一片红。用 Helm 部署kube-prometheus-stack时RBAC 相关资源会自动创建但你要知道这个前提存在后面排查权限问题才不抓瞎。存储方面Prometheus 默认把数据写在容器的临时目录里Pod 一重建历史数据就全没了。生产环境要给 Prometheus 配上 PVC容量按“指标数量 × 采集频率 × 保留天数”粗估。一般来说100 个 Pod 规模的集群保留 15 天30Gi 起步如果采集间隔压到 15s这个数字要翻倍。3.2 用 Helm 安装 kube-prometheus-stack 的完整过程这是目前最快、最不容易出错的路径一个 Chart 包含 Prometheus、Grafana、Alertmanager、node-exporter、kube-state-metrics以及它们之间的联动配置。操作步骤分三步执行。# 1. 添加官方 Helm 仓库并更新索引 helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update # 2. 创建独立的命名空间并安装 kubectl create namespace monitoring helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack \ --namespace monitoring \ --version 当前稳定版本参数说明prometheus-community是社区维护的官方 Chart 仓库kube-prometheus-stack是包名--namespace monitoring让所有监控组件集中在一个命名空间方便统一管理权限和网络策略。安装完成后用下面的命令看启动状态kubectl get pods -n monitoring # 期望看到 prometheus、grafana、alertmanager 等 Pod 处于 Running 状态刚装完时 Pod 可能会因为拉镜像慢而卡在ContainerCreating等一两分钟再看是正常的。如果状态一直变CrashLoopBackOff多半是镜像拉不下来或资源限制太小这个我们后面单独讲排查。3.3 安装前把这三个参数写进 values.yaml默认安装能跑通但直接上生产会难受。我一般会在安装前准备一个values.yaml把下面三组参数先改掉grafana: adminPassword: your-strong-password # 默认 admin 密码太简单先改掉 service: type: NodePort # 测试环境用 NodePort 快速访问 nodePort: 30080 prometheus: prometheusSpec: retention: 15d # 指标保留时长默认也是 15d显式写出来便于审计 resources: requests: memory: 2Gi # 请求内存调度时参考 limits: memory: 4Gi # 限制内存防止 OOM 拖垮节点 storageSpec: volumeClaimTemplate: spec: accessModes: [ReadWriteOnce] resources: requests: storage: 50Gi # 给 Prometheus 数据盘参数说明retention是时序数据的保留时间超过这个时间的数据会被后台任务删除storageSpec.volumeClaimTemplate让 Prometheus 的每个副本都绑定一个 PVCPod 调度到其他节点时数据跟着走。资源限制不能省Prometheus 的内存占用会随 target 数量线性增长不设 limits 的后果是 OOM 后 Kubernetes 不断重启它数据写入跟不上。3.4 验证部署结果从 Pod 状态到 Targets 页面部署完不是看一眼 Pod 就完事要验证“能抓能查能画”。先做两步检查# 检查 Prometheus 服务是否在集群内可访问 kubectl get svc -n monitoring # 找到 prometheus 的 ClusterIP 服务一般叫 kube-prometheus-stack-prometheus # 把 Prometheus 的 Web UI 转发到本地 kubectl port-forward -n monitoring svc/kube-prometheus-stack-prometheus 9090:9090浏览器打开http://localhost:9090进入Status → Targets这里会列出 Prometheus 当前抓取的所有目标。正常的节点和 ServiceMonitor 目标应该是绿色的UP状态。如果目标是DOWN点进去能看到具体的拉取错误信息这是后面调监控最重要的入口。4. Grafana 接入与数据源配置让监控面板先亮起来4.1 Grafana 的登录与暴露方式用kube-prometheus-stack安装时 Grafana 已经带好数据源默认配置里已经自动添加了 Prometheus登录后就能看到预置的 Kubernetes 集群监控 Dashboard密码就是刚才values.yaml里设置的adminPassword。但如果你是手工分开部署的 Grafana或者想理解数据源是怎么连上的要按下面的步骤走一遍。访问 Grafana 有两种方式测试环境用 NodePort 或 port-forward生产环境建议走 Ingress 并开启 HTTPS。下面命令把 Grafana 转发到本地 3000 端口kubectl port-forward -n monitoring svc/kube-prometheus-stack-grafana 3000:80浏览器打开http://localhost:3000用admin和你设置的密码登录。登录后第一件事不是建 Dashboard而是确认Configuration → Data Sources → Prometheus里的 URL 是否正确。4.2 数据源的 URL 到底该填什么这是最常见的翻车点。很多人装了 Grafana 后在数据源 URL 里填localhost:9090结果图全是 No Data。原因很简单Grafana 和 Prometheus 在不同的 Pod 里localhost指向的是 Grafana 自己。正确写法是使用 Prometheus 的集群内服务地址格式为http://service-name.namespace.svc.cluster.local:port。用我们 Chart 默认的 release 名实际填的就是# Grafana Data Source 配置示例 apiVersion: v1 kind: ConfigMap metadata: name: grafana-datasources namespace: monitoring data: datasources.yaml: | apiVersion: 1 datasources: - name: Prometheus type: prometheus url: http://kube-prometheus-stack-prometheus.monitoring.svc.cluster.local:9090 access: proxy isDefault: true填完后点Save Test出现绿色提示 Data source is working 就说明通了。如果报HTTP status 400或连接超时优先检查 Prometheus Service 的名字——release 名变了服务名也会跟着变不要照抄网上的路径。4.3 免手工配置用 Provisioning 管理数据源和 Dashboard面板多了以后手工在界面上一个个配置数据源和导入 JSON 是很痛苦的事而且换环境就要重来一遍。生产做法是走 Provisioning把数据源配置和 Dashboard 文件挂载到 Grafana 容器里启动时自动加载。# 把 Dashboard JSON 放到 Grafana 的 provisioning 目录 kubectl create configmap grafana-dashboards \ --from-filedashboards.json \ -n monitoring # 在 values.yaml 中开启挂载 grafana: additionalDataSources: - name: Prometheus type: prometheus url: http://kube-prometheus-stack-prometheus.monitoring.svc.cluster.local:9090 access: proxy isDefault: true dashboards: default: k8s-cluster: json: | # 这里放你自己的 Dashboard JSON 内容参数说明additionalDataSources是 Chart 提供的扩展字段它会把数据源自动写进 Grafana 配置dashboards下面的配置会把 JSON 内容挂载进容器Grafana 启动时扫描并导入。这样做的好处是数据源和面板都变成代码环境迁移时只需要重新应用同一份 YAML。4.4 导入社区 Dashboard一个 ID 省三天工作量自己从零画监控面板效率太低社区已经有非常成熟的现成 Dashboard。Grafana 官方社区里有大量针对 Kubernetes 和节点监控的面板导入方式很简单Dashboards → Import → 输入 Dashboard ID → Load。推荐几个经过大量生产环境验证的面板 ID面板 ID监控对象适用场景315Node Exporter 节点指标看 CPU、内存、磁盘、网络的基础面板8919Kubernetes 集群监控集群视角的 Pod、容器、节点总览1860Node Exporter 全量指标需要深度排查节点问题时用导入后如果某些图显示 No Data大概率是面板里的 PromQL 查询用了固定 job 名和你环境里的标签不一致。这时候要回到 Prometheus 的 Targets 页面看实际的job和instance标签手动改面板查询里的job...部分即可。5. 避坑K8s 上跑 Prometheus 与 Grafana 的五个高频问题5.1 现象Prometheus Pod 反复重启状态停在 CrashLoopBackOff明明 Helm 安装没有报错Pod 却一直重启。看日志发现是存储目录权限问题或者是内存超限被杀。前者常见于自定义了storageSpec但没有给 PVC 正确的 fsGroup后者常见于只设置了 limits 却没给 requests导致调度时内存评估失真。解决分两步走第一给 Prometheus 的 StatefulSet 加securityContext.fsGroup让运行用户对 PVC 有写权限第二检查resources配置把 requests 和 limits 都显式设上避免 OOM 后无限重启。5.2 现象Grafana 面板全是 No Data但数据源测试是通的数据源能连通说明网络没问题图没数据问题出在查询层面。最常见的原因是面板里的 PromQL 用了旧版的标签名比如把node_cpu_seconds_total写成node_cpu或者 job 名不匹配。另一个隐蔽原因是 Grafana 的时区设置不对看起来“没有数据”其实是时间范围选到了没有数据的未来时段。排查路径先到 Prometheus 的 Graph 页面里手工执行同样的 PromQL确认有数据再回到 Grafana 的 Explore 页面查询看返回的时间序列标签最后检查面板变量里的job下拉值是否匹配你的集群标签。5.3 现象监控系统比业务系统还吃资源这是最容易被忽视的“隐形成本”node-exporter 是 DaemonSet每个节点都有一份kube-state-metrics 要监听集群全部资源Prometheus 本身还要把抓到的数据做索引和压缩。小规模集群导出的资源可能占掉 10% 的总内存。我一般建议三个收敛动作第一把全局scrape_interval从默认改到 30s 甚至 60s很多指标不需要 15s 粒度第二用relabel_configs过滤不需要抓取的 Pod比如只保留带prometheus.io/scrapetrue注解的目标第三给 Prometheus 设置合理的内存 limits宁可牺牲一点缓存命中率也不能让它把节点内存吃满。5.4 现象重启后历史监控图变成空白Prometheus 的时序数据写在本地磁盘如果用的是emptyDir存储Pod 被重新调度后数据就没了。这不是“坏”了而是存储没配 PVC。在测试环境里图方便没关系一旦你对着空白的图排查历史问题就知道什么叫后悔药没处买。解决给 Prometheus 配上volumeClaimTemplate同时确认 PVC 的回收策略是Retain。另外如果有 HA 需求单副本的 Prometheus 本身就有单点风险数据持久化只是第一步。5.5 现象ServiceMonitor 建了但 Targets 里没有对应目标ServiceMonitor 是让 Prometheus 自动发现抓取目标的关键但很多人创建后等半天 Targets 里还是空的。原因基本是标签选择器对不上ServiceMonitor 的selector匹配的是 Service 的标签而不是 Pod 的标签或者namespaceSelector没有选中目标 Service 所在的命名空间。# 一段可复制的 ServiceMonitor 示例 apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: example-app namespace: monitoring spec: selector: matchLabels: app: example-app # 匹配 Service 的 labels namespaceSelector: matchNames: - default # Service 所在命名空间 endpoints: - port: metrics # Service 端口名必须和 Service 定义一致 interval: 30s这段配置的核心是port字段它对应 Service 里定义的端口名不是数字端口。写错这个字段Targets 里会一直显示Http discovery error。遇到这类问题先用kubectl get svc -n default --show-labels确认标签和端口名再反查 ServiceMonitor 的 selector。6. 验证监控系统真的可用从 Targets 清单到告警联调安装完成不等于监控完成我习惯用三件事验证这套系统“真的能用”。第一件事回到 Prometheus 的Status → Targets页面清点目标数量。一个正常的集群至少应该看到三类目标kubernetes-nodes节点指标、kubernetes-pods带采集注解的 Pod、kubernetes-service-endpointsServiceMonitor 生成的目标。任意一类为空都说明服务发现链路有断点。第二件事在 Grafana 的 Explore 页面手动执行一条 PromQL验证数据闭环。比如查节点 CPU 使用率100 - (avg by (instance) (rate(node_cpu_seconds_total{modeidle}[5m])) * 100)如果这条查询能输出曲线说明采集、存储、查询、展示全部打通。第三件事配置一条最简单的告警规则验证 Alertmanager 链路。在 Prometheus 的规则里加一条“节点内存使用率超过 90% 持续 5 分钟”的告警然后故意压一个测试节点看告警能不能到达你的通知渠道。最后一个习惯每次改动监控配置前用helm template渲染出完整 YAML 检查一遍再helm upgrade应用。监控系统是运维的眼睛但它自己出问题时排障成本最高。这套方案我用下来的感受是Prometheus 和 Grafana 的组合在 Kubernetes 里不是“能跑”的问题而是“能不能稳定地跑、出问题时能不能快速定位”。提前把存储、权限、资源边界设好后面能省掉大量半夜救火的精力。希望帮到你。提示文中涉及的面板 ID 和 Chart 名称来自社区公开资料实际部署时以你所用版本的官方文档为准。资源大小和保留时长的数值均需结合集群规模调整先小后大观察内存曲线再扩容。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑