Kubernetes 可观测性实战:集群、Pod、网络、存储全链路监控

系统性 Kubernetes 可观测性实战指南:K8s 分层监控模型(集群/节点/Pod/容器/应用/API Server/etcd)、kubelet/cAdvisor/Metrics Server/Node Exporter 指标详解、Vertical Pod Autoscaler (VPA) / Horizontal Pod Autoscaler (HPA) 监控、Kubernetes Events / Audit Logs / Control Plane 日志、网络可观测性(CNI / kube-proxy / CoreDNS / Ingress)、存储可观测性(PVC/StorageClass/CSI driver metrics)、K8s 告警规则(Prometheus Rule)、Grafana K8s Dashboard 生态(社区模板/自定义)、Kubectl resource metrics / stern / k9s 排障工具链。

Kubernetes 让基础设施变得可编排,但也让故障排查变得多层次。 一个请求失败可能是因为应用代码问题、Pod 资源不足、节点磁盘压力、网络策略拦截、DNS 解析超时、Ingress 配置错误、API Server 响应慢,或者 etcd 存储满了。K8s 可观测性的目标是建立从集群到容器的全链路可视性。


一、K8s 分层监控模型

1.1 五层架构

Kubernetes 可观测性分层:

Layer 5: Application(应用层)
  ├── 应用指标(RED:Rate/Errors/Duration)
  ├── 业务指标(订单数、转化率)
  ├── APM 追踪(OpenTelemetry)
  └── 日志(结构化 JSON)

Layer 4: Container(容器层)
  ├── CPU / Memory / Disk IO / Network
  ├── 容器进程(PID 压力)
  ├── 容器重启次数
  └── OOMKilled / Evicted

Layer 3: Pod(编排层)
  ├── 副本数 vs 期望数
  ├── 就绪探针 / 存活探针状态
  ├── Pod 调度延迟
  └── 亲和性/反亲和性冲突

Layer 2: Node(节点层)
  ├── CPU / Memory / Disk / Network
  ├── 节点状态(Ready/NotReady)
  ├── 内核压力(Pressure)
  └── 节点污点/污点容忍

Layer 1: Cluster(控制平面层)
  ├── API Server 延迟/错误率
  ├── etcd 延迟/存储/领袖选举
  ├── Scheduler 调度延迟/失败数
  └── Controller Manager 性能

二、核心组件指标

2.1 kubelet 与 cAdvisor

# kubelet 指标
# Pod 启动延迟
kubelet_pod_start_duration_seconds_count

# 容器运行时操作延迟
kubelet_runtime_operations_duration_seconds{operation_type=~"create_container|pull_image"}

# PLEG(Pod Lifecycle Event Generator)延迟
kubelet_pleg_relist_duration_seconds

# cAdvisor 容器指标
# 容器 CPU 使用率
rate(container_cpu_usage_seconds_total{container!=""}[5m])

# 容器内存使用
container_memory_working_set_bytes{container!=""}

# 容器网络 IO
rate(container_network_receive_bytes_total[5m])
rate(container_network_transmit_bytes_total[5m])

# 容器文件系统使用
container_fs_usage_bytes{container!=""}

2.2 Metrics Server

# Metrics Server 提供 kubectl top 能力
kubectl top nodes
# NAME        CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
# node-01     850m         21%    8192Mi          51%
# node-02     1200m        30%    10240Mi         64%

kubectl top pods --all-namespaces
# NAMESPACE   NAME                    CPU(cores)   MEMORY(bytes)
# default     nginx-7d8c9b4f5-x2b3c   5m           128Mi
# default     api-5f4d8c9b2-a1b2c     150m         512Mi

# Metrics Server HPA 指标
# kubectl get --raw /apis/metrics.k8s.io/v1beta1/pods

2.3 Node Exporter

# 节点 CPU
100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

# 节点内存
(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) /
node_memory_MemTotal_bytes * 100

# 节点磁盘
(node_filesystem_size_bytes{mountpoint="/"} - node_filesystem_avail_bytes{mountpoint="/"}) /
node_filesystem_size_bytes{mountpoint="/"} * 100

# 节点网络
rate(node_network_receive_bytes_total{device!="lo"}[5m])
rate(node_network_transmit_bytes_total{device!="lo"}[5m])

# 节点压力
node_pressure_cpu_waiting_seconds_total
node_pressure_memory_waiting_seconds_total
node_pressure_io_waiting_seconds_total

三、K8s 核心告警规则

# kubernetes-alerts.yml
groups:
  - name: kubernetes-critical
    rules:
      # Pod 频繁重启
      - alert: PodCrashLooping
        expr: rate(kube_pod_container_status_restarts_total[10m]) > 0
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Pod {{ $labels.pod }} is crash looping"

      # Pod 未就绪
      - alert: PodNotReady
        expr: |
          kube_pod_status_phase{phase=~"Pending|Unknown|Failed"} == 1
        for: 15m
        labels:
          severity: warning

      # Pod OOMKilled
      - alert: PodOOMKilled
        expr: |
          kube_pod_container_status_last_terminated_reason{reason="OOMKilled"} == 1
        labels:
          severity: warning

      # 节点 NotReady
      - alert: NodeNotReady
        expr: kube_node_status_condition{condition="Ready",status="false"} == 1
        for: 5m
        labels:
          severity: critical

      # 节点磁盘压力
      - alert: NodeDiskPressure
        expr: kube_node_status_condition{condition="DiskPressure",status="true"} == 1
        for: 2m
        labels:
          severity: warning

      # 节点内存压力
      - alert: NodeMemoryPressure
        expr: kube_node_status_condition{condition="MemoryPressure",status="true"} == 1
        for: 2m
        labels:
          severity: warning

      # Job 失败
      - alert: JobFailed
        expr: kube_job_status_failed{job_name=~".*"} > 0
        for: 0m
        labels:
          severity: warning

      # HPA 达到最大副本
      - alert: HPAMaxReplicas
        expr: |
          kube_horizontalpodautoscaler_status_current_replicas
          ==
          kube_horizontalpodautoscaler_spec_max_replicas
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "HPA {{ $labels.horizontalpodautoscaler }} at max replicas"

  - name: kubernetes-control-plane
    rules:
      # API Server 延迟
      - alert: APIServerHighLatency
        expr: |
          histogram_quantile(0.99,
            sum(rate(apiserver_request_duration_seconds_bucket[5m])) by (le)
          ) > 1
        for: 5m
        labels:
          severity: warning

      # etcd 领袖选举频繁
      - alert: EtcdFrequentLeaderChanges
        expr: |
          rate(etcd_server_leader_changes_seen_total[1h]) > 0
        for: 5m
        labels:
          severity: critical

      # etcd DB 大小
      - alert: EtcdDatabaseHigh
        expr: etcd_mvcc_db_total_size_in_bytes / etcd_server_quota_backend_bytes > 0.8
        for: 5m
        labels:
          severity: warning

      # Scheduler 调度失败
      - alert: SchedulerFailures
        expr: rate(scheduler_schedule_attempts_total{result="unschedulable"}[5m]) > 0
        for: 10m
        labels:
          severity: warning

四、K8s Events 与 Audit Logs

4.1 Events 监控

# 查看 Pod 事件
kubectl describe pod <pod-name>

# 查看所有 Warning 事件
kubectl get events --field-selector type=Warning --sort-by='.lastTimestamp'

# 按原因筛选
kubectl get events --field-selector reason=FailedScheduling

# 用 stern 实时查看日志
stern --all-namespaces --selector app=api

4.2 Audit Logs

# audit-policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  - level: Metadata
    resources:
      - group: ""
        resources: ["pods"]

  - level: RequestResponse
    resources:
      - group: "rbac.authorization.k8s.io"
        resources: ["roles", "rolebindings", "clusterroles", "clusterrolebindings"]

  - level: Request
    omitStages:
      - RequestReceived
    nonResourceURLs:
      - /healthz*
      - /version
    users:
      - system:kube-proxy
    verbs: ["get"]
# API Server 启用审计日志
kube-apiserver \
  --audit-policy-file=/etc/kubernetes/audit-policy.yaml \
  --audit-log-path=/var/log/audit.log \
  --audit-log-maxsize=100 \
  --audit-log-maxbackup=10

五、网络可观测性

5.1 CNI 监控

# Calico 指标(如启用 Felix 指标)
# 网络策略命中
felix_active_local_endpoints

# Cilium 指标
cilium_endpoint_count
cilium_drop_total{reason="Policy denied"}

# Flannel 指标
flannel_subnets

5.2 CoreDNS

# DNS 查询速率
coredns_dns_requests_total

# DNS 查询延迟
coredns_dns_request_duration_seconds_bucket

# DNS 查询失败
coredns_dns_responses_total{rcode="NXDOMAIN"}
coredns_dns_responses_total{rcode="SERVFAIL"}

# 缓存命中率
coredns_cache_hits_total
coredns_cache_misses_total

5.3 Ingress

# Nginx Ingress Controller
nginx_ingress_controller_requests
nginx_ingress_controller_nginx_process_requests

# 请求延迟
histogram_quantile(0.99,
  sum by (le, ingress) (rate(nginx_ingress_controller_request_duration_seconds_bucket[5m]))
)

# 5xx 错误
nginx_ingress_controller_requests{status=~"5.."}

六、存储可观测性

6.1 PVC 监控

# PVC 使用率
(
  kubelet_volume_stats_used_bytes
  /
  kubelet_volume_stats_capacity_bytes
) * 100

# PVC 接近满
kubelet_volume_stats_available_bytes / kubelet_volume_stats_capacity_bytes < 0.1

# StorageClass 配额
kube_persistentvolumeclaim_resource_requests_storage_bytes

6.2 CSI Driver 指标

# CSI Driver 暴露了标准的 gRPC 指标
# 需要 CSI 驱动支持

# 示例:创建 PVC 延迟
csi_sidecar_operations_seconds_bucket{driver="csi-driver-name", method_name="CreateVolume"}

七、排障工具链

工具用途命令
kubectl基础查询kubectl get/describe/logs/top
k9s交互式 TUIk9s
stern多 Pod 日志聚合stern --selector app=api
kubectl-traceBPF 追踪kubectl trace run node-01 -e '...'
inspektor-gadgetK8s 专用 eBPFkubectl gadget trace tcp
kubectl-debug调试容器kubectl debug pod-xxx --image=busybox
kor清理孤儿资源kor all

参考与延伸阅读

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「infra」更多文章

  1. 可观测性数据存储选型:TSDB、列式存储、对象存储与成本优化
  2. 云原生 APM 与性能剖析:Continuous Profiling 与火焰图
  3. eBPF 可观测性:内核可编程追踪与性能剖析