K8s集群运行时异常趋势分析预警实操

项目

内容

适用版本

Kubernetes v1.28.15 + Prometheus 2.48 + Grafana 10.2 + Loki 2.9 + containerd 1.7.x

核心目标

运行时异常实时感知、趋势预测、容量预警、自动化应急响应

编写日期

2026-08-18

文档版本

v1.0

1. 操作环境与前置准备

1.1 硬件要求

角色

CPU

内存

硬盘

说明

Worker

8核+

16GB+

200GB SSD

业务节点

监控节点

8核+

16GB+

500GB SSD

Prometheus+Grafana+Loki

告警节点

4核+

8GB+

100GB SSD

Alertmanager(可复用监控节点)

监控节点建议独立部署,避免监控组件与业务争抢资源。大规模集群(50+节点)需独立部署。

1.2 软件版本矩阵

组件

版本

说明

Kubernetes

v1.28.15

集群版本

containerd

1.7.11+

容器运行时

Prometheus

2.48.0+

指标存储与告警

Alertmanager

0.26.0+

告警路由通知

Grafana

10.2.0+

可视化看板

Loki

2.9.0+

日志聚合分析

Promtail

2.9.0+

日志采集器

node-exporter

1.7.0+

节点指标采集

kube-state-metrics

2.10.0+

K8s资源状态指标

kube-prometheus-stack

最新

一键部署(可选)

1.3 节点规划

主机名

IP地址

角色

部署组件

k8s-worker01

192.168.10.21

Worker

业务Pod + node-exporter

k8s-worker02

192.168.10.22

Worker

业务Pod + node-exporter

k8s-worker03

192.168.10.23

Worker

业务Pod + node-exporter

k8s-monitor

192.168.10.40

监控

Prometheus/Grafana/Loki/Alertmanager

1.4 存储规划

数据类型

保留周期

预估存储

存储路径

Loki日志

7天

200GB+

/data/loki

Alertmanager

永久

<1GB

/data/alertmanager

Grafana

永久

<10GB

/data/grafana

2. 运行时异常监控体系架构

2.1 异常分类与监控维度

异常类别

监控对象

关键指标

预警级别

资源耗尽

CPU/内存/磁盘/网络

使用率、趋势斜率、预测值

P1/P2

Pod异常

容器状态

CrashLoopBackOff、OOMKilled、重启率

P1/P2

网络异常

连接/丢包/延迟

conntrack使用率、丢包率、TCP重传

P1/P2

存储异常

磁盘/IO

磁盘使用率、IO等待、inode

P1/P2

调度异常

调度器

调度失败数、Pending Pod数

P2

应用异常

业务容器

错误率、延迟、5xx比例

P1/P2

2.2 整体架构

┌──────────────────────────────────────────────────────────────────┐
│                        K8s Cluster                                │
│                                                                  │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐         │
│  │  Worker1 │  │  Worker2 │  │  Worker3 │  │  Master  │         │
│  │node-exp  │  │node-exp  │  │node-exp  │  │kubelet   │         │
│  │promtail  │  │promtail  │  │promtail  │  │metrics   │         │
│  │cAdvisor  │  │cAdvisor  │  │cAdvisor  │  │          │         │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘  └────┬─────┘         │
│       │              │              │              │              │
│       └──────────────┼──────────────┼──────────────┘              │
│                      │              │                             │
│              metrics │        logs  │                             │
│                      ▼              ▼                             │
│  ┌──────────────────────────┐ ┌──────────────────┐               │
│  │      Prometheus          │ │      Loki        │               │
│  │  (指标存储+告警规则)      │ │  (日志聚合分析)  │               │
│  └──────────┬───────────────┘ └────────┬─────────┘               │
│             │ alerts                    │ logs                    │
│             ▼                           ▼                         │
│  ┌──────────────────┐        ┌──────────────────┐                 │
│  │  Alertmanager    │        │     Grafana      │                 │
│  │  (路由/通知/抑制) │◄──────►│  (可视化看板)    │                 │
│  └────────┬─────────┘        └──────────────────┘                 │
│           │                                                      │
│           ▼                                                      │
│  ┌──────────────────┐                                           │
│  │  钉钉/企微/邮件   │                                           │
│  └──────────────────┘                                           │
└──────────────────────────────────────────────────────────────────┘

2.3 数据流转链路

采集层          存储层           分析层           通知层
─────────      ─────────       ─────────       ─────────
node-exporter → Prometheus → 告警规则引擎 → Alertmanager → 钉钉
kubelet       → Prometheus → 趋势预测模型 → Alertmanager → 企微
cAdvisor      → Prometheus → 异常检测算法 → Grafana看板  → 邮件
Promtail      → Loki       → 日志关键字匹配 → 告警联动   → 短信
kube-state    → Prometheus → 资源状态分析 → 容量预警

3. 指标监控采集部署

3.1 Prometheus部署

创建命名空间和配置:

kubectl create namespace monitoring

创建 prometheus-config.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
  namespace: monitoring
data:
  prometheus.yml: |
    global:
      scrape_interval: 15s
      evaluation_interval: 15s
      external_labels:
        cluster: k8s-prod

    alerting:
      alertmanagers:
      - static_configs:
        - targets:
          - alertmanager.monitoring.svc.cluster.local:9093

    rule_files:
      - /etc/prometheus/rules/*.yml

    scrape_configs:
      # Prometheus自身
      - job_name: 'prometheus'
        static_configs:
        - targets: ['localhost:9090']

      # node-exporter
      - job_name: 'node-exporter'
        kubernetes_sd_configs:
        - role: endpoints
        relabel_configs:
        - source_labels: [__meta_kubernetes_service_name]
          regex: node-exporter
          action: keep

      # kubelet
      - job_name: 'kubelet'
        kubernetes_sd_configs:
        - role: node
        scheme: https
        tls_config:
          ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
        relabel_configs:
        - action: labelmap
          regex: __meta_kubernetes_node_label_(.+)

      # cAdvisor (通过kubelet)
      - job_name: 'cadvisor'
        kubernetes_sd_configs:
        - role: node
        scheme: https
        metrics_path: /metrics/cadvisor
        tls_config:
          ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token

      # kube-state-metrics
      - job_name: 'kube-state-metrics'
        static_configs:
        - targets: ['kube-state-metrics.monitoring.svc.cluster.local:8080']

      # containerd (通过节点exporter或cRI)
      - job_name: 'containerd'
        static_configs:
        - targets: ['192.168.10.21:9091','192.168.10.22:9091','192.168.10.23:9091']

部署Prometheus:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prometheus
  template:
    metadata:
      labels:
        app: prometheus
    spec:
      serviceAccountName: prometheus
      containers:
      - name: prometheus
        image: harbor.local/monitoring/prometheus:v2.48.0
        args:
        - --config.file=/etc/prometheus/prometheus.yml
        - --storage.tsdb.path=/prometheus
        - --storage.tsdb.retention.time=15d
        - --storage.tsdb.retention.size=100GB
        - --web.enable-lifecycle
        ports:
        - containerPort: 9090
        volumeMounts:
        - name: config
          mountPath: /etc/prometheus
        - name: rules
          mountPath: /etc/prometheus/rules
        - name: storage
          mountPath: /prometheus
        resources:
          requests:
            cpu: "2"
            memory: 4Gi
          limits:
            cpu: "4"
            memory: 8Gi
      volumes:
      - name: config
        configMap:
          name: prometheus-config
      - name: rules
        configMap:
          name: prometheus-rules
      - name: storage
        persistentVolumeClaim:
          claimName: prometheus-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: prometheus
  namespace: monitoring
spec:
  selector:
    app: prometheus
  ports:
  - port: 9090
    targetPort: 9090
  type: NodePort

3.2 node-exporter部署

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter
  namespace: monitoring
spec:
  selector:
    matchLabels:
      app: node-exporter
  template:
    metadata:
      labels:
        app: node-exporter
    spec:
      hostNetwork: true
      hostPID: true
      containers:
      - name: node-exporter
        image: harbor.local/monitoring/node-exporter:v1.7.0
        args:
        - --path.procfs=/host/proc
        - --path.sysfs=/host/sys
        - --path.rootfs=/host/root
        - --collector.filesystem.mount-points-exclude=^/(dev|proc|sys|var/lib/docker/.+)($|/)
        - --collector.systemd
        - --collector.processes
        - --collector.tcpstat
        ports:
        - containerPort: 9100
          hostPort: 9100
        volumeMounts:
        - name: proc
          mountPath: /host/proc
          readOnly: true
        - name: sys
          mountPath: /host/sys
          readOnly: true
        - name: root
          mountPath: /host/root
          readOnly: true
      volumes:
      - name: proc
        hostPath:
          path: /proc
      - name: sys
        hostPath:
          path: /sys
      - name: root
        hostPath:
          path: /
---
apiVersion: v1
kind: Service
metadata:
  name: node-exporter
  namespace: monitoring
spec:
  selector:
    app: node-exporter
  ports:
  - port: 9100
    targetPort: 9100

3.3 cAdvisor与kubelet指标

cAdvisor已集成在kubelet中,通过 /metrics/cadvisor 端点采集。关键指标:

指标名

说明

container_memory_working_set_bytes

容器内存使用

container_network_receive_bytes_total

容器网络接收

container_network_transmit_bytes_total

容器网络发送

container_fs_usage_bytes

容器磁盘使用

container_last_seen

容器最后活跃时间

kubelet关键指标:

指标名

说明

kubelet_running_containers

运行中容器数

kubelet_pod_start_duration_seconds

Pod启动耗时

kubelet_cgroup_manager_duration_seconds

cgroup操作耗时

kubelet_pleg_relist_duration_seconds

PLEG耗时(过高表示运行时异常)

3.4 containerd指标采集

containerd内置Prometheus指标支持,需开启:

# 修改containerd配置,开启metrics
# /etc/containerd/config.toml
[metrics]
  address = "0.0.0.0:9091"
  grpc_histogram = true

# 重启containerd
systemctl restart containerd

# 验证指标
curl http://localhost:9091/v1/metrics | head -20

containerd关键指标:

指标名

说明

containerd_grpc_request_duration_seconds

gRPC请求耗时

containerd_snapshots_total

快照数量

containerd_content_total

内容存储数量

containerd_images_total

镜像数量

3.5 kube-state-metrics部署

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kube-state-metrics
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kube-state-metrics
  template:
    metadata:
      labels:
        app: kube-state-metrics
    spec:
      serviceAccountName: kube-state-metrics
      containers:
      - name: kube-state-metrics
        image: harbor.local/monitoring/kube-state-metrics:v2.10.0
        ports:
        - containerPort: 8080
        resources:
          requests:
            cpu: 100m
            memory: 256Mi
          limits:
            cpu: 500m
            memory: 512Mi
---
apiVersion: v1
kind: Service
metadata:
  name: kube-state-metrics
  namespace: monitoring
spec:
  selector:
    app: kube-state-metrics
  ports:
  - port: 8080
    targetPort: 8080

4. 日志采集与异常分析

4.1 Loki部署

apiVersion: apps/v1
kind: Deployment
metadata:
  name: loki
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: loki
  template:
    metadata:
      labels:
        app: loki
    spec:
      containers:
      - name: loki
        image: harbor.local/monitoring/loki:2.9.0
        args:
        - -config.file=/etc/loki/loki-config.yml
        ports:
        - containerPort: 3100
        volumeMounts:
        - name: config
          mountPath: /etc/loki
        - name: storage
          mountPath: /data/loki
        resources:
          requests:
            cpu: "1"
            memory: 2Gi
          limits:
            cpu: "2"
            memory: 4Gi
      volumes:
      - name: config
        configMap:
          name: loki-config
      - name: storage
        persistentVolumeClaim:
          claimName: loki-pvc
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: loki-config
  namespace: monitoring
data:
  loki-config.yml: |
    auth_enabled: false
    server:
      http_listen_port: 3100
    common:
      path_prefix: /data/loki
      storage:
        filesystem:
          chunks_directory: /data/loki/chunks
          rules_directory: /data/loki/rules
      replication_factor: 1
      ring:
        instance_addr: 127.0.0.1
        kvstore:
          store: inmemory
    query_range:
      results_cache:
        cache:
          enable_fifocache: true
          fifocache:
            max_size_items: 1024
            validity: 24h
    limits_config:
      retention_period: 168h
      max_query_length: 721h
      max_streams_per_user: 0
      reject_old_samples: true
      reject_old_samples_max_age: 168h
    schema_config:
      configs:
      - from: 2024-01-01
        store: tsdb
        object_store: filesystem
        schema: v13
        index:
          prefix: index_
          period: 24h

4.2 Promtail日志采集

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: promtail
  namespace: monitoring
spec:
  selector:
    matchLabels:
      app: promtail
  template:
    metadata:
      labels:
        app: promtail
    spec:
      serviceAccountName: promtail
      containers:
      - name: promtail
        image: harbor.local/monitoring/promtail:2.9.0
        args:
        - -config.file=/etc/promtail/promtail-config.yml
        volumeMounts:
        - name: config
          mountPath: /etc/promtail
        - name: logs
          mountPath: /var/log
          readOnly: true
        - name: containers
          mountPath: /var/log/containers
          readOnly: true
        - name: pods
          mountPath: /var/log/pods
          readOnly: true
        - name: journal
          mountPath: /var/log/journal
          readOnly: true
      volumes:
      - name: config
        configMap:
          name: promtail-config
      - name: logs
        hostPath:
          path: /var/log
      - name: containers
        hostPath:
          path: /var/log/containers
      - name: pods
        hostPath:
          path: /var/log/pods
      - name: journal
        hostPath:
          path: /var/log/journal
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: promtail-config
  namespace: monitoring
data:
  promtail-config.yml: |
    server:
      http_listen_port: 9080
      grpc_listen_port: 0
    positions:
      filename: /tmp/positions.yaml
    clients:
    - url: http://loki.monitoring.svc.cluster.local:3100/loki/api/v1/push
    scrape_configs:
    # 容器日志
    - job_name: kubernetes-pods
      pipeline_stages:
      - docker: {}
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - source_labels: ['__meta_kubernetes_pod_node_name']
        target_label: 'node'
      - source_labels: ['__meta_kubernetes_namespace']
        target_label: 'namespace'
      - source_labels: ['__meta_kubernetes_pod_name']
        target_label: 'pod'
      - source_labels: ['__meta_kubernetes_container_name']
        target_label: 'container'
      - replacement: '/var/log/pods/*$1/*.log'
        separator: /
        source_labels:
        - __meta_kubernetes_pod_uid
        - __meta_kubernetes_pod_container_name
        target_label: __path__
    # containerd系统日志
    - job_name: containerd-system
      static_configs:
      - targets: [localhost]
        labels:
          job: containerd
          __path__: /var/log/messages
      pipeline_stages:
      - match:
          selector: '{job="containerd"} |= "containerd"'
          stages:
          - labels:
              runtime: containerd
    # kubelet日志
    - job_name: kubelet-journal
      journal:
        json: false
        max_age: 7d
        path: /var/log/journal
        labels:
          job: kubelet
      relabel_configs:
      - source_labels: ['__journal__systemd_unit']
        target_label: 'unit'

4.3 运行时日志关键字监控

在Loki中配置告警规则,监控运行时异常关键字:

# /etc/loki/rules/fake/runtime-alerts.yml
groups:
- name: runtime-errors
  rules:
  - alert: ContainerdCriError
    expr: |
      count_over_time({job="containerd"} |= "error" |= "cri" [5m]) > 5
    for: 2m
    labels:
      severity: critical
    annotations:
      summary: "containerd CRI错误激增"
      description: "节点{{ $labels.node }} containerd CRI错误5分钟内超过5次"

  - alert: KubeletPlegHigh
    expr: |
      count_over_time({job="kubelet", unit="kubelet.service"} |= "PLEG" |= "unhealthy" [5m]) > 0
    for: 1m
    labels:
      severity: critical
    annotations:
      summary: "kubelet PLEG不健康"
      description: "节点{{ $labels.node }} kubelet PLEG异常,可能导致Pod无法调度"

  - alert: OomKilledDetected
    expr: |
      count_over_time({namespace=~".+"} |= "OOMKilled" [10m]) > 0
    for: 0m
    labels:
      severity: warning
    annotations:
      summary: "检测到OOMKilled"
      description: "Pod {{ $labels.pod }} 因OOM被杀死"

  - alert: CrashLoopBackOff
    expr: |
      count_over_time({namespace=~".+"} |= "CrashLoopBackOff" [5m]) > 0
    for: 1m
    labels:
      severity: warning
    annotations:
      summary: "Pod CrashLoopBackOff"
      description: "Pod {{ $labels.pod }} 进入CrashLoopBackOff状态"

4.4 日志异常模式匹配

常用异常日志模式:

异常模式

关键字

级别

CRI调用失败

failed to get sandbox / rpc error

P1

kubelet节点异常

PLEG is not healthy / runtime operation timed out

P0

镜像拉取失败

Failed to pull image / manifest unknown

P2

OOM内存溢出

OOMKilled / out of memory

P1

磁盘压力

disk pressure / image garbage collection

P1

网络异常

network plugin cni / failed to setup network

P1

调度失败

FailedScheduling / insufficient cpu/memory

P2

Loki查询示例:

# 查询所有运行时错误
{job=~"containerd|kubelet"} |= "error" != "EOF"

# 按节点统计错误数
sum by (node) (count_over_time({job="containerd"} |= "error" [1h]))

# 趋势对比(同比上周)
sum(count_over_time({namespace="prod"} |= "500" [1h]))
  /
sum(count_over_time({namespace="prod"} |= "500" [1h] offset 168h))

5. 运行时健康监控体系

5.1 containerd健康指标

# 查看containerd服务状态
systemctl is-active containerd
systemctl show containerd --property=NRestarts,ActiveEnterTimestamp

# 查看containerd指标
curl -s http://localhost:9091/v1/metrics | grep -E 'grpc_requests|grpc_request_duration'

# Prometheus查询
# containerd gRPC错误率
rate(containerd_grpc_requests_total{code=~"Internal|Unavailable|Unknown"}[5m])

# containerd gRPC延迟P99
histogram_quantile(0.99, rate(containerd_grpc_request_duration_seconds_bucket[5m]))

5.2 kubelet健康监控

# kubelet健康检查
curl -sk https://localhost:10250/healthz
# 应返回 ok

# kubelet就绪检查
curl -sk https://localhost:10250/readyz

# PLEG耗时(超过3s异常)
curl -sk https://localhost:10250/metrics | grep kubelet_pleg_relist_duration

# Prometheus告警表达式
# PLEG P99延迟 > 3s
histogram_quantile(0.99, rate(kubelet_pleg_relist_duration_seconds_bucket[5m])) > 3

# kubelet重启
changes(kubelet_running_pods[5m]) < 0 and time() - kubelet_node_start_timestamp < 300

5.3 节点资源趋势监控

关键Prometheus查询:

# CPU使用率(按节点)
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

# 内存使用率
100 * (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes))

# 磁盘使用率
100 - (100 * node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"})

# 磁盘IO等待
rate(node_pressure_io_waiting_seconds_total[5m])

# 网络接收速率
rate(node_network_receive_bytes_total{device!~"lo|cali.*|tunl0|vxlan"}[5m]) * 8

# 网络发送速率
rate(node_network_transmit_bytes_total{device!~"lo|cali.*|tunl0|vxlan"}[5m]) * 8

# TCP重传率
rate(node_netstat_Tcp_RetransSegs[5m]) / rate(node_netstat_Tcp_OutSegs[5m]) * 100

# conntrack使用率
node_nf_conntrack_entries / node_nf_conntrack_entries_limit * 100

5.4 Pod异常状态监控

# CrashLoopBackOff Pod数
sum(kube_pod_container_status_waiting_reason{reason="CrashLoopBackOff"}) by (namespace, pod)

# OOMKilled次数
increase(kube_pod_container_status_last_terminated_reason{reason="OOMKilled"}[1h])

# Pending Pod数(调度失败)
sum(kube_pod_status_phase{phase="Pending"}) by (namespace)

# 容器重启率(5分钟内重启>2次)
increase(kube_pod_container_status_restarts_total[5m]) > 2

# Pod不可用
sum(kube_pod_status_phase{phase=~"Failed|Unknown"}) by (namespace, pod)

# 容器CPU throttling(被限流)
rate(container_cpu_cfs_throttled_seconds_total[5m]) > 0

5.5 网络异常监控

# conntrack使用率 > 80%
node_nf_conntrack_entries / node_nf_conntrack_entries_limit > 0.8

# TCP重传率 > 5%
rate(node_netstat_Tcp_RetransSegs[5m]) / rate(node_netstat_Tcp_OutSegs[5m]) > 0.05

# 网卡丢包率
rate(node_network_receive_drop_total[5m]) > 10
rate(node_network_transmit_drop_total[5m]) > 10

# 连接数异常增长
increase(node_netstat_Tcp_CurrEstab[10m]) > 1000

# Calico节点异常
calico Felix健康检查失败数

6. 异常趋势分析模型

6.1 静态阈值告警

最基础的告警方式,适用于明确的资源上限:

- alert: NodeCpuHigh
  expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85
  for: 10m
  labels:
    severity: warning
  annotations:
    summary: "节点CPU使用率超过85%"

- alert: NodeMemoryCritical
  expr: 100 * (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) > 95
  for: 5m
  labels:
    severity: critical

6.2 动态基线告警

基于历史同期数据计算动态阈值,适用于业务有明显周期性的场景:

# 当前值 vs 上周同期基线(偏差>50%告警)
(
  avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m]))
  -
  avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m] offset 168h))
)
/
avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m] offset 168h))
> 0.5

6.3 同比环比趋势分析

# 环比(当前小时 vs 上一小时)
sum(rate(container_cpu_usage_seconds_total[1h]))
  /
sum(rate(container_cpu_usage_seconds_total[1h] offset 1h))

# 同比(当前 vs 上周同时段)
sum(rate(container_network_receive_bytes_total[1h]))
  /
sum(rate(container_network_receive_bytes_total[1h] offset 168h))

# 7日移动平均
avg_over_time((sum by(instance) (rate(node_cpu_seconds_total{mode!="idle"}[5m])))[7d:])

6.4 异常突变检测

使用3-sigma原则检测异常突变:

# 当前值偏离7日均值超过3倍标准差
(
  sum by(instance) (rate(node_cpu_seconds_total{mode!="idle"}[5m]))
  -
  avg_over_time((sum by(instance) (rate(node_cpu_seconds_total{mode!="idle"}[5m])))[7d:])
)
>
3 * stddev_over_time((sum by(instance) (rate(node_cpu_seconds_total{mode!="idle"}[5m])))[7d:])

6.5 容量趋势预测

线性回归预测资源耗尽时间:

# 磁盘使用率趋势预测(预测24小时后使用率)
predict_linear(node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"}[6h], 24*3600) < 0

# 内存耗尽预测(预测何时内存不足)
predict_linear(node_memory_MemAvailable_bytes[6h], 3600) < 0

# conntrack表满预测
predict_linear(node_nf_conntrack_entries[1h], 3600) > node_nf_conntrack_entries_limit * 0.95

# 按当前增长率预测磁盘满的时间(小时)
(node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"})
/
(-1 * deriv(node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"}[1h]))
/ 3600 < 24

7. 告警规则配置

7.1 运行时异常告警规则

创建 prometheus-rules.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-rules
  namespace: monitoring
data:
  runtime-alerts.yml: |
    groups:
    - name: runtime-health
      rules:
      # containerd服务异常
      - alert: ContainerdDown
        expr: up{job="containerd"} == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "containerd服务停止"
          description: "节点{{ $labels.instance }} containerd已停止超过1分钟"

      # containerd gRPC错误率
      - alert: ContainerdGrpcErrorHigh
        expr: |
          rate(containerd_grpc_requests_total{code=~"Internal|Unavailable|Unknown|DeadlineExceeded"}[5m])
          /
          rate(containerd_grpc_requests_total[5m]) > 0.05
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "containerd gRPC错误率过高"
          description: "节点{{ $labels.instance }} gRPC错误率超过5%"

      # containerd gRPC延迟
      - alert: ContainerdGrpcLatencyHigh
        expr: histogram_quantile(0.99, rate(containerd_grpc_request_duration_seconds_bucket[5m])) > 2
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "containerd gRPC延迟过高"
          description: "节点{{ $labels.instance }} P99延迟超过2秒"

      # kubelet异常
      - alert: KubeletDown
        expr: up{job="kubelet"} == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "kubelet服务停止"

      # PLEG异常
      - alert: KubeletPlegHighLatency
        expr: histogram_quantile(0.99, rate(kubelet_pleg_relist_duration_seconds_bucket[5m])) > 3
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "kubelet PLEG延迟过高"
          description: "节点{{ $labels.instance }} PLEG P99延迟超过3秒,Pod可能无法正常调度"

      # kubelet重启
      - alert: KubeletRestarted
        expr: changes(kubelet_node_start_timestamp[15m]) > 0
        for: 0m
        labels:
          severity: warning
        annotations:
          summary: "kubelet发生重启"

7.2 资源趋势告警规则

  resource-alerts.yml: |
    groups:
    - name: resource-trend
      rules:
      # CPU高
      - alert: NodeCpuUsageHigh
        expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "节点CPU使用率超过85%"
          description: "节点{{ $labels.instance }} CPU使用率{{ $value }}%"

      # CPU持续高(趋势)
      - alert: NodeCpuSustainedHigh
        expr: avg_over_time((100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100))[30m:]) > 80
        for: 30m
        labels:
          severity: critical
        annotations:
          summary: "节点CPU持续高负载"

      # 内存高
      - alert: NodeMemoryHigh
        expr: 100 * (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) > 90
        for: 10m
        labels:
          severity: warning

      # 磁盘即将满(预测)
      - alert: DiskWillFillIn24h
        expr: predict_linear(node_filesystem_avail_bytes{fstype!~"tmpfs|overlay",mountpoint="/"}[6h], 24*3600) < 0
        for: 1h
        labels:
          severity: critical
        annotations:
          summary: "磁盘预计24小时内写满"
          description: "节点{{ $labels.instance }} 根分区预计24小时内耗尽"

      # 磁盘使用率高
      - alert: NodeDiskHigh
        expr: 100 - (100 * node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"}) > 85
        for: 10m
        labels:
          severity: warning

      # 内存耗尽预测
      - alert: MemoryWillExhaust
        expr: predict_linear(node_memory_MemAvailable_bytes[6h], 3600) < 0
        for: 15m
        labels:
          severity: critical
        annotations:
          summary: "内存预计1小时内耗尽"

7.3 网络异常告警规则

  network-alerts.yml: |
    groups:
    - name: network-anomaly
      rules:
      # conntrack使用率
      - alert: ConntrackHigh
        expr: node_nf_conntrack_entries / node_nf_conntrack_entries_limit > 0.8
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "conntrack使用率超过80%"

      # conntrack即将满(预测)
      - alert: ConntrackWillFull
        expr: predict_linear(node_nf_conntrack_entries[1h], 1800) > node_nf_conntrack_entries_limit * 0.95
        for: 10m
        labels:
          severity: critical

      # TCP重传率
      - alert: TcpRetransHigh
        expr: rate(node_netstat_Tcp_RetransSegs[5m]) / rate(node_netstat_Tcp_OutSegs[5m]) > 0.05
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "TCP重传率超过5%"

      # 网卡丢包
      - alert: NetworkPacketLoss
        expr: rate(node_network_receive_drop_total[5m]) > 10 or rate(node_network_transmit_drop_total[5m]) > 10
        for: 5m
        labels:
          severity: warning

      # 网络带宽跑满
      - alert: NetworkBandwidthFull
        expr: (rate(node_network_receive_bytes_total{device!~"lo|cali.*|tunl0|vxlan"}[5m]) * 8) > (node_network_speed_bytes{device!~"lo|cali.*|tunl0|vxlan"} * 0.9 * 8)
        for: 10m
        labels:
          severity: warning

7.4 告警分级与抑制

级别

触发条件

响应时间

通知方式

P1 Warning

性能下降、资源预警

30分钟

钉钉+邮件

P2 Info

趋势异常、容量预测

2小时

邮件+看板

告警抑制规则(Alertmanager):

inhibit_rules:
# P0告警抑制同节点P1/P2告警
- source_match:
    severity: critical
  target_match:
    severity: warning
  equal: ['instance', 'alertname']
# 节点宕机抑制该节点所有Pod告警
- source_match:
    alertname: NodeDown
  target_match_re:
    alertname: 'Pod.*'
  equal: ['instance']

8. Alertmanager告警通知

8.1 Alertmanager部署

apiVersion: apps/v1
kind: Deployment
metadata:
  name: alertmanager
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: alertmanager
  template:
    metadata:
      labels:
        app: alertmanager
    spec:
      containers:
      - name: alertmanager
        image: harbor.local/monitoring/alertmanager:v0.26.0
        args:
        - --config.file=/etc/alertmanager/alertmanager.yml
        - --storage.path=/alertmanager
        - --web.external-url=http://alertmanager:9093
        ports:
        - containerPort: 9093
        volumeMounts:
        - name: config
          mountPath: /etc/alertmanager
        - name: storage
          mountPath: /alertmanager
      volumes:
      - name: config
        configMap:
          name: alertmanager-config
      - name: storage
        emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
  name: alertmanager
  namespace: monitoring
spec:
  selector:
    app: alertmanager
  ports:
  - port: 9093
    targetPort: 9093

8.2 告警路由配置

apiVersion: v1
kind: ConfigMap
metadata:
  name: alertmanager-config
  namespace: monitoring
data:
  alertmanager.yml: |
    global:
      resolve_timeout: 5m
      # 企业微信webhook
      wechat_api_url: 'https://qyapi.weixin.qq.com/cgi-bin/'
      wechat_api_secret: '<企业微信Secret>'
      wechat_api_corp_id: '<企业ID>'

    route:
      group_by: ['alertname', 'cluster', 'instance']
      group_wait: 10s
      group_interval: 5m
      repeat_interval: 4h
      receiver: 'default'
      routes:
      # P0告警立即通知
      - match:
          severity: critical
        receiver: 'critical-webhook'
        group_wait: 0s
        repeat_interval: 1h
      # P1告警
      - match:
          severity: warning
        receiver: 'warning-dingtalk'
        repeat_interval: 4h
      # P2告警
      - match:
          severity: info
        receiver: 'info-email'
        repeat_interval: 12h

    receivers:
    - name: 'default'
      webhook_configs:
      - url: 'http://alertmanager-webhook.monitoring.svc.cluster.local:8080/webhook'

    - name: 'critical-webhook'
      webhook_configs:
      - url: 'http://alertmanager-webhook.monitoring.svc.cluster.local:8080/critical'
        send_resolved: true

    - name: 'warning-dingtalk'
      webhook_configs:
      - url: 'http://alertmanager-webhook.monitoring.svc.cluster.local:8080/dingtalk'
        send_resolved: true

    - name: 'info-email'
      email_configs:
      - to: 'ops@company.com'
        from: 'alert@company.com'
        smarthost: 'smtp.company.com:587'
        auth_username: 'alert@company.com'
        auth_password: '<邮箱密码>'
        send_resolved: true

    inhibit_rules:
    - source_match:
        severity: critical
      target_match:
        severity: warning
      equal: ['instance']

8.3 钉钉/企业微信通知

部署Webhook转发服务(支持钉钉和企业微信):

#!/usr/bin/env python3
# alertmanager-webhook.py
from flask import Flask, request
import requests
import json

app = Flask(__name__)

DINGTALK_WEBHOOK = "https://oapi.dingtalk.com/robot/send?access_token=<token>"
WECHAT_WEBHOOK = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=<key>"

def send_dingtalk(alert):
    severity = alert['labels'].get('severity', 'unknown')
    emoji = "🔴" if severity == "critical" else "��" if severity == "warning" else "🔵"
    content = f"""{emoji} **{alert['annotations'].get('summary', '告警')}**
> 级别: {severity}
> 节点: {alert['labels'].get('instance', 'N/A')}
> 描述: {alert['annotations'].get('description', 'N/A')}
> 时间: {alert['startsAt']}"""
    
    data = {
        "msgtype": "markdown",
        "markdown": {"title": "K8s告警", "text": content}
    }
    requests.post(DINGTALK_WEBHOOK, json=data)

def send_wechat(alert):
    severity = alert['labels'].get('severity', 'unknown')
    content = f"[{severity.upper()}] {alert['annotations'].get('summary', '告警')}\n节点: {alert['labels'].get('instance', 'N/A')}\n描述: {alert['annotations'].get('description', 'N/A')}"
    data = {"msgtype": "text", "text": {"content": content}}
    requests.post(WECHAT_WEBHOOK, json=data)

@app.route('/webhook', methods=['POST'])
def webhook():
    data = request.json
    for alert in data.get('alerts', []):
        if alert['status'] == 'firing':
            send_dingtalk(alert)
            send_wechat(alert)
    return "ok"

@app.route('/critical', methods=['POST'])
def critical():
    data = request.json
    for alert in data.get('alerts', []):
        if alert['status'] == 'firing':
            send_dingtalk(alert)
            send_wechat(alert)
    return "ok"

@app.route('/dingtalk', methods=['POST'])
def dingtalk():
    data = request.json
    for alert in data.get('alerts', []):
        if alert['status'] == 'firing':
            send_dingtalk(alert)
    return "ok"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)

8.4 告警聚合与抑制

# 同一告警分组聚合(避免告警风暴)
route:
  group_by: ['alertname', 'cluster']
  group_wait: 30s      # 首次告警等待30s,聚合同组告警
  group_interval: 5m   # 同组新告警间隔5分钟
  repeat_interval: 4h  # 重复告警间隔4小时

# 静默规则(维护期间静默)
# 通过Alertmanager API创建
# curl -X POST http://alertmanager:9093/api/v2/silences -d '{
#   "matchers": [{"name":"severity","value":"warning","isRegex":false}],
#   "startsAt": "2026-08-18T22:00:00.000Z",
#   "endsAt": "2026-08-19T02:00:00.000Z",
#   "createdBy": "ops",
#   "comment": "夜间维护窗口"
# }'

9. Grafana可视化看板

9.1 Grafana部署与配置

apiVersion: apps/v1
kind: Deployment
metadata:
  name: grafana
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: grafana
  template:
    metadata:
      labels:
        app: grafana
    spec:
      containers:
      - name: grafana
        image: harbor.local/monitoring/grafana:10.2.0
        ports:
        - containerPort: 3000
        env:
        - name: GF_SECURITY_ADMIN_PASSWORD
          value: "Grafana@2026"
        - name: GF_USERS_ALLOW_SIGN_UP
          value: "false"
        volumeMounts:
        - name: storage
          mountPath: /var/lib/grafana
        - name: datasources
          mountPath: /etc/grafana/provisioning/datasources
        resources:
          requests:
            cpu: 500m
            memory: 1Gi
          limits:
            cpu: "2"
            memory: 2Gi
      volumes:
      - name: storage
        persistentVolumeClaim:
          claimName: grafana-pvc
      - name: datasources
        configMap:
          name: grafana-datasources
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: grafana-datasources
  namespace: monitoring
data:
  datasources.yml: |
    apiVersion: 1
    datasources:
    - name: Prometheus
      type: prometheus
      access: proxy
      url: http://prometheus.monitoring.svc.cluster.local:9090
      isDefault: true
    - name: Loki
      type: loki
      access: proxy
      url: http://loki.monitoring.svc.cluster.local:3100

9.2 运行时总览看板

关键面板配置:

面板

查询语句

图表类型

containerd状态

up{job="containerd"}

Stat

kubelet状态

up{job="kubelet"}

Stat

集群CPU使用率

100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

Gauge

集群内存使用率

100 * (1 - (sum(node_memory_MemAvailable_bytes) / sum(node_memory_MemTotal_bytes)))

Gauge

集群磁盘使用率

100 - (100 * sum(node_filesystem_avail_bytes{mountpoint="/"}) / sum(node_filesystem_size_bytes{mountpoint="/"}))

Gauge

Pod总数

sum(kube_pod_status_phase{phase="Running"})

Stat

异常Pod数

`sum(kube_pod_status_phase{phase=~"Failed

Pending

运行时重启数

increase(kube_pod_container_status_restarts_total[1h])

Table

9.3 趋势分析看板

面板

查询语句

图表类型

内存趋势(7天)

100 * (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes))

Time series

网络入流量趋势

`rate(node_network_receive_bytes_total{device!~"lo

.*cali.*

网络出流量趋势

`rate(node_network_transmit_bytes_total{device!~"lo

.*cali.*

conntrack趋势

node_nf_conntrack_entries / node_nf_conntrack_entries_limit * 100

Time series

TCP连接数趋势

node_netstat_Tcp_CurrEstab

Time series

磁盘IO趋势

rate(node_disk_io_time_seconds_total[5m]) * 100

Time series

同比对比

当前值 / 上周同期值

Time series

9.4 异常告警看板

面板

内容

告警趋势(24h)

按级别统计告警数

TOP10告警源

按instance/alertname统计

告警响应时长

从firing到resolved的时间差

告警静默列表

当前生效的silence

P0告警历史

critical级别告警记录

10. 趋势预测与容量预警

10.1 资源使用趋势预测

# CPU使用率线性回归预测(1小时后)
predict_linear(
  (100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100))[6h:],
  3600
)

# 内存使用预测(2小时后)
predict_linear(
  (100 * (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)))[6h:],
  7200
)

# 基于7天数据的趋势预测
predict_linear(
  (sum by(instance) (rate(node_cpu_seconds_total{mode!="idle"}[1h])))[7d:],
  86400
)

10.2 磁盘容量预警

# 节点磁盘监控脚本(配合cron定时执行)
#!/bin/bash
THRESHOLD=80
for node in $(kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="InternalIP")].address}'); do
  USAGE=$(ssh root@${node} "df -h / | awk 'NR==2{print \$5}' | tr -d '%'")
  if [ ${USAGE} -gt ${THRESHOLD} ]; then
    # 计算按当前增速耗尽时间
    REMAIN=$(ssh root@${node} "df -B1 / | awk 'NR==2{print \$4}'")
    GROWTH=$(ssh root@${node} "cat /tmp/disk_growth_rate")
    HOURS_LEFT=$((REMAIN / GROWTH / 3600))
    echo "WARN: ${node} 磁盘使用率${USAGE}%, 预计${HOURS_LEFT}小时后耗尽"
    # 发送告警...
  fi
done

Prometheus磁盘预测告警:

- alert: DiskPredictionCritical
  expr: |
    predict_linear(node_filesystem_avail_bytes{fstype!~"tmpfs|overlay",mountpoint="/"}[6h], 86400) < 0
  for: 30m
  labels:
    severity: critical
  annotations:
    summary: "磁盘预计24小时内写满"
    description: "节点{{ $labels.instance }} 根分区按当前增速预计24小时内耗尽,请立即清理"

- alert: DiskPredictionWarning
  expr: |
    predict_linear(node_filesystem_avail_bytes{fstype!~"tmpfs|overlay",mountpoint="/"}[24h], 259200) < 0
  for: 1h
  labels:
    severity: warning
  annotations:
    summary: "磁盘预计3天内写满"

10.3 连接数趋势预警

# conntrack表满预测(30分钟内超过95%)
predict_linear(node_nf_conntrack_entries[1h], 1800) > node_nf_conntrack_entries_limit * 0.95

# TCP连接数异常增长(1小时内增长超过50%)
(
  node_netstat_Tcp_CurrEstab
  -
  node_netstat_Tcp_CurrEstab offset 1h
)
/
node_netstat_Tcp_CurrEstab offset 1h > 0.5

# 容器网络连接数趋势
sum by(pod) (rate(container_network_tcp_connections_total[5m]))

10.4 自动化容量扩缩容建议

基于趋势数据生成扩容建议:

#!/bin/bash
# 容量评估脚本
echo "========== K8s集群容量评估报告 =========="
echo "生成时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo ""

# 1. CPU容量
CPU_TOTAL=$(kubectl get nodes -o jsonpath='{.items[*].status.capacity.cpu}' | tr ' ' '\n' | awk '{sum+=$1}END{print sum}')
CPU_USED=$(kubectl top nodes --no-headers | awk '{sum+=$3}END{print sum}' | tr -d '%')
echo "[CPU] 总核数: ${CPU_TOTAL}, 已用: ${CPU_USED}%"

# 2. 内存容量
MEM_TOTAL=$(kubectl get nodes -o jsonpath='{.items[*].status.capacity.memory}' | tr ' ' '\n' | sed 's/Ki//' | awk '{sum+=$1}END{print sum/1024/1024 "Gi"}')
MEM_USED=$(kubectl top nodes --no-headers | awk '{sum+=$5}END{print sum}' | tr -d '%')
echo "[内存] 总量: ${MEM_TOTAL}, 已用: ${MEM_USED}%"

# 3. Pod容量
POD_TOTAL=$(kubectl get nodes -o jsonpath='{.items[*].status.capacity.pods}' | tr ' ' '\n' | awk '{sum+=$1}END{print sum}')
POD_USED=$(kubectl get pods -A --no-headers | wc -l)
echo "[Pod] 总容量: ${POD_TOTAL}, 已用: ${POD_USED} ($((POD_USED*100/POD_TOTAL))%)"

# 4. 扩容建议
echo ""
echo "========== 扩容建议 =========="
if [ ${CPU_USED} -gt 70 ]; then
  echo "⚠ CPU使用率超过70%,建议新增Worker节点"
fi
if [ ${MEM_USED} -gt 70 ]; then
  echo "⚠ 内存使用率超过70%,建议新增Worker节点"
fi
if [ $((POD_USED*100/POD_TOTAL)) -gt 75 ]; then
  echo "⚠ Pod容量使用率超过75%,建议新增Worker节点"
fi
echo "✅ 容量评估完成"

11. 应急响应流程

11.1 告警分级响应矩阵

级别

告警类型

响应时间

处理人

升级条件

P1

CPU/内存>90%、磁盘预测24h满、OOM、PLEG异常

30分钟

值班SRE

1小时未解决→技术负责人

P2

CPU/内存>80%、TCP重传高、调度失败、趋势异常

2小时

SRE团队

4小时未解决→技术负责人

P3

容量预测、日志异常、性能基线偏离

工作日

SRE团队

-

11.2 运行时异常应急处理

containerd停止应急:

# 1. 确认状态
systemctl status containerd
crictl info

# 2. 查看日志
journalctl -u containerd -n 200 --no-pager

# 3. 尝试重启
systemctl restart containerd

# 4. 如重启失败,检查配置
containerd config dump > /dev/null

# 5. 检查残留进程
ps aux | grep containerd
ss -lntp | grep containerd.sock

# 6. 紧急恢复(清理残留后重启)
rm -f /run/containerd/containerd.sock
systemctl restart containerd

# 7. 验证恢复
crictl ps
kubectl get nodes

节点NotReady应急:

# 1. 确认节点状态
kubectl get nodes
kubectl describe node <node-name>

# 2. 检查kubelet
systemctl status kubelet
journalctl -u kubelet -n 100

# 3. 检查containerd
systemctl status containerd
crictl info

# 4. 检查资源
free -h
df -h
dmesg | tail -50

# 5. 紧急驱逐(如节点无法恢复)
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data --force

# 6. 恢复后重新调度
kubectl uncordon <node-name>

11.3 自动化自愈脚本

#!/bin/bash
# k8s-node-auto-heal.sh
# 节点自动健康检查与自愈

LOGFILE="/var/log/k8s-heal.log"

log() {
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> ${LOGFILE}
}

# 1. containerd健康检查
if ! systemctl is-active containerd > /dev/null; then
  log "containerd未运行,尝试重启..."
  systemctl restart containerd
  sleep 5
  if systemctl is-active containerd > /dev/null; then
    log "containerd重启成功"
  else
    log "containerd重启失败,需人工介入"
    # 发送告警...
  fi
fi

# 2. kubelet健康检查
if ! systemctl is-active kubelet > /dev/null; then
  log "kubelet未运行,尝试重启..."
  systemctl restart kubelet
fi

# 3. 磁盘空间检查
DISK_USAGE=$(df / | awk 'NR==2{print $5}' | tr -d '%')
if [ ${DISK_USAGE} -gt 90 ]; then
  log "磁盘使用率${DISK_USAGE}%,执行清理..."
  # 清理containerd未使用镜像
  crictl rmi --prune
  # 清理journal日志
  journalctl --vacuum-size=500M
  # 清理/tmp
  find /tmp -type f -atime +7 -delete
fi

# 4. conntrack检查
CT_COUNT=$(sysctl -n net.netfilter.nf_conntrack_count)
CT_MAX=$(sysctl -n net.netfilter.nf_conntrack_max)
if [ $((CT_COUNT * 100 / CT_MAX)) -gt 90 ]; then
  log "conntrack使用率过高,调大上限..."
  sysctl -w net.netfilter.nf_conntrack_max=2097152
fi

# 5. OOM Pod检查
OOM_PODS=$(crictl ps -a | grep OOMKilled | wc -l)
if [ ${OOM_PODS} -gt 0 ]; then
  log "检测到${OOM_PODS}个OOMKilled容器"
fi

配置定时执行:

# 每5分钟执行一次
chmod +x /opt/k8s-node-auto-heal.sh
(crontab -l 2>/dev/null; echo "*/5 * * * * /opt/k8s-node-auto-heal.sh") | crontab -

11.4 事后复盘与规则优化

复盘模板:

【告警复盘报告】
告警名称:
发生时间:
恢复时间:
持续时长:
影响范围:
根本原因:
处理过程:
改进措施:
  1. 短期(立即执行):
  2. 中期(1周内):
  3. 长期(1月内):
告警规则优化:
  - 阈值调整:
  - 新增告警:
  - 移除误报告警:

更多推荐