news 2026/10/14 7:18:50

Kubernetes集群监控实战:kube-prometheus-stack部署与告警配置指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Kubernetes集群监控实战:kube-prometheus-stack部署与告警配置指南

给 Kubernetes 集群加监控,我最早用的是比较笨的办法:手动写 Prometheus 配置文件,维护一堆 job_name 和服务发现列表。直到集群规模变大,我才意识到在 K8s 里做监控,核心难点根本不是 Prometheus 本身的部署,而是如何让采集目标跟着业务的创建和删除自动变化。这次完整走了一遍 k8s 集群部署 Prometheus 和 Grafana 的流程,从选型到落地再到排坑,我把它整理成一份带注释的检查单,给正准备给集群配监控的同学做一个参考。

先把适用范围说清楚。如果你手里的是一个正在运行业务的生产集群,需要尽快看到节点、Pod、容器的核心指标面板,那这篇文章可以直接照着做;如果你是想自己手动把每个 YAML 都写一遍,那这套方案可能太省事了,但我会把原理拆出来,你看了也能理解背后发生了什么。

1. 部署前的规划:版本、资源与方案选型

1.1 为什么优先选 kube-prometheus-stack

先交代一个背景问题:在 Kubernetes 集群里,Pod 是随时可能漂移、重建的,节点扩容缩容也很常见。如果你还按传统思维去“固定写”采集对象,那维护成本会非常难受。每次服务有变动,都得改配置、重启进程,这种模式放在云原生环境里根本不现实。所以云原生监控第一原则,是让采集配置动态化。

Prometheus 本身支持基于 Kubernetes API 的服务发现,这能让它抓到一部分资源。但真正把“动态化”做得最彻底的,是 Prometheus Operator 这套机制。它引入了一组 CRD,包括 Prometheus、ServiceMonitor、PodMonitor、AlertmanagerConfig、PrometheusRule 等等。你把采集配置、告警规则都描述成 K8s 对象,由 Operator 去翻译成 Prometheus 实际的配置文件并热加载。配置管理变成声明式,整个链路都在用 K8s 自己的方式去描述监控。

为了不重复造轮子,这次部署我直接选择了 kube-prometheus-stack。它把所有监控组件打成一个 Helm Chart,开箱自带 Prometheus、Grafana、Alertmanager、kube-state-metrics、node-exporter,还有一堆针对 Kubernetes 的推荐面板和告警规则。你不用再分开去安装五个组件然后一个个拼配置。

我把几种部署方式的对比放在下面:

方案组件数量动态采集推荐适用场景维护成本
kube-prometheus-stack全家桶开箱自带绝大多数团队,特别是刚接入监控时低
单独部署 Prometheus Operator,手动创建 CRD只有 Operator,其他资源自己定义同样支持已有成熟规范,不想被包一层中
手写 Prometheus 配置 + 手动服务发现Prometheus 单组件需要自己维护学习、临时测试、没有规则约束的场合高

按我实测下来的经验,哪怕后面要深度定制,也建议先用 kube-prometheus-stack 跑起来,再逐步调整。它的默认配置本身也接近生产可用的水平,尤其是采集 kube-apiserver、kubelet 这类核心指标的逻辑都是现成的,不需要自己去猜 endpoint 路径。

1.2 版本、资源与存储的取舍

部署前必须先做三件事:确认 Kubernetes 集群版本、预留配额、想清楚存储。

版本兼容这一点不细看很容易埋雷。Helm Chart 版本一直在更新,每个版本都有它测试过的 Kubernetes 版本范围。部署前照下面的思路确认一遍即可:

  • 去 Helm 仓库查一下当前 Chart 版本对应支持的 K8s 版本区间;
  • 对比集群版本,如果偏差太远,退回一个更匹配的 Chart 版本;
  • 同时检查 kubelet、kube-apiserver 的版本,因为 node-exporter 和 kube-state-metrics 要跟这些组件通信。

资源方面,我给一套适合刚起步小型集群的最低参考:Prometheus 单副本 2 核 4G,Grafana 1 核 1G,Alertmanager 分配 500M 内存,node-exporter 和 kube-state-metrics 各给 200M 左右的内存。加起来大概需要 6 核和 6G 内存的余量。注意这是最低余量,节点本身不多的话,得先把这些配额算在节点容量计划内,不然一装完可能半个集群的闲置容量都被吃掉了。

存储比较容易被忽略。默认情况下,Chart 里的 Prometheus 和 Grafana 都没开启持久化,Pod 重建以后历史数据就直接没了。生产环境我建议至少给 Prometheus 配一个 50G 以上的持久卷,保留时间按 15 天算,后面不够再加。Grafana 的持久化主要是为了保住你自己导入的面板和配置,容量 5G 到 10G 就完全足够了。

2. 核心组件拆解:一套监控系统到底是什么结构

很多新手装完以后看着 Pod 列表里一堆名字,不知道到底是干嘛的。这里先拆一遍,后面排查问题的时候你才知道去哪个 Pod 找日志。

2.1 Prometheus Operator 与 CRD 的关系

先说 Operator。它安装在集群里以后,就是一个常驻的控制器 Pod。它监控着集群里这几类关键对象:

  • Prometheus:定义一个 Prometheus 实例本身,包括副本数、资源、存储、告警全局配置;
  • ServiceMonitor:声明“我要采集哪些 Service 暴露的指标”;
  • PodMonitor:声明“我要采集哪些 Pod 直接暴露的指标”;
  • PrometheusRule:声明告警规则;
  • AlertmanagerConfig:声明 Alertmanager 的通知路由与接收者。

你创建了一个 ServiceMonitor 之后,Operator 会在后台自动把它转换成 Prometheus 的 scrape_config 配置,并且用热加载的方式让 Prometheus 自动刷新。整个过程不需要人工进入 Prometheus 容器里去改文件,也不用重启。这就解决了云原生环境里最头疼的动态发现痛点。

还有一个观念层面的变化:你不再把监控配置当成一组零散的 YAML 文件,而是当成 K8s 资源来管理。哪套环境需要不同策略,扔一组不同的 CR 就行。因为是标准的 K8s 对象,权限、审计、GitOps 流程都能直接复用。

2.2 ServiceMonitor、kube-state-metrics、node-exporter 各自干什么

这里按职责分一下:

ServiceMonitor 是采集目标的描述。以后你要“加一个新的采集对象”,做的不是改 Prometheus 配置,而是创建一个 ServiceMonitor。它通过 label 选择器去关联某个 Service,再从 Service 的某个端口去拉取 /metrics。标签选择器这套机制很符合 K8s 用户的习惯,定义完以后配置即代码,也方便走 GitOps 流程。

node-exporter 是部署在每个节点上的采集 DaemonSet,暴露系统指标。节点 CPU、内存、磁盘、网卡流量都从它来。只要集群节点还在,这个组件就应该在运行,所以它的 Pod 应该遍布所有节点。

kube-state-metrics 跟 node-exporter 恰好互补。node-exporter 告诉你系统层发生了什么,kube-state-metrics 则把 K8s 对象的状态变成指标,比如 Deployment 的期望副本数、Pod 的重启次数、容器有无资源配额、PVC、Ingress、Service 等这些 K8s 层面的数据。业务稳定性分析大多离不开它。

三者汇总来看,整个链路可以这样理解:应用或系统暴露指标,ServiceMonitor 或 PodMonitor 描述采集目标,Prometheus 定期抓取并存储,Grafana 查询并展示。

2.3 Grafana 与 Alertmanager 在链路里的位置

Grafana 在数据链路中实际上是一个“消费者”。它自己既不采集指标,也不存储指标,只是把 Prometheus 当数据源,通过查询语句把指标画成面板。所以在部署时,要清楚 Grafana 和 Prometheus 之间是通过网络访问 Prometheus 的 Service 域名来通信的。它报错的时候经常是数据源连接失败,问题往往不在 Grafana 本身,而在网络、Service 地址或者权限上。

Alertmanager 负责把 Prometheus 里告警规则的结果分发出去。Prometheus 负责评估规则,命中了就把告警推给 Alertmanager,Alertmanager 再按定义好的路由规则发给不同接收者,比如邮件、通用 Webhook、内部即时通讯机器人。这个链路看起来简短,配置时候却容易在路由和接收者上绕晕,后面我会用实际例子演示。

3. 实操部署全流程:从 Helm 到仪表盘

前面把原理讲得差不多了,下面就是真正能照着操作的步骤。这次我以 kube-prometheus-stack 为例,假设你已经有一个能正常使用的 Kubernetes 集群。

3.1 准备工作:Helm 仓库与命名空间

先确认 Helm 已经装好。然后添加 Prometheus 社区的 Chart 仓库,并更新索引。

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update

这次部署我会把所有监控相关的对象放进独立命名空间,避免跟业务命名空间混在一起:

kubectl create namespace monitoring

命名空间取名为 monitoring 是约定俗成的做法,后面接各类权限和网络策略时,别人一眼就能看出这是监控专用环境。

3.2 编写 values.yaml

我不建议直接裸安装,因为默认配置有两处不适合生产:一是不开持久化,二是 Grafana 和 Alertmanager 的服务类型默认是 ClusterIP,不方便访问。为了便于调整,创建一个 values 文件,按需覆盖配置。

我这次用的 values.yaml 核心内容如下,省略的部分保持默认:

grafana: enabled: true adminPassword: "你的强密码" service: type: NodePort nodePort: 32000 persistence: enabled: true storageClassName: standard accessModes: ["ReadWriteOnce"] size: 10Gi prometheus: prometheusSpec: retention: 15d storageSpec: volumeClaimTemplate: spec: storageClassName: standard accessModes: ["ReadWriteOnce"] resources: requests: storage: 50Gi resources: requests: cpu: 500m memory: 2Gi limits: cpu: 2 memory: 4Gi alertmanager: enabled: true service: type: ClusterIP

说一下几个关键配置的选择原因:

  • retention 设置 15 天,这个数值是监控数据量的直接决定因素。如果集群规模很大,每天新增指标量大,15 天 50G 可能不够,后面要根据查询性能和磁盘情况进行调整。
  • service.type 改成 NodePort 是为了在没有 Ingress 的环境里也能快速打开界面。如果集群已经有 Ingress 控制器,我更推荐用 Ingress,而不是直接暴露 NodePort。
  • storageClassName 必须填集群里真实存在的存储类。管理平台通常默认带一个,自建的可以用 local-path 或 NFS,先确认它存在再写。

之后执行安装命令:

helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack \ --namespace monitoring \ -f values.yaml

等待几分钟,等镜像拉完,Pod 状态稳定。

3.3 验证核心服务状态

安装完成后先看一遍 Pod 状态:

kubectl get pods -n monitoring

正常情况下,你应该能看到几类 Pod:Prometheus Operator、Prometheus、Grafana、Alertmanager,以及分布在各节点的 node-exporter DaemonSet Pod。

如果某个 Pod 一直 Pending,先看事件。最常见的原因是节点资源不够,或者 PVC 没有可用的存储类。这两个问题后面我会专门讲。

再检查一下关键对象有没有创建出来:

kubectl get svc -n monitoring kubectl get prometheus -n monitoring kubectl get servicemonitor -n monitoring kubectl get prometheusrule -n monitoring

如果这些对象都存在且状态正常,说明 Operator 已经把 CRD 转换后的配置同步到 Prometheus 实例了。

3.4 打开 Grafana 看第一张面板

Grafana 用 NodePort 暴露后,直接访问节点 IP 加端口就行。地址通常是http://节点IP:32000,默认管理员账号是 admin,密码就是你在 values.yaml 里设置的 adminPassword。

登录以后先做两件事。

第一步,确认数据源。如果 kube-prometheus-stack 部署完整,数据源一般会被自动配置,你可以在左侧菜单进入“数据源”看看 Prometheus 的 URL 是不是http://prometheus-operated:9090。如果不是自动配置,手动添加时这个地址大概率就是要填的。

这里有个容易看懵的点:为什么不是 localhost 而是 prometheus-operated?因为 Grafana 的 Pod 和 Prometheus 的 Pod 在同一个集群,不同容器组里,通信靠的是 Service 域名,而不是本机地址。填 localhost 是绝对连不上的。

第二步,导入仪表盘。kube-prometheus-stack 自带一批 Kubernetes 推荐面板,登录以后通常能看到“Kubernetes / Compute Resources / Node”和“Kubernetes / Networking / Cluster”之类。直接点开就行,不需要单独导入 JSON。

如果你想导入更细的面板,可以从社区仪表盘库找“Kubernetes”相关模板,导入的时候数据源选择 Prometheus 即可。

实际面板开出来以后,先看“Kubernetes / Compute Resources / Node”这几张图。节点 CPU、内存、网络都是带多维度的,切换节点、命名空间都可以在面板顶部的下拉框操作。这就是 Prometheus 多维数据模型带来的能力,也是 Grafana 模板偏爱它的原因。

4. 配置业务监控与告警规则

集群自身的监控做完以后,最关键的一步是把业务应用的指标接进来。很多人装了监控之后觉得“没内容看”,根本原因就在这里:只采集了系统指标,没有接业务指标。

4.1 自定义 ServiceMonitor 接入业务指标

假设我有个业务应用叫 my-app,它有一个 Service 暴露了 /metrics 接口,端口名称设置为 metrics。要对接到 Prometheus,我创建下面这个 ServiceMonitor:

apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: my-app-monitor namespace: my-app-ns spec: selector: matchLabels: app: my-app endpoints: - port: metrics interval: 30s

创建之后等一会,进入 Prometheus 界面打开 Targets 页面,你会发现 my-app 这个采集目标已经出现在列表里。如果没出现,第一件事是检查 ServiceMonitor 的 label 选择器和 Service 的 label 是否匹配,第二件事是检查命名空间。

这里有个细节值得强调:ServiceMonitor 和 Service 的命名空间关系。ServiceMonitor 作用于哪些命名空间,取决于 namespaceSelector。如果不写,默认只作用于它自己所在的命名空间;如果写成matchNames: ["my-app-ns"],表示从这个命名空间找 Service。

还有一个容易踩坑的地方:如果 Prometheus 实例的 spec 里设置了 serviceMonitorSelector,那么只会处理带有对应 label 的 ServiceMonitor。多团队隔离时这个开关很实用,但它也会让“明明创建了 ServiceMonitor 但 Prometheus 不采集”的问题出现。查法是把 Prometheus 对象拉出来:

kubectl get prometheus -n monitoring -o yaml

看看 spec.serviceMonitorSelector 和 spec.serviceMonitorNamespaceSelector,再对照你的 ServiceMonitor 标签调整。

业务指标接进来之后,通常查的是应用自己暴露的指标。比如你的应用有http_requests_total这样的计数指标,可以这样算 QPS:

sum(rate(http_requests_total[5m])) by (path)

4.2 通过 PrometheusRule 添加告警

告警规则同样是声明式的,不需要进容器改文件。下面是一个自定义 PrometheusRule 示例,含义是当节点内存使用率超过 85% 时触发告警:

apiVersion: monitoring.coreos.com/v1 kind: PrometheusRule metadata: name: node-memory-rule namespace: monitoring spec: groups: - name: node-memory.rules rules: - alert: NodeHighMemoryUsage expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 85 for: 5m labels: severity: warning annotations: summary: "节点 {{ $labels.instance }} 内存使用率超过 85%"

说明几个细节:

  • for: 5m表示持续 5 分钟才触发。这是为了避免瞬时抖动导致告警轰炸。
  • expr 里表达式的写法是核心。内存使用率可以理解成“总量减去可用量,再除以总量”,所以写成1 - 可用量/总量,再乘 100 转成百分比。
  • 告警规则建在 monitoring 命名空间,不影响它计算,因为 Prometheus 查询的是自己的数据库,指标没有命名空间隔离的说法。

创建以后,到 Prometheus 的 Alerts 页面看到这条规则就对了。想验证告警链路通没通,可以临时把阈值调到很低,观察告警状态变化。

4.3 告警通知渠道配置

Alertmanager 的通知配置,在 kube-prometheus-stack 新版本里可以通过 AlertmanagerConfig 这类 CRD 声明。这里给一个通用 Webhook 接收器的示例:

apiVersion: monitoring.coreos.com/v1alpha1 kind: AlertmanagerConfig metadata: name: default-webhook namespace: monitoring spec: route: receiver: "webhook" continue: true receivers: - name: "webhook" webhookConfigs: - url: "http://xx-webhook-service.你的命名空间.svc:8000/hook" sendResolved: true

创建成功后,需要让 Alertmanager 能发现这个配置。默认情况下,Alertmanager 按照 label 选择器过滤 AlertmanagerConfig,selector 为空表示选择所有,通常不需要额外处理。如果集群里设置了选择器,新建的配置就要挂上对应 label。

Webhook 是所有渠道里最容易接的。内部如果有现成的即时通讯机器人,把 URL 配上,告警消息就能直接发到群里。如果你还没有收告警的地方,建议先搭一个最简单的 Webhook 接收服务,验证链路能通了再去接正式渠道,不要把一堆配置一次性都堆上去。

5. 常见问题与排查经验

部署和使用的过程里,总会踩到几个比较固定的坑。我按出现频率从高到低列一下。

5.1 资源不足导致 Pod 反复重启

症状是kubectl get pods看到很多监控 Pod 处于 Pending 或 CrashLoopBackOff,伴随 OOMKilled。最常见原因是默认资源配额被设置得比较大,尤其是多副本 Prometheus 和 Operator,小集群根本没那么多资源。

解决办法是调低配额,或者只开单副本。调整后用 upgrade 让配置生效:

helm upgrade kube-prometheus-stack prometheus-community/kube-prometheus-stack -n monitoring -f values.yaml

如果是纯测试环境,甚至可以把 Prometheus 的资源 limits 全部去掉,只留 requests。但生产环境千万别这么干,没有 limit 的 Pod 可能把节点拖垮。

5.2 采集目标显示 Down,怎么查

Prometheus Targets 列表里某个目标红了,按这个顺序排查:

1. 确认 ServiceMonitor 的 selector 匹配到了正确的 Service。 2. 确认 Service 的端口名和 ServiceMonitor 里 endpoints 指定的端口名一致。 3. 确认 /metrics 接口能不能访问,临时用 kubectl port-forward 到 Service 直接验证。 4. 如果返回 401 或 403,说明可能有网络策略或者鉴权拦截。

大部分“明明配了 ServiceMonitor 却采集不了”的问题,都出在前两类:标签没匹配上,端口名不叫 metrics。这里要特别强调:ServiceMonitor 的 endpoints 里指定的是端口的名字,不是端口号。如果 Service 里端口名写错,即使 ServiceMonitor 匹配到了 Service,也会因为找不到端口而失败。

5.3 监控数据一重启就丢

这个坑我最早部署时遇到过。当时没有配持久存储,Prometheus 的 Pod 被调度到别的节点,一重启所有历史数据全没了,面板长期空白。

解决办法就是两个动作:一是在 values.yaml 里给 Prometheus 配 volumeClaimTemplate,二是在存储类存在的前提下确认 PVC 创建成功。Grafana 同理,开启持久化以后,导入的面板不会因为 Pod 重建就回到出厂状态。

如果想更稳,注意 Prometheus 的存储必须是 ReadWriteOnce,它不支持多节点共享读写。所以别拿一个 NFS 存储类强行给多个 Prometheus 副本共享,否则会出现性能问题,甚至数据损坏。

5.4 权限相关错误

kube-state-metrics 和 Operator 要读取集群对象,它们的 ServiceAccount 如果没有足够 RBAC 权限,日志里大概率会刷权限禁止的报错。kube-prometheus-stack 通常已经把常用 ClusterRole 配好,出现这类问题更多是因为你手动创建了自定义 Prometheus,或者高度自定义组件,导致 ServiceAccount 权限不完全匹配。

排查思路是:先看具体报错,是资源被禁止还是 apiGroup 不支持;再到角色规则里补对应的 apiGroups、resources、verbs。比如要读节点指标,就需要在 ClusterRole 里包含 nodes 的 list 和 watch 权限。改完 RBAC 等待一段时间让规则生效,必要时重启相应 Pod。

这次部署之后我最深的体会是,监控系统从“能装好”到“能用起来”,中间差的是对指标和数据模型的理解。装好一套 Prometheus 和 Grafana 其实半天就能完成,但让团队真正习惯用监控面板看数据,把告警规则打磨到不吵人又不错报,需要持续迭代。

写这篇记录的时候,我把部署过程中值得记住的细节都放进了对应章节,你可以把它当成一份带注释的检查单。后续如果有时间,我准备再整理一篇关于监控数据量估算和面板优化的记录,欢迎一起交流踩坑经验。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/14 7:18:47

Lombok日志脱敏:@ToString.Exclude与Include控制toString输出

刚开始接触 Lombok 的人,往往只记住了Data能省掉 Getter/Setter,却忽略了它默认生成的toString()也会把对象输出成一个“全量快照”。我在一次联调环境的问题排查里,就看到过这样的日志:整个用户对象被logger.info("创建用户…

作者头像 李华
网站建设 2026/10/14 7:18:37

Python在线学习平台开发:从Django选型到视频防盗链

很多人觉得做一个python网络课程在线学习平台,最费劲的是写课程内容、录视频、找老师。我最初也这么想,可真把一个平台从零搭起来之后才发现,真正的工程量藏在那些用户根本看不见的地方:课程怎么分类、视频怎么防爬、播放进度怎么…

作者头像 李华
网站建设 2026/10/14 7:18:22

从零构建语种识别器:字符n-gram与朴素贝叶斯实战

接手一个多语客服工单分类需求的时候,我才意识到“语种识别”这个看似不起眼的小功能,其实是很多NLP工程链路的入口。拿一段文本自动判断它是中文、英文还是日文,听起来很基础,但真正要自己训练一个语种识别器,再通过F…

作者头像 李华
网站建设 2026/10/14 7:18:22

Fiddler免安装版抓包实战:配置、HTTPS解密与避坑指南

简介:Fiddler中文免安装版是一款面向Web开发、测试与安全评估人员的网络封包分析工具,基于Telerik出品的Fiddler 4.6汉化而来,无需安装即可直接运行,适合需要快速抓取HTTP/HTTPS流量、排查接口异常或分析页面加载性能的初中级开发…

作者头像 李华
网站建设 2026/10/14 7:18:15

在哪里购买SSL证书?常见渠道与申请方式说明

SSL证书主要有三种购买渠道——CA机构官网、云服务商平台和专业证书服务商。如果需要购买SSL证书,推荐优先考虑专业SSL证书服务商。这类平台的优势在于:集成多个CA品牌便于对比选型、提供免费安装部署服务、支持中文技术沟通。一、SSL证书的三类购买渠道…

作者头像 李华
网站建设 2026/10/14 7:18:11

AI存储底座为什么是HDD?从容量成本到工程实践

最近在给某跨平台系统的存储底座做容量评估,规划报表里那一串数字从TB一路涨到PB,最后不得不按EB量级去预留扩展空间。这种体验放在几年前很难想象,但AI存储进入PB/EB时代之后,一个很有意思的现象出现了:真正扛起海量数…

作者头像 李华