Appearance
K8s指标监控
Kubernetes 指标监控要覆盖节点、容器、Pod、控制平面、etcd、Ingress/Gateway 和业务应用。单独看 kubectl top 只能看到现场资源快照,长期趋势、告警和看板还是要接 Prometheus。K8s 环境里更常见的做法是用 Prometheus Operator 管理 Prometheus、Alertmanager、规则和抓取对象。
一、K8s 里指标从哪里来
常见指标来源:
| 来源 | 典型指标 | 用途 |
|---|---|---|
| Node Exporter | 节点 CPU、内存、磁盘、网络 | 主机层资源 |
| kubelet / cAdvisor | 容器 CPU、内存、文件系统 | 容器层资源 |
| kube-state-metrics | Deployment、Pod、PVC、Job 等资源状态 | K8s 对象状态 |
| API Server | 请求量、延迟、错误 | 控制面健康 |
| etcd | leader、DB 大小、fsync、请求延迟 | 集群存储健康 |
| Ingress / Gateway | QPS、状态码、延迟 | 入口流量 |
应用 /metrics | 业务请求、错误率、耗时 | 服务运行状态 |
节点 CPU 高和 Pod CPU 高不是一回事。节点指标说明宿主机资源情况,Pod 指标说明容器资源情况,kube-state-metrics 说明资源对象是否处在期望状态。排查 Pod Pending、Deployment 副本不足、PVC 绑定失败这类问题时,kube-state-metrics 很有用。
二、Prometheus Operator
Prometheus Operator 把 Prometheus 相关配置变成 Kubernetes CRD。手工改 prometheus.yml 的方式,在 K8s 里会变得很难维护;Operator 让抓取配置、告警规则、Alertmanager 配置都能用 YAML 声明。
常见对象:
| 对象 | 作用 |
|---|---|
Prometheus | 定义 Prometheus 实例 |
Alertmanager | 定义 Alertmanager 实例 |
ServiceMonitor | 通过 Service 发现抓取目标 |
PodMonitor | 直接通过 Pod 发现抓取目标 |
PrometheusRule | 告警规则和记录规则 |
AlertmanagerConfig | 告警路由、接收器、静默相关配置 |
很多环境直接装 kube-prometheus-stack,它把 Prometheus Operator、Prometheus、Alertmanager、Grafana、node-exporter、kube-state-metrics 和常见规则一起装好。实验环境可以这样起步;生产里还是要回头看每个组件的资源、保留周期、规则和权限。
三、ServiceMonitor
ServiceMonitor 通过 Service 发现目标。它匹配的是 Service 标签,不是 Pod 标签——这个容易看错。
示例应用 Service:
yaml
apiVersion: v1
kind: Service
metadata:
name: demo-app
namespace: demo
labels:
app: demo-app
spec:
selector:
app: demo-app
ports:
- name: metrics
port: 9100
targetPort: metricsServiceMonitor:
yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: demo-app
namespace: monitoring
labels:
release: kube-prometheus-stack
spec:
namespaceSelector:
matchNames:
- demo
selector:
matchLabels:
app: demo-app # 匹配 Service 的 labels
endpoints:
- port: metrics
path: /metrics
interval: 30srelease: kube-prometheus-stack 这类标签要和 Prometheus 实例的 selector 对上。ServiceMonitor 创建了但 Targets 里没有,多半是 selector 没匹配、namespace 不在范围内、port 名写错,或者 Prometheus 实例没有选择这条 ServiceMonitor。
四、PodMonitor
PodMonitor 直接匹配 Pod,不依赖 Service。适合没有稳定 Service、或者每个 Pod 都需要单独抓取的场景。
yaml
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: demo-pods
namespace: monitoring
labels:
release: kube-prometheus-stack
spec:
namespaceSelector:
matchNames:
- demo
selector:
matchLabels:
app: demo-app
podMetricsEndpoints:
- port: metrics
path: /metrics
interval: 30sPodMonitor 更直接,但服务变动时也更容易暴露出很多短生命周期 target。普通业务服务通常先用 ServiceMonitor,除非确实需要绕开 Service。
五、PrometheusRule
PrometheusRule 用来声明告警规则和记录规则。
yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: pod-alerts
namespace: monitoring
labels:
release: kube-prometheus-stack
spec:
groups:
- name: pod.rules
rules:
- alert: PodRestartingTooOften
expr: increase(kube_pod_container_status_restarts_total[15m]) > 3
for: 5m
labels:
severity: warning
annotations:
summary: "Pod 重启频繁"
description: "命名空间 {{ $labels.namespace }} 的 Pod {{ $labels.pod }} 在 15 分钟内多次重启"这条规则依赖 kube-state-metrics 暴露的 Pod 重启指标。告警里保留 namespace、pod、container、node 这些标签,收到通知后才能直接定位对象。
六、常见 K8s 指标
Pod 重启:
promql
increase(kube_pod_container_status_restarts_total[15m])Pod 等待原因:
promql
kube_pod_container_status_waiting_reasonDeployment 副本不足:
promql
kube_deployment_status_replicas_available
<
kube_deployment_spec_replicas容器 CPU 使用率:
promql
sum by (namespace, pod, container) (
rate(container_cpu_usage_seconds_total{container!="",image!=""}[5m])
)容器内存使用:
promql
container_memory_working_set_bytes{container!="",image!=""}PVC 可用空间:
promql
kubelet_volume_stats_available_bytes
/
kubelet_volume_stats_capacity_bytesK8s 指标的标签很多,namespace、pod、container、node、cluster 通常要保留。写聚合时把这些标签全聚掉,图会很好看,但排查时又要重新查对象。
七、看板和告警
常见看板:
| 看板 | 关注点 |
|---|---|
| 集群总览 | 节点数、Pod 数、资源使用、告警数量 |
| Node | CPU、内存、磁盘、网络、负载 |
| Namespace | requests、limits、实际使用、Pod 状态 |
| Pod | 重启、OOM、CPU、内存、日志入口 |
| API Server | 请求量、延迟、错误率 |
| etcd | fsync、leader、DB 大小 |
| Ingress/Gateway | QPS、状态码、P95/P99 |
常见告警:
| 告警 | 方向 |
|---|---|
| 节点 NotReady | 节点状态异常 |
| Pod CrashLoopBackOff | 容器反复重启 |
| Deployment 副本不足 | 可用副本低于期望 |
| PVC 空间不足 | 持久卷容量风险 |
| API Server 错误率升高 | 控制面异常 |
| etcd fsync 延迟升高 | etcd 磁盘或负载问题 |
K8s 告警要避免把每个短暂 Pod 状态变化都发出来。发布过程中 Pod 重建是正常现象,关键是持续异常、可用副本不足、错误率升高和资源逼近瓶颈。
八、排查顺序
K8s 监控问题常见分层:
| 层级 | 检查点 |
|---|---|
| Prometheus | Targets、ServiceMonitor、PodMonitor、规则是否加载 |
| Service | Service label、port name、Endpoints |
| Pod | Pod label、metrics 端口、/metrics 是否可访问 |
| RBAC | Prometheus 是否有权限发现对象 |
| 网络 | NetworkPolicy、Service 访问、Pod 端口 |
| 指标本身 | 指标名、标签、采集间隔 |
ServiceMonitor 没生效时,通常按这个顺序查:
bash
# 看 ServiceMonitor 是否创建在预期 namespace
kubectl get servicemonitor -A
# 看 Service 标签和 ServiceMonitor selector 是否匹配
kubectl get svc -n demo demo-app --show-labels
# 确认 Service 端口名和 ServiceMonitor endpoints.port 一致
kubectl get svc -n demo demo-app -o yaml
# 看 Prometheus 目标页面是否出现对应 target
kubectl port-forward -n monitoring svc/kube-prometheus-stack-prometheus 9090:9090K8s 上 Prometheus 的问题,多半不是 PromQL 本身,而是发现链路没打通:CRD selector、namespace、Service label、port name、RBAC、NetworkPolicy 任何一层错了,Targets 里都可能看不到目标。