花开月下机器人 Prometheus 监控 K8s 集群(集群内部部署)
这是云原生监控的经典场景。核心思路:用 kube-prometheus-stack(Helm Chart)一把部署 Prometheus + Grafana + AlertManager + node-exporter + kube-state-metrics,覆盖集群节点、Pod、Deployment、Service 等全维度监控。下面从架构到落地完整讲透。
---
一、监控架构总览
┌─────────────────────────────────────────────────────────┐
│ K8s 集群内部 │
│ │
│ ┌──────────┐ ┌──────────────────┐ ┌─────────────┐ │
│ │ Grafana │◄──│ Prometheus │──►│ AlertManager│ │
│ │ (可视化) │ │ (时序数据库+采集) │ │ (告警路由) │ │
│ └──────────┘ └───────┬──────────┘ └─────────────┘ │
│ │ │
│ ┌────────────────┼────────────────┐ │
│ │ │ │ │
│ ┌────▼─────┐ ┌─────▼──────┐ ┌─────▼──────┐ │
│ │kube-state│ │node-exporter│ │kubelet/cAdvisor│ │
│ │-metrics │ │(DaemonSet) │ │(内置) │ │
│ │(集群状态) │ │(节点硬件) │ │(容器指标) │ │
│ └──────────┘ └────────────┘ └──────────────┘ │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ API Server (Service/Pod/Deployment 等对象状态) │ │
│ └──────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
| 组件 | 作用 | 部署形态 |
|------|------|----------|
| Prometheus | 采集 + 存储时序数据 | StatefulSet / Deployment |
| Grafana | 可视化看板 | Deployment |
| AlertManager | 告警路由、分组、抑制、静默 | StatefulSet |
| node-exporter | 节点级 CPU/内存/磁盘/网络 | DaemonSet(每节点一个) |
| kube-state-metrics | 集群对象状态(Deployment 副本数、Pod 状态等) | Deployment |
| kubelet + cAdvisor | 容器级 CPU/内存/网络/文件系统 | K8s 内置,无需额外部署 |
---
二、快速部署(kube-prometheus-stack Helm Chart)
2.1 前置条件
确认 Helm 3 已安装
helm version --short
v3.x.x
确认有可用的 StorageClass(持久化用)
kubectl get storageclass
如果没有,用 local-path-provisioner 或集群自带的
2.2 添加仓库 + 部署
添加 Prometheus 社区 Helm 仓库
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
创建监控命名空间
kubectl create namespace monitoring
部署 kube-prometheus-stack
helm install kube-prometheus-stack \
prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--version 65.x.x \
--set prometheus.prometheusSpec.retention=15d \
--set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.storageClassName=standard \
--set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.resources.requests.storage=50Gi \
--set grafana.adminPassword='your-secure-password' \
--set grafana.persistence.enabled=true \
--set grafana.persistence.size=10Gi
2.3 验证部署
查看 Pod 状态
kubectl get pods -n monitoring
NAME READY
alertmanager-kube-prometheus-stack-alertmanager-0 2/2
kube-prometheus-stack-grafana-xxxxx 3/3
kube-prometheus-stack-kube-state-metrics-xxxxx 1/1
kube-prometheus-stack-operator-xxxxx 1/1
kube-prometheus-stack-prometheus-node-exporter-xxxxx 1/1 (每个节点一个)
prometheus-kube-prometheus-stack-prometheus-0 2/2
查看 Service
kubectl get svc -n monitoring
kube-prometheus-stack-prometheus ClusterIP
kube-prometheus-stack-grafana ClusterIP
kube-prometheus-stack-alertmanager ClusterIP
查看 ServiceMonitor(自动创建的采集规则)
kubectl get servicemonitor -n monitoring
NAME AGE
kube-prometheus-stack-alertmanager
kube-prometheus-stack-apiserver
kube-prometheus-stack-coredns
kube-prometheus-stack-kube-controller-manager
kube-prometheus-stack-kube-etcd
kube-prometheus-stack-kube-proxy
kube-prometheus-stack-kube-scheduler
kube-prometheus-stack-kubelet
kube-prometheus-stack-node-exporter
kube-prometheus-stack-prometheus
kube-prometheus-stack 开箱即配好了 10+ 个 ServiceMonitor,覆盖 API Server、kubelet、etcd、coredns、node-exporter 等——装完即有数据,不需要手动配采集规则。
2.4 访问 Grafana
端口转发(临时访问)
kubectl port-forward svc/kube-prometheus-stack-grafana 3000:80 -n monitoring
浏览器打开 http://localhost:3000
默认账号: admin 密码: 你上面设的 your-secure-password
Grafana 自带 20+ 个预置 Dashboard,包括:
集群总览(Cluster Overview)
节点详情(Node Exporter / Nodes)
Pod 资源使用(Pod Usage)
API Server 性能
etcd 监控
CoreDNS
---
三、核心监控指标体系
3.1 节点级(node-exporter)
| 指标 | PromQL | 含义 |
|------|--------|------|
| CPU 使用率 | 100 - (avg(rate(nodecpuseconds_total{mode="idle"}[5m])) by (instance) * 100) | 节点 CPU 占用 |
| 内存使用率 | (1 - nodememoryMemAvailablebytes / nodememoryMemTotalbytes) * 100 | 可用内存占比 |
| 磁盘使用率 | (1 - nodefilesystemavailbytes / nodefilesystemsizebytes) * 100 | 文件系统占用 |
| 磁盘 IO | rate(nodediskiotimeseconds_total[5m]) | IO 繁忙度 |
| 网络流量 | rate(nodenetworkreceivebytestotal[5m]) | 入站带宽 |
| 节点在线 | up{job="node-exporter"} | 节点存活 |
3.2 容器级(kubelet/cAdvisor)
| 指标 | PromQL | 含义 |
|------|--------|------|
| Pod CPU | sum(rate(containercpuusagesecondstotal{container!=""}[5m])) by (pod) | Pod CPU 使用 |
| Pod 内存 | containermemoryworkingsetbytes{container!=""} | Pod 实际内存(含缓存) |
| Pod 磁盘读写 | rate(containerfsreadsbytestotal[5m]) | 容器文件系统 IO |
| Pod 网络收发 | rate(containernetworkreceivebytestotal[5m]) | 容器网络流量 |
| 容器重启次数 | kubepodcontainerstatusrestarts_total | 重启计数 |
| Pod 状态 | kubepodstatus_phase | Pending/Running/Failed/Succeeded |
3.3 集群对象级(kube-state-metrics)
| 指标 | PromQL | 含义 |
|------|--------|------|
| Deployment 副本数 | kubedeploymentstatus_replicas | 当前副本数 |
| 期望副本数 | kubedeploymentstatusreplicasavailable | 可用副本数 |
| Pod 不健康 | kubepodstatus_phase{phase=~"Failed\|Unknown"} | 异常 Pod |
| PVC 使用 | kubepersistentvolumeclaimstatus_phase | PVC 绑定状态 |
| Job 成功/失败 | kubejobstatussucceeded / kubejobstatusfailed | 作业结果 |
| 节点就绪 | kubenodestatus_condition{condition="Ready",status="true"} | 节点 Ready |
| HPA 状态 | kubehpastatuscurrentreplicas | 自动伸缩当前副本 |
3.4 控制面(API Server / etcd / scheduler)
| 指标 | PromQL | 含义 |
|------|--------|------|
| API 请求 QPS | sum(rate(apiserverrequesttotal[5m])) by (verb) | 按动词分类 |
| API 延迟 P99 | histogramquantile(0.99, rate(apiserverrequestdurationseconds_bucket[5m])) | 请求延迟分位 |
| etcd 提交延迟 | histogramquantile(0.99, rate(etcddiskwalfsyncdurationseconds_bucket[5m])) | WAL 刷盘延迟 |
| etcd leader | etcdserverhas_leader | 是否有 leader |
| 调度延迟 | histogramquantile(0.99, rate(schedulere2eschedulingdurationsecondsbucket[5m])) | 端到端调度耗时 |
---
四、告警规则配置
4.1 内置告警(开箱即用)
kube-prometheus-stack 自带一批 PrometheusRule,装完就有:
kubectl get prometheusrule -n monitoring
kube-prometheus-stack-general
kube-prometheus-stack-kube-apiserver
kube-prometheus-stack-kube-prometheus
kube-prometheus-stack-kubernetes-monitoring
kube-prometheus-stack-node-exporter
内置告警包括:节点 Down、Pod CrashLoopBackOff、CPU > 80%、内存 > 90%、磁盘 > 85%、API Server 不可用、etcd 无 leader 等。
4.2 自定义告警规则
custom-alerts.yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: custom-alerts
namespace: monitoring
labels:
release: kube-prometheus-stack # 必须匹配 Prometheus 的 ruleSelector
spec:
groups:
name: k8s-cluster
rules:
# 节点 CPU > 80% 持续 5 分钟
alert: NodeHighCPU
expr: |
100 - (avg(rate(nodecpuseconds_total{mode="idle"}[5m])) by (instance) * 100) > 80
for: 5m
labels:
severity: warning
annotations:
summary: "节点 {{ $labels.instance }} CPU 使用率过高"
description: "CPU 使用率 {{ $value }}% > 80%,持续 5 分钟"
# Pod 频繁重启
alert: PodCrashLooping
expr: |
increase(kubepodcontainerstatusrestarts_total[1h]) > 5
for: 2m
labels:
severity: critical
annotations:
summary: "Pod {{ $labels.pod }} 在 1 小时内重启超过 5 次"
# PVC 即将满
alert: PVCAlmostFull
expr: |
(1 - kubeletvolumestatsavailablebytes / kubeletvolumestatscapacitybytes) * 100 > 85
for: 10m
labels:
severity: warning
annotations:
summary: "PVC {{ $labels.persistentvolumeclaim }} 使用率超过 85%"
# API Server 错误率
alert: APIServerErrorRate
expr: |
sum(rate(apiserverrequesttotal{code=~"5.."}[5m]))
/ sum(rate(apiserverrequesttotal[5m])) * 100 > 5
for: 5m
labels:
severity: critical
annotations:
summary: "API Server 5xx 错误率 > 5%"
kubectl apply -f custom-alerts.yaml
4.3 告警通知(AlertManager → 钉钉/飞书/企微)
values.yaml 中配置 AlertManager
alertmanager:
config:
route:
receiver: 'dingtalk'
group_by: ['alertname', 'namespace']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
routes:
matchers: ['severity="critical"']
receiver: 'dingtalk'
group_wait: 10s
matchers: ['severity="warning"']
receiver: 'dingtalk'
receivers:
name: 'dingtalk'
webhook_configs:
url: 'https://oapi.dingtalk.com/robot/send?accesstoken=YOURTOKEN'
send_resolved: true
helm upgrade kube-prometheus-stack \
prometheus-community/kube-prometheus-stack \
-n monitoring \
-f values.yaml
---
五、监控自定义业务应用
业务 Pod 暴露 /metrics 端点(Prometheus 格式),通过 ServiceMonitor 接入:
业务应用暴露 metrics 端口
apiVersion: v1
kind: Service
metadata:
name: my-app
labels:
app: my-app
spec:
selector:
app: my-app
ports:
name: metrics
port: 8080
targetPort: 8080
---
ServiceMonitor 告诉 Prometheus 采集这个 Service
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: my-app
namespace: monitoring
labels:
release: kube-prometheus-stack # 匹配 Prometheus 的 serviceMonitorSelector
spec:
selector:
matchLabels:
app: my-app # 匹配上面的 Service label
namespaceSelector:
matchNames:
default # 业务应用所在 namespace
endpoints:
port: metrics
path: /metrics
interval: 30s
kubectl apply -f my-app-monitor.yaml
几秒后 Prometheus 就开始采集,Grafana 里可查到 myapp* 指标
---
六、生产环境加固要点
| 维度 | 配置 | 命令/参数 |
|------|------|-----------|
| 数据保留 | 15-30 天 | --set prometheusSpec.retention=15d |
| 持久化存储 | PVC 50-100Gi | storageSpec.volumeClaimTemplate |
| 远程长期存储 | 接 Thanos/VMagent | 远程写入 remote_write |
| 资源限制 | 限制 Prometheus 内存 | prometheusSpec.resources.limits.memory=4Gi |
| 高可用 | 2 副本 Prometheus | --set prometheusSpec.replicas=2 |
| 压缩旧数据 | 启用 TSDB 压缩 | 默认开启 |
| Node Exporter 容忍 | 确保覆盖所有节点 | DaemonSet + tolerations |
| 安全 | Grafana 改密码 + RBAC | grafana.rbac.create=true |
| 采集间隔 | 15-30s(默认 30s) | --set prometheusSpec.scrapeInterval=15s |
高可用部署示例
helm install kube-prometheus-stack \
prometheus-community/kube-prometheus-stack \
-n monitoring \
--set prometheus.prometheusSpec.replicas=2 \
--set alertmanager.alertmanagerSpec.replicas=2 \
--set prometheus.prometheusSpec.retention=30d \
--set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.resources.requests.storage=100Gi \
--set prometheus.prometheusSpec.resources.limits.memory=8Gi \
--set prometheus.prometheusSpec.resources.limits.cpu=4
---
七、常见问题排查
查看采集目标状态(哪些 target up/down)
kubectl port-forward svc/kube-prometheus-stack-prometheus 9090:9090 -n monitoring
浏览器 → http://localhost:9090/targets
查看 Prometheus 采集配置(最终生效的)
http://localhost:9090/config
查看某个指标是否存在
http://localhost:9090/api/v1/label/name/values
ServiceMonitor 没生效?检查 label 匹配
kubectl get prometheus -n monitoring -o yaml | grep -A5 serviceMonitorSelector
Prometheus 只选择匹配 release=kube-prometheus-stack 的 ServiceMonitor
node-exporter 没数据?检查 DaemonSet 是否调度到所有节点
kubectl get ds -n monitoring
kubectl get ds -n monitoring -o wide
Pod 级别没数据?检查 kubelet 端口
kubelet 默认在 10250 端口暴露 metrics,cAdvisor 在 10250/metrics/cadvisor
---
八、完整部署清单速查
部署步骤:
helm repo add + update
helm install kube-prometheus-stack(带持久化参数)
kubectl get pods -n monitoring(等全部 Running)
port-forward Grafana → 打开看板
kubectl apply -f custom-alerts.yaml(自定义告警)
配置 AlertManager webhook(钉钉/飞书)
业务应用加 ServiceMonitor
日常运维:
Prometheus UI → /targets 看采集状态
Prometheus UI → /alerts 看告警状态
Grafana → 看预置 Dashboard
kubectl get prometheusrule -n monitoring → 管理告警规则
kubectl get servicemonitor -n monitoring → 管理采集规则
kube-prometheus-stack 是目前 K8s 监控的事实标准——一个 Helm install 覆盖节点/容器/控制面/集群对象全维度,自带告警和看板,业务应用通过 ServiceMonitor 即插即用。生产环境加上持久化 + 高可用 + 远程长期存储(Thanos)就是完整方案。