Kubernetes集群监控体系构建:Prometheus+Grafana+Alertmanager全链路实战

引言:为什么K8s集群需要可观测性体系

Kubernetes作为容器编排的事实标准,其动态性和复杂性使得传统的监控方式难以胜任。Pod的随时调度、节点扩缩容、Service的动态发现,都要求监控系统具备自动发现和自适应能力。Prometheus+Grafana+Alertmanager组合是目前K8s生态中最成熟的可观测性方案,本文将从架构设计到生产部署,提供完整的落地指南。

一、监控体系架构设计

一个完整的K8s监控体系需要覆盖三个层面:

  • 基础设施层:节点CPU、内存、磁盘IO、网络流量
  • 容器运行时层:Pod资源使用、容器状态、OOM事件
  • 应用层:业务指标(QPS、延迟、错误率)、自定义指标

Prometheus通过Pull模型从各个Target采集指标,ServiceMonitor和PodMonitor CRD实现了采集目标的自动发现。采集的指标经PromQL查询后,在Grafana中可视化展示,同时由Alertmanager管理告警路由和通知。

二、Prometheus部署与配置

使用Prometheus Operator是最推荐的部署方式,它通过CRD声明式管理Prometheus配置:

# 使用Helm部署kube-prometheus-stack
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

helm install monitoring prometheus-community/kube-prometheus-stack \
  --namespace monitoring --create-namespace \
  --set prometheus.prometheusSpec.retention=15d \
  --set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.storageClassName=local-ssd \
  --set prometheus.prometheusSpec.storageSpec.volumeClaimTemplate.spec.resources.requests.storage=50Gi \
  --set grafana.adminPassword="your-secure-password" \
  --set alertmanager.enabled=true

关键配置项

  • retention:数据保留时长,15天是常见选择。超过30天建议使用Thanos或Cortex做长期存储
  • storageClassName:使用local SSD存储,保证写入性能
  • resources:为Prometheus分配足够的CPU和内存,通常2核4G起步

三、ServiceMonitor:自动发现与采集配置

ServiceMonitor是Prometheus Operator的核心CRD,它声明式定义了如何发现和采集服务的指标:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: my-app-metrics
  namespace: default
  labels:
    release: monitoring  # 必须匹配prometheus的serviceMonitorSelector
spec:
  selector:
    matchLabels:
      app: my-app  # 匹配带有此label的Service
  namespaceSelector:
    any: true  # 从所有namespace发现
  endpoints:
  - port: metrics  # Service中定义的端口名
    path: /actuator/prometheus  # 指标路径
    interval: 15s  # 采集间隔
    scrapeTimeout: 10s
    honorLabels: true  # 保留应用自身的label

当新的Pod带着app: my-app标签上线时,ServiceMonitor会自动将其纳入采集目标,无需手动修改Prometheus配置。这是GitOps友好型的配置管理方式。

四、核心Grafana Dashboard构建

kube-prometheus-stack自带了一批高质量的Dashboard,但生产环境通常需要定制化:

# 集群概览Dashboard的关键面板
# 1. 集群资源使用率
# CPU: sum(rate(node_cpu_seconds_total{mode!="idle"}[5m])) / sum(rate(node_cpu_seconds_total[5m]))
# 内存: (sum(node_memory_MemTotal_bytes) - sum(node_memory_MemAvailable_bytes)) / sum(node_memory_MemTotal_bytes)

# 2. Pod资源Top排行
# topk(10, sum(container_memory_working_set_bytes{container!="", namespace!="monitoring"}) by (namespace, pod))

# 3. API Server请求延迟
# histogram_quantile(0.99, sum(rate(apiserver_request_duration_seconds_bucket[5m])) by (le, verb))

# 4. 调度器延迟
# histogram_quantile(0.99, sum(rate(scheduler_scheduling_duration_seconds_bucket[5m])) by (le))

在构建Dashboard时,建议使用变量(Template Variables)实现多集群和多Namespace切换:

# Grafana变量定义
# cluster: label_values(kube_node_info, cluster)
# namespace: label_values(kube_pod_info{cluster="$cluster"}, namespace)
# pod: label_values(kube_pod_info{namespace="$namespace"}, pod)

五、Alertmanager告警规则与路由

告警体系的核心是规则定义和通知路由。PrometheusRule CRD用于声明告警规则:

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: k8s-critical-alerts
  namespace: monitoring
spec:
  groups:
  - name: node-alerts
    rules:
    - alert: NodeMemoryUsageHigh
      expr: |
        (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes)
        / node_memory_MemTotal_bytes > 0.9
      for: 5m
      labels:
        severity: critical
      annotations:
        summary: "节点 {{ $labels.instance }} 内存使用率超过90%"
        runbook_url: "https://wiki.internal/runbook/node-memory-high"

    - alert: PodCrashLooping
      expr: rate(kube_pod_container_status_restarts_total[15m]) > 0
      for: 5m
      labels:
        severity: warning
      annotations:
        summary: "Pod {{ $labels.namespace }}/{{ $labels.pod }} 持续重启"

  - name: app-alerts
    rules:
    - alert: APIHighLatency
      expr: |
        histogram_quantile(0.99, 
          sum(rate(http_request_duration_seconds_bucket[5m])) by (le, service)
        ) > 2
      for: 3m
      labels:
        severity: warning
      annotations:
        summary: "服务 {{ $labels.service }} P99延迟超过2秒"

Alertmanager的路由配置决定告警发送到哪里:

# Alertmanager配置(通过Secret管理)
route:
  group_by: [alertname, namespace]
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  routes:
  - match:
      severity: critical
    receiver: oncall-pagerduty
    continue: false
  - match:
      severity: warning
    receiver: dev-slack
    repeat_interval: 8h

receivers:
- name: oncall-pagerduty
  pagerduty_configs:
  - routing_key: <your-routing-key>
- name: dev-slack
  slack_configs:
  - api_url: https://hooks.slack.com/services/xxx
    channel: "#alerts"
    title: "{{ .GroupLabels.alertname }}"
    text: "{{ range .Alerts }}{{ .Annotations.summary }}{{ end }}"

六、自定义应用指标采集

除了基础设施和容器指标,业务应用的自定义指标同样重要。以Spring Boot应用为例:

# application.yml 启用Prometheus端点
management:
  endpoints:
    web:
      exposure:
        include: health,info,prometheus,metrics
  metrics:
    export:
      prometheus:
        enabled: true
    tags:
      application: ${spring.application.name}

# 自定义指标代码示例(Java)
@Component
public class OrderMetrics {
    private final Counter orderCounter;
    private final Gauge activeUsersGauge;

    public OrderMetrics(MeterRegistry registry) {
        this.orderCounter = Counter.builder("orders_total")
            .description("Total number of orders")
            .tag("type", "online")
            .register(registry);

        this.activeUsersGauge = Gauge.builder("active_users", 
            () -> SessionManager.getActiveCount())
            .description("Current active users")
            .register(registry);
    }

    public void recordOrder() {
        orderCounter.increment();
    }
}

七、长期存储与高可用

单机Prometheus不适合长期存储和大规模集群。Thanos是社区主流的长期存储方案:

# Thanos架构:Sidecar + Store Gateway + Compactor + Query
# 部署Thanos Sidecar与Prometheus共存
- name: thanos-sidecar
  image: thanosio/thanos:v0.34.0
  args:
  - sidecar
  - --tsdb.path=/prometheus
  - --objstore.config-file=/etc/thanos/objstore.yml
  - --http-address=0.0.0.0:10902
  - --grpc-address=0.0.0.0:10901
  ports:
  - containerPort: 10902
    name: http
  - containerPort: 10901
    name: grpc

# 对象存储配置(S3兼容)
type: S3
config:
  bucket: thanos-storage
  endpoint: s3.amazonaws.com
  access_key: <key>
  secret_key: <secret>

Thanos Query提供全局视图,可以跨多个Prometheus实例查询数据,Compactor负责对历史数据进行降采样和压缩,Store Gateway从对象存储中提供历史数据查询。

总结

构建K8s可观测性体系不是简单的工具安装,而是需要根据业务重要性和团队规模精心设计监控维度、告警策略和可视化方案。Prometheus Operator的声明式配置使得整个监控体系可以纳入GitOps管理,与集群一起版本化。告警设计的关键在于信噪比——过多的无效告警会让团队麻木,过少则可能漏掉真实故障。建议从核心指标(资源使用率、错误率、延迟)出发,逐步扩展到业务指标,同时持续优化告警阈值和路由策略,最终形成可持续演进的监控体系。