Skip to content

Kubernetes 全链路观测与告警方案(立足 K8s 自身)

生产集群出问题,最常见的窘境是:业务报障说"服务不通",运维却要花半小时逐层排查——是节点挂了?CoreDNS 解析失败?Calico 网络策略误伤?还是 API Server 卡了导致调度停滞?本文立足 Kubernetes 自身各环节(不讨论业务 APM),给出一套可落地的全链路观测与告警方案:覆盖控制面、DNS、CNI(Calico)、节点、工作负载五大环节,做到"哪个环节出问题,一眼就能看出来"。配套告警规则可直接使用,并针对"监控数据断断续续"这一高频顽疾给出根因清单与治理方案。

适用对象:Kubeadm / RKE2 / K3s 等自建发行版集群,监控栈以 Prometheus + Grafana + Alertmanager 为准,日志以 Loki 为准。文中 IP、域名均为示例值,按实际集群替换。

读完本文你将得到

  • 覆盖控制面 / DNS / Calico / 节点 / 负载五大环节的指标接入清单与关键指标
  • 一张红绿灯总览看板:哪个环节出问题,一眼定位
  • 20+ 条可直接入库的 PromQL 告警规则(含 P1/P2/P3 分级路由)
  • 监控数据"断断续续"的根因清单与治理方案

一、总体架构

1.1 观测信号分层

K8s 自身可观测性依赖三类信号,缺一不可:

信号回答的问题选型
Metrics(指标)各环节"健不健康、慢不慢"Prometheus(kube-prometheus-stack)+ node-exporter + kube-state-metrics
Logs(日志)组件"报了什么错"Loki + Promtail(DaemonSet)
Events(事件)调度器/kubelet"做了什么决策"kube-event-exporter(K8s Event 默认只存 1 小时,必须外采)

1.2 组件部署图

text
┌──────────────────────────── 被观测对象 ────────────────────────────┐
│ 控制面: apiserver / etcd / scheduler / controller-manager         │
│ 网络面: calico-node(felix) / calico-typha / CoreDNS / kube-proxy  │
│ 节点面: kubelet / containerd / OS(CPU/内存/磁盘/网卡/conntrack)  │
│ 负载面: kube-state-metrics(Pod/Deploy/PVC 等对象状态)            │
└──────────────┬───────────────────────────────────────────────────┘
               │ /metrics (Prometheus 拉取,ServiceMonitor 声明)

┌── Prometheus HA ×2(双副本去重)── remote_write ──► VictoriaMetrics(长期存储,可选)
│        │                                          │
│        ▼                                          ▼
│  Alertmanager(分组/抑制/路由/静默)         Grafana(统一查询,聚合视图)
└───────────────────────────────────────────────────────────────┘
Promtail(每节点 DaemonSet)──► Loki ──► Grafana(日志面板 + Explore 联动)
kube-event-exporter ──► Loki(Event 落日志)+ Webhook(P1 事件直推告警)

核心原则:

  • kube-prometheus-stack 一把梭:Helm 安装即带控制面/节点/工作负载的 ServiceMonitor、Grafana 看板、告警规则基线,在其上做增量,不重复造轮子。
  • Prometheus 双副本 HA:单 Prometheus 重启/OOM 就是"数据断点"的主要来源(详见第五节)。
  • Event 必须外采kubectl get events 只能看最近 1 小时,排障时事件早已蒸发。

二、各环节指标接入与"一眼定位"关键指标

本章是方案核心:每个环节给出指标来源、接入方式、判断健康的关键指标。告警阈值见第四章。

2.1 控制面:API Server

接入:kube-prometheus-stack 默认 ServiceMonitor(apiserver 的 /metrics,443 端口)。

一眼定位指标:

指标含义异常表现
up{job="apiserver"}端点是否可抓取0 = 挂了或证书问题
rate(apiserver_request_total{code=~"5.."}[5m])5xx 错误率持续 >1/s 需警惕
histogram_quantile(0.99, rate(apiserver_request_duration_seconds_bucket[5m]))请求 P99 延迟>1s 说明 etcd 或 APF 限流
apiserver_flowcontrol_rejected_requests_totalAPF 限流拒绝数突增 = 有客户端在暴力请求
apiserver_current_inflight_requests在途请求数打满 mutating/readOnly 上限
workqueue_depth{name=~".*"}LIST/WATCH 处理深度持续增长 = 处理不过来

注意:API Server 慢,八成是 etcd 慢。看 apiserver 延迟时必须同时看 etcd 指标。

2.2 控制面:etcd

接入:Kubeadm 集群的 etcd /metrics 默认只监听 127.0.0.1:2381(HTTP),可直接用;RKE2 需配置 etcd-metrics 或单独建 Endpoints。证书方式注意 RBAC。

一眼定位指标:

指标含义异常表现
etcd_server_has_leader是否有 Leader0 = 集群失主,只读
etcd_server_leader_changes_seen_totalLeader 切换次数频繁切换 = 节点抖动/磁盘慢
histogram_quantile(0.99, rate(etcd_disk_wal_fsync_duration_seconds_bucket[5m]))WAL 刷盘 P99>10ms = 磁盘是瓶颈(SSD 应 <2ms)
histogram_quantile(0.99, rate(etcd_network_peer_round_trip_time_seconds_bucket[5m]))节点间 RTT跨机房部署重点看
etcd_mvcc_db_total_size_in_bytesDB 实际大小逼近 2G 配额会触发空间告警(NOSPACE),参考 etcd 空间告警与证书轮换实战

2.3 控制面:Scheduler / Controller-Manager

Kubeadm 默认绑定 127.0.0.1,需在静态 Pod 清单改为 0.0.0.0--bind-address)后建 Service/Endpoints 接入。

一眼定位指标:

组件指标异常表现
schedulerscheduler_pending_pods{queue="unschedulable"}持续增长 = 资源不足或污点/亲和性配置问题
schedulerrate(scheduler_schedule_attempts_total{result="error"}[5m])>0 持续存在需排查
controller-managerworkqueue_depth{name="deployment"}队列积压 = controller 处理不动
controller-managerrate(workqueue_retries_total[5m])重试率飙升 = 某 controller 在死循环报错

2.4 节点:kubelet / cAdvisor

接入:kube-prometheus-stack 默认抓取 /metrics/metrics/cadvisor

一眼定位指标:

指标异常表现
up{job="kubelet"}0 = kubelet 异常或节点不可达
kubelet_running_pods vs 节点容量逼近 110 上限
rate(kubelet_runtime_operations_errors_total[5m])>0 = 容器运行时(containerd)有问题
kubelet_volume_stats_used_bytes / kubelet_volume_stats_capacity_bytesPVC 使用率 >85% 告警
node_kubelet_evictions_total(如有)Pod 被驱逐 = 节点资源压力

2.5 节点 OS:node-exporter

接入:kube-prometheus-stack 默认 DaemonSet 部署。

K8s 场景下最值得盯的节点指标(普通 CPU/内存告警之外):

指标为什么重要
node_filesystem_avail_bytes(含 /var/lib/containerd、/var/lib/kubelet)镜像/日志盘打满是节点 NotReady 的头号原因
node_load1 / count(node_cpu_seconds_total{mode="idle"})Load 超核数 2 倍 = CPU 争抢严重
node_network_receive_errs_total / node_network_transmit_errs_total网卡错包增长 = 物理链路/驱动问题,Pod 网络"玄学"故障的源头
node_sockstat_TCP_tw / node_conntrack_entriesconntrack 表打满会导致新连接随机丢包,典型"时通时断"
node_time_timex_offset_seconds时钟偏移 >0.5s 会引发证书校验、日志错乱
node_systemd_unit_state{state="failed"}直接暴露 containerd/kubelet 等关键 unit 失败

conntrack:K8s 节点最容易被忽视的一环

kube-proxy iptables 模式下每个 Service 转发都过 conntrack,表满(默认 65536~262144)表现为新连接偶发超时、旧连接正常,极易误判为应用问题。告警表达式:node_nf_conntrack_entries / node_nf_conntrack_entries_limit > 0.8(内核较新时指标名带 nf_ 前缀,旧内核为 node_conntrack_entries)。

2.6 DNS:CoreDNS

CoreDNS 是"全站超时"类故障最常见的放大器。完整指标体系(解析延迟、缓存命中率、forward 上游健康、NodeLocal DNSCache)见 CoreDNS 监控完整体系,本文不重复,只列接入与总览要点:

  • 接入:CoreDNS 的 Corefile 开启 prometheus :9153,kube-prometheus-stack 的 coreDns.enabled=true 自动建 ServiceMonitor。
  • 总览三指标:coredns_dns_request_duration_seconds(P99 延迟)、rate(coredns_dns_responses_total{rcode="SERVFAIL"}[5m])(失败率)、coredns_panics_total(崩溃)。
  • 建议搭配黑盒探测:用 blackbox-exporter 或简单 CronJob 定时从 Pod 内 dig 一个已知域名,把"端到端解析成功率"作为用户视角的兜底指标(2.10 节)。

2.7 CNI:Calico(felix / typha / bird)

Calico 默认不暴露指标,需要显式开启,这是很多集群"网络黑盒"的原因:

yaml
# 1) 开启 felix 与 typha 的 Prometheus 端口
kubectl patch felixconfiguration default --type merge -p \
  '{"spec":{"prometheusMetricsEnabled":true,"prometheusMetricsPort":9091}}'
kubectl patch felixconfiguration default --type merge -p \
  '{"spec":{"prometheusTyphaMetricsPort":9093}}'

# 2) 为 calico-node 9091、calico-typha 9093 建 Service + ServiceMonitor(略,同常规套路)

一眼定位指标(felix 指标名前缀 felix_*):

指标含义异常表现
felix_active_local_endpoints本节点 workload endpoint 数突变配合 Pod 数核对
felix_ipsets_calico / felix_ipset_entriesipset 规模大规模集群看增长趋势
rate(felix_ipset_errors[5m])ipset 编程失败>0 = iptables/ipset 层出问题,网络策略可能未生效
rate(felix_iptables_restore_errors[5m])iptables 规则下发失败>0 必须立即排查(策略不生效且无业务报错
felix_int_dataplane_failures数据面编程失败计数累计增长 = felix 与内核脱节
rate(felix_resyncs_applied[5m])与 datastore 重同步频率频繁 resync = apiserver 连接不稳
typha: typha_connections_accepted / typha_ping_latencytypha 连接与延迟>50 节点必须部署 typha,连接数应≈节点数

除了指标,Calico 还有两个"非指标"健康项要纳入巡检(用 cron + textfile 采集器转成指标,或纳入第四章的黑盒探测):

bash
# 每个 calico-node 的就绪状态(bird 协议、felix 同步)
kubectl exec -n kube-system ds/calico-node -- calico-node -ready

# BGP 邻居状态(BGP 模式):Established 才是正常
kubectl exec -n kube-system calico-node-xxx -- birdcl -s /var/run/calico/bird.ctl show protocols

IP-in-IP / VXLAN 模式重点关注隧道 MTU 不匹配导致的"大包丢、小包通",用 2.10 的黑盒 ping(不同包长)探测。

2.8 kube-proxy

接入:/metrics 默认绑定 10249,开启 metricsBindAddress 后建 ServiceMonitor。

一眼定位指标:

指标异常表现
rate(kubeproxy_sync_proxy_rules_duration_seconds_sum[5m]) / 规则数规则同步耗时随 Service 规模线性增长,突增 = 变更风暴
kubeproxy_sync_proxy_rules_last_timestamp_seconds距上次成功同步过久 = 卡死
rate(kubeproxy_network_programming_duration_seconds_bucket[5m])端点变更到生效的延迟(K8s SLI)

2.9 工作负载对象:kube-state-metrics

接入:kube-prometheus-stack 默认。

"一眼定位"看板全靠它,关键表达式:

promql
# 未就绪的 Deployment 副本(>0 即亮红灯)
kube_deployment_status_replicas_available != kube_deployment_spec_replicas

# CrashLoopBackOff / 反复重启的容器
increase(kube_pod_container_status_restarts_total[15m]) > 3

# Pending 超过 5 分钟的 Pod
kube_pod_status_phase{phase="Pending"} == 1

# OOMKilled 过的容器
kube_pod_container_status_last_terminated_reason{reason="OOMKilled"} == 1

# 节点状态(NodeNotReady 一屏可见)
kube_node_status_condition{condition="Ready",status="true"} == 0

# HPA 打到上限(容量不足的早期信号)
kube_horizontalpodautoscaler_status_current_replicas == kube_horizontalpodautoscaler_spec_max_replicas

2.10 黑盒探测:用户视角兜底

指标再全也有盲区(比如"CoreDNS 指标正常,但跨节点 Pod 就是解析不通")。用 blackbox-exporter 或自建 CronJob 探针补三类端到端探测:

探测项方法暴露的问题
Pod → Service → DNS 全链路CronJob 每 30s 解析 kubernetes.default.svc.cluster.localCoreDNS、kube-proxy、conntrack
跨节点 Pod 互通DaemonSet 探针互 ping + TCP 建连Calico 隧道、MTU、安全组
出集群外网blackbox-exporter http probe 内网 VIP/网关NAT、出口策略

探测结果转为指标(probe_success / 成功率),在总览看板单独一行。

指标与探测的关系

指标告诉你组件在转,探测告诉你链路真的通。

三、"一眼定位"总览看板设计

Grafana 首页建一张 Cluster Health Overview 看板,顶部一行红绿灯 Stat 面板,每个面板对应一个环节,故障定位从"逐层猜"变成"看哪个红灯亮了":

text
┌─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┐
│Nodes    │API Srv  │etcd     │CoreDNS  │Calico   │调度队列 │黑盒探测 │
│ 3/3 OK  │5xx: 0   │Leader:1 │P99: 2ms │err: 0   │pending:0│DNS:100% │
└─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┘

每个 Stat 面板的表达式(阈值自行调整,红=需要立即处理):

promql
# Nodes:未就绪节点数(0 为绿)
count(kube_node_status_condition{condition="Ready",status="true"} == 0)

# API Server:5xx 速率
sum(rate(apiserver_request_total{code=~"5.."}[5m]))

# etcd:失主节点数
count(etcd_server_has_leader == 0)

# CoreDNS:SERVFAIL 率
sum(rate(coredns_dns_responses_total{rcode="SERVFAIL"}[5m]))

# Calico:iptables/ipset 编程错误速率
sum(rate(felix_iptables_restore_errors[5m])) + sum(rate(felix_ipset_errors[5m]))

# 调度:不可调度 Pod 数
sum(scheduler_pending_pods{queue="unschedulable"})

# 黑盒:DNS 探测失败率
1 - avg(probe_success{job="k8s-dns-probe"})

下方按第二章的分层各放一排行(row),每个红灯面板配置 dashboard link 点击下钻到对应环节的明细看板(kube-prometheus-stack 自带看板 + 自建 Calico/CoreDNS 看板)。日志面板用 Loki datasource 在同看板嵌入 sum by (app) (rate({namespace="kube-system"} |= "error" [5m])),实现"指标红了 → 同屏看错误日志"。

四、告警规则体系

4.1 告警分级与路由

级别定义通道响应
P1集群不可用或即将不可用(API/etcd 全挂、大面积 NotReady)电话/短信/oncall立即
P2单环节异常,有冗余未影响业务(单节点 NotReady、CoreDNS SERVFAIL 率升)IM 群(企微/钉钉/飞书)30 分钟
P3趋势性风险(磁盘 80%、conntrack 70%、证书 30 天到期)IM 群/工单工作时间

Alertmanager 关键配置:按 severity 路由;group_by: [cluster, alertname];P1 配 repeat_interval: 5m 强提醒;节点级告警加 inhibit(节点 NotReady 时抑制该节点上所有 Pod 级告警,避免告警风暴)。

4.2 核心告警规则(可直接入库的节选)

yaml
groups:
# ===== 控制面 =====
- name: k8s-control-plane
  rules:
  - alert: KubeAPIDown
    expr: absent(up{job="apiserver"} == 1) or max(up{job="apiserver"}) == 0
    for: 3m
    labels: {severity: P1, layer: control-plane}
    annotations:
      summary: "API Server 不可达,集群失去控制入口"

  - alert: KubeAPIErrorRateHigh
    expr: sum(rate(apiserver_request_total{code=~"5.."}[5m])) / sum(rate(apiserver_request_total[5m])) > 0.05
    for: 10m
    labels: {severity: P2, layer: control-plane}
    annotations:
      summary: "API Server 5xx 错误率超过 5%"

  - alert: EtcdNoLeader
    expr: etcd_server_has_leader == 0
    for: 1m
    labels: {severity: P1, layer: etcd}
    annotations:
      summary: "etcd {{ $labels.instance }} 失去 Leader"

  - alert: EtcdDiskSlow
    expr: histogram_quantile(0.99, rate(etcd_disk_wal_fsync_duration_seconds_bucket[5m])) > 0.01
    for: 10m
    labels: {severity: P2, layer: etcd}
    annotations:
      summary: "etcd WAL 刷盘 P99 超过 10ms,检查磁盘性能"

# ===== 节点 =====
- name: k8s-node
  rules:
  - alert: KubeNodeNotReady
    expr: kube_node_status_condition{condition="Ready",status="true"} == 0
    for: 5m
    labels: {severity: P2, layer: node}
    annotations:
      summary: "节点 {{ $labels.node }} NotReady 超过 5 分钟"

  - alert: NodeConntrackAlmostFull
    expr: node_nf_conntrack_entries / node_nf_conntrack_entries_limit > 0.8
    for: 10m
    labels: {severity: P3, layer: node}
    annotations:
      summary: "节点 {{ $labels.instance }} conntrack 使用率超 80%,新连接将随机失败"

  - alert: NodeNetworkErrsIncreasing
    expr: rate(node_network_receive_errs_total[5m]) + rate(node_network_transmit_errs_total[5m]) > 0
    for: 15m
    labels: {severity: P3, layer: node}
    annotations:
      summary: "节点 {{ $labels.instance }} 网卡错包持续增长,检查物理链路/驱动"

# ===== DNS =====
- name: k8s-coredns
  rules:
  - alert: CoreDNSServfailHigh
    expr: sum(rate(coredns_dns_responses_total{rcode="SERVFAIL"}[5m])) / sum(rate(coredns_dns_requests_total[5m])) > 0.05
    for: 5m
    labels: {severity: P2, layer: dns}
    annotations:
      summary: "CoreDNS SERVFAIL 占比超 5%,检查上游 DNS 与 forward 配置"

  - alert: CoreDNSLatencyHigh
    expr: histogram_quantile(0.99, sum(rate(coredns_dns_request_duration_seconds_bucket[5m])) by (le)) > 0.5
    for: 10m
    labels: {severity: P2, layer: dns}
    annotations:
      summary: "CoreDNS P99 解析延迟超 500ms"

# ===== Calico =====
- name: k8s-calico
  rules:
  - alert: CalicoFelixDataplaneErrors
    expr: rate(felix_iptables_restore_errors[5m]) + rate(felix_ipset_errors[5m]) > 0
    for: 5m
    labels: {severity: P2, layer: cni}
    annotations:
      summary: "节点 {{ $labels.instance }} Calico 规则下发失败,网络策略可能未生效"

  - alert: CalicoNodeNotReady
    expr: up{job="calico-node"} == 0
    for: 5m
    labels: {severity: P2, layer: cni}
    annotations:
      summary: "节点 {{ $labels.instance }} calico-node 指标不可抓取"

# ===== 调度与负载 =====
- name: k8s-workload
  rules:
  - alert: KubePodCrashLooping
    expr: increase(kube_pod_container_status_restarts_total[15m]) > 3
    for: 5m
    labels: {severity: P3, layer: workload}
    annotations:
      summary: "{{ $labels.namespace }}/{{ $labels.pod }} 容器 15 分钟内重启超过 3 次"

  - alert: KubeDeploymentReplicasMismatch
    expr: kube_deployment_status_replicas_available != kube_deployment_spec_replicas
    for: 15m
    labels: {severity: P3, layer: workload}
    annotations:
      summary: "Deployment {{ $labels.namespace }}/{{ $labels.deployment }} 可用副本数与期望不符"

# ===== 黑盒兜底 =====
- name: k8s-blackbox
  rules:
  - alert: K8sDNSProbeFailing
    expr: avg_over_time(probe_success{job="k8s-dns-probe"}[5m]) < 0.9
    for: 5m
    labels: {severity: P2, layer: blackbox}
    annotations:
      summary: "集群内 DNS 端到端探测成功率低于 90%"

事件类告警(如 Warning Event、PodFailedScheduling、证书过期)由 kube-event-exporter 直推,补全"指标看不到、事件里早有答案"的场景(如镜像拉取失败 Failed to pull image)。

五、监控数据"断断续续"的根因与治理

Grafana 曲线出现断点/锯齿,是自建 Prometheus 最常被吐槽的问题。根因按出现频率排序:

5.1 根因清单

根因现象特征定位方法
Prometheus 单副本重启/OOMKilled所有面板同时间段集体断kubectl get pod -n monitoring 看 RESTARTS;prometheus_tsdb_head_series 逼近内存
抓取目标 OOM/被驱逐单个 job 断(如 node-exporter 某实例)对应 exporter Pod 的重启记录
scrape_interval 与看板 interval 不匹配曲线"虚线化"、rate 锯齿抓取间隔 30s 而查询步长 <30s
scrape_timeout 默认 10s,目标响应慢大数据量 job(cadvisor)间歇性失败up == 0 的时间点 + scrape_duration_seconds > scrape_interval
网络丢包/跨节点抓取消耗大随机性断点node 网卡错包指标 + Prometheus 日志 context deadline exceeded
时序爆炸导致 TSDB 压缩卡顿周期性(对齐 compaction 2h 边界)卡顿prometheus_tsdb_compactions_failed_total、cardinality 超限
磁盘写满/IO 慢写入阻塞,查询超时node-exporter 磁盘指标

5.2 治理方案

① Prometheus 双副本 HA(必选)

yaml
# kube-prometheus-stack values
prometheus:
  prometheusSpec:
    replicas: 2
    retention: 7d          # 本地只留短期,长期交给远端存储
    scrapeInterval: 30s
    scrapeTimeout: 10s     # 大 job 单独调大
    resources:
      requests: {memory: 4Gi}
      limits: {memory: 8Gi}  # 按 head_series 估算:每百万 series 约 1~2GB

双副本抓同一批目标,Grafana 查询端用 VictoriaMetrics/Thanos 的 dedup 合并去重,任何单副本重启都不产生断点。

② 长期存储 + 查询聚合(推荐 VictoriaMetrics,Thanos 亦可)

text
Prometheus ×2 ── remote_write ──► vminsert ──► vmstorage
Grafana ──► vmselect(dedup,跨副本合并、长期查询)
  • remote_write 自带队列与磁盘 WAL,存储端故障恢复后数据自动补传,本地断点也能回填。
  • Prometheus 本地 retention 缩到 7 天,内存/磁盘压力骤降,OOM 断点问题解决大半。

③ 抓取侧调优

yaml
# cadvisor 等大指标量 job 单独放宽超时
- job_name: kubelet-cadvisor
  scrape_interval: 30s
  scrape_timeout: 25s   # 必须 < interval
  metric_relabel_configs:
  # 砍掉无用高基数指标,防时序爆炸(OOM 断点的源头)
  - source_labels: [__name__]
    regex: container_(network_tcp_usage_total|network_udp_usage_total|tasks_state|memory_failures_total)
    action: drop

关键纪律:scrape_timeout < scrape_intervalup == 0 本身要告警(监控盲了要第一时间知道):

yaml
- alert: PrometheusTargetDown
  expr: up == 0
  for: 5m
  labels: {severity: P2, layer: monitoring}
  annotations:
    summary: "抓取目标 {{ $labels.job }}/{{ $labels.instance }} 失联超 5 分钟"

④ Grafana 侧:看板统一 min_interval=30s 对齐抓取间隔;rate 窗口 ≥ 2×interval([5m] 起步),消除锯齿。

治理后验收标准:任选一周时间窗,count_over_time((up == 1)[7d:30s]) 与理论抓取次数一致,即无断点。

六、日志与事件

6.1 组件日志:Loki + Promtail

yaml
# loki-stack values 要点
promtail:
  config:
    snippets:
      extraScrapeConfigs: |
        # 控制面静态 Pod 日志(/var/log/pods/kube-system_*)
        # kube-prometheus-stack 自带容器日志 pipeline 已覆盖,
        # 重点是给控制面/网络组件打好 job 标签便于检索:
        - job_name: kubernetes-control-plane
          kubernetes_sd_configs: [{role: pod}]
          relabel_configs:
          - source_labels: [__meta_kubernetes_namespace]
            regex: kube-system
            action: keep

查询场景示例:

logql
# API Server 最近 1 小时的 5xx 详情
{component="kube-apiserver"} |= "status=500" | json | line_format "{{.verb}} {{.requestURI}}"

# calico-node 某节点 felix 报错
{app="calico-node", pod=~"calico-node-xxx"} |~ "(?i)error|fail"

Loki 告警:对 |= "panic"|= "NOSPACE"(etcd 空间告警关键字)等模式建 LogQL ruler 告警,日志关键字直达告警通道。

6.2 K8s Event 外采

bash
helm install kube-event-exporter oci://ghcr.io/resmoio/charts/kubernetes-event-exporter

配置要点:Warning 事件全量推 Loki(可检索、可关联);reason: FailedScheduling / FailedMount / Unhealthy / BackOff 直推 IM(这类事件往往先于指标异常出现,是最早的故障信号)。路由树示例:

yaml
route:
  routes:
  - match:
    - receiver: "loki"                       # 全量落 Loki
  - match:
    - apiVersion: v1
      kind: Pod
      reason: "FailedScheduling|FailedMount|BackOff|Unhealthy"
      type: "Warning"
    receiver: "webhook-im"                   # 关键事件直推告警

七、落地清单

按依赖顺序执行,每步完成后用第四章告警自验证:

  1. 基座:Helm 装 kube-prometheus-stack(Prometheus×2 + Alertmanager + node-exporter + kube-state-metrics + 控制面/KSM 告警基线)。
  2. 补盲区:Kubeadm 集群改 scheduler/controller-manager bind-address 并建 ServiceMonitor;Calico 开 felix/typha metrics 并接入;kube-proxy 开 10249。
  3. 日志:Loki + Promtail,控制面与 kube-system 组件日志入库;kube-event-exporter 双路(Loki 全量 + IM 关键事件)。
  4. 黑盒:部署 DNS/Pod 互通/出网三类探针,结果入 Prometheus。
  5. HA 与长存:Prometheus 双副本 + remote_write 到 VictoriaMetrics,Grafana 走 vmselect dedup。
  6. 看板:按第三章建 Cluster Health Overview 总览看板,环节红灯下钻明细。
  7. 告警:导入 4.2 规则,配 Alertmanager 分级路由与节点级抑制;灰度期先 P3 全开、P1/P2 逐条调阈值降噪。
  8. 演练:每月故障演练(杀一个 etcd 成员、断开某节点 calico-node、打满测试盘),验证"总览看板对应红灯亮起 + 告警按级别到达"。

至此,集群任何一个环节异常,都能在总览看板一眼定位、在告警中按级别触达、在日志/事件中拿到细节,监控自身也通过 HA + up 告警保证不再"断断续续"。