Skip to content

K8s指标监控

Kubernetes 指标监控要覆盖节点、容器、Pod、控制平面、etcd、Ingress/Gateway 和业务应用。单独看 kubectl top 只能看到现场资源快照,长期趋势、告警和看板还是要接 Prometheus。K8s 环境里更常见的做法是用 Prometheus Operator 管理 Prometheus、Alertmanager、规则和抓取对象。

一、K8s 里指标从哪里来

常见指标来源:

来源典型指标用途
Node Exporter节点 CPU、内存、磁盘、网络主机层资源
kubelet / cAdvisor容器 CPU、内存、文件系统容器层资源
kube-state-metricsDeployment、Pod、PVC、Job 等资源状态K8s 对象状态
API Server请求量、延迟、错误控制面健康
etcdleader、DB 大小、fsync、请求延迟集群存储健康
Ingress / GatewayQPS、状态码、延迟入口流量
应用 /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: metrics

ServiceMonitor:

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: 30s

release: 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: 30s

PodMonitor 更直接,但服务变动时也更容易暴露出很多短生命周期 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 重启指标。告警里保留 namespacepodcontainernode 这些标签,收到通知后才能直接定位对象。

六、常见 K8s 指标

Pod 重启:

promql
increase(kube_pod_container_status_restarts_total[15m])

Pod 等待原因:

promql
kube_pod_container_status_waiting_reason

Deployment 副本不足:

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_bytes

K8s 指标的标签很多,namespacepodcontainernodecluster 通常要保留。写聚合时把这些标签全聚掉,图会很好看,但排查时又要重新查对象。

七、看板和告警

常见看板:

看板关注点
集群总览节点数、Pod 数、资源使用、告警数量
NodeCPU、内存、磁盘、网络、负载
Namespacerequests、limits、实际使用、Pod 状态
Pod重启、OOM、CPU、内存、日志入口
API Server请求量、延迟、错误率
etcdfsync、leader、DB 大小
Ingress/GatewayQPS、状态码、P95/P99

常见告警:

告警方向
节点 NotReady节点状态异常
Pod CrashLoopBackOff容器反复重启
Deployment 副本不足可用副本低于期望
PVC 空间不足持久卷容量风险
API Server 错误率升高控制面异常
etcd fsync 延迟升高etcd 磁盘或负载问题

K8s 告警要避免把每个短暂 Pod 状态变化都发出来。发布过程中 Pod 重建是正常现象,关键是持续异常、可用副本不足、错误率升高和资源逼近瓶颈。

八、排查顺序

K8s 监控问题常见分层:

层级检查点
PrometheusTargets、ServiceMonitor、PodMonitor、规则是否加载
ServiceService label、port name、Endpoints
PodPod label、metrics 端口、/metrics 是否可访问
RBACPrometheus 是否有权限发现对象
网络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:9090

K8s 上 Prometheus 的问题,多半不是 PromQL 本身,而是发现链路没打通:CRD selector、namespace、Service label、port name、RBAC、NetworkPolicy 任何一层错了,Targets 里都可能看不到目标。