Chaos Agent

2 阅读14分钟

Chaos Agent 工作流程报告

📋 目录


1. 概述

1.1 Agent 是什么?

Chaos Redis Analyzer Agent 是一个基于 LangGraph 框架构建的智能故障分析系统。它的主要职责是:

┌─────────────────────────────────────────────────────────────┐
│                    Chaos Redis Analyzer                      │
│                                                              │
│  1. 在 Kubernetes 环境中注入混沌故障(如 Pod 杀死、网络延迟等)    │
│  2. 监控故障注入后的系统状态变化                                 │
│  3. 收集日志、事件、追踪数据                                    │
│  4. 智能分析故障表现是否合理                                    │
│  5. 生成详细的分析报告                                         │
└─────────────────────────────────────────────────────────────┘

1.2 为什么需要这个 Agent?

在生产环境中,我们需要验证系统的容错能力。比如:

  • 当一个 Redis Pod 被意外杀死后,系统能否自动恢复?
  • 网络延迟发生时,应用是否能正确处理超时?

这个 Agent 就是自动化执行这类混沌工程测试的智能助手。


2. 整体架构

2.1 技术栈

组件用途
LangGraph工作流编排框架,定义节点和边
Pydantic数据模型验证
AsyncIO异步执行,提高效率
MCP ToolsKubernetes 资源操作
Chaos Mesh故障注入平台

2.2 工作流图

                                    ┌──────────────────────────────────────┐
                                    │              工作流总览               │
                                    └──────────────────────────────────────┘
                                                      │
                                                      ▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│                              1. init_context                                     │
│                         【状态初始化和信息收集】                                    │
│                    验证命名空间、获取所有运行中的 Pod                               │
└─────────────────────────────────────────────────────────────────────────────────┘
                                                      │
                                                      ▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│                    2. pre_injection_data_plane_validation                        │
│                         【故障注入前数据面验证】                                   │
│              部署验证 Pod、执行基准测试、建立故障前基线                             │
└─────────────────────────────────────────────────────────────────────────────────┘
                                                      │
                                                      ▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│                           3. inject_fault                                        │
│                            【故障注入执行】                                        │
│                  调用 Chaos Mesh 执行故障注入操作                                  │
└─────────────────────────────────────────────────────────────────────────────────┘
                                                      │
                                                      ▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│                         4. verify_injection                                      │
│                           【故障注入验证】                                         │
│                      检查故障注入是否成功完成                                       │
└─────────────────────────────────────────────────────────────────────────────────┘
                                                      │
                              ┌───────────────────────┼───────────────────────┐
                              │                       │                       │
                              ▼                       ▼                       ▼
                        ┌──────────┐           ┌──────────┐           ┌──────────┐
                        │ success  │           │ running  │           │  failed  │
                        │  成功    │           │  运行中   │           │  失败    │
                        └──────────┘           └──────────┘           └──────────┘
                              │                       │                       │
                              │                       ▼                       │
                              │              ┌──────────────┐                │
                              │              │  wait_retry  │                │
                              │              │  等待重试    │                │
                              │              └──────────────┘                │
                              │                       │                       │
                              │                       └──────► verify_injection │
                              │                                         (重试)
                              ▼                                                       │
┌─────────────────────────────────────────────────────────────────────────────────┐
│                         5. monitor_data_plane                                    │
│                           【数据面监控】                                           │
│              收集 Pod 状态变化、资源趋势、数据面日志、K8s 事件                       │
└─────────────────────────────────────────────────────────────────────────────────┘
                                                      │
                                                      ▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│                           6. collect_trace                                       │
│                          【分布式追踪收集】                                         │
│                   收集目标 Pod 和辅助 Pod 的追踪数据                               │
└─────────────────────────────────────────────────────────────────────────────────┘
                                                      │
                                                      ▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│                             7. analyze                                           │
│                            【智能分析】                                            │
│              基于规则引擎和 LLM 分析故障表现是否合理                                │
└─────────────────────────────────────────────────────────────────────────────────┘
                                                      │
                                                      ▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│                             8. report                                            │
│                          【最终报告生成】                                          │
│                汇总所有分析结果,生成 JSON 格式报告文件                              │
└─────────────────────────────────────────────────────────────────────────────────┘
                                                      │
                                                      ▼
                                                    【END

3. 核心组件详解

3.1 状态模型 (ChaosAnalysisState)

状态模型是整个工作流的"大脑",存储所有节点的输入输出数据:

class ChaosAnalysisState(BaseModel):
    """Agent 的状态容器 - 所有节点共享这个状态"""
    
    # ========== 输入参数 ==========
    target_namespace: str           # 目标命名空间(必需)
    target_pod_label: Optional[str] # Pod 标签选择器,如 "app=redis"
    target_pod_name: Optional[str]  # 指定的 Pod 名称
    fault_type: str                 # 故障类型,如 "pod-kill"
    fault_params: Dict[str, Any]    # 故障参数,如 {"duration": "60s"}
    
    # ========== 数据面验证配置 ==========
    data_plane_cluster_host: Optional[str]  # Redis 服务主机地址
    data_plane_redis_type: Optional[str]    # Redis 类型 (proxy/unproxy)
    data_plane_test_type: Optional[str]     # 测试类型 (consistency/performance)
    data_plane_timeout: Optional[int]       # 超时时间(秒)
    
    # ========== 处理过程中的数据 ==========
    cluster_info: Optional[Dict[str, Any]]           # 集群信息
    target_pods: Optional[List[Dict[str, Any]]]      # 目标 Pod 列表
    primary_target_pods: Optional[List[Dict]]        # 主要故障目标 Pod
    auxiliary_pods: Optional[List[Dict[str, Any]]]   # 辅助 Pod(拓扑上下文)
    all_pods: Optional[List[Dict[str, Any]]]         # 所有 Pod
    injection_id: Optional[str]                       # 故障注入 ID
    injection_status: Optional[str]                   # 注入状态
    retry_count: int = 0                              # 重试计数
    
    # ========== 收集的数据 ==========
    data_plane_validation_results: Optional[Dict]    # 数据面验证结果
    k8s_events: Optional[List[Dict[str, Any]]]       # K8s 事件
    pod_state_changes: Optional[Dict[str, Any]]      # Pod 状态变化
    traces: Optional[Dict[str, Any]]                 # 追踪数据
    pre_injection_validation: Optional[Dict]         # 预注入验证结果
    pre_injection_baseline: Optional[Dict]           # 预注入基线数据
    
    # ========== 分析结果 ==========
    analysis_result: Optional[Dict[str, Any]]        # 分析结果
    final_report: Optional[str]                      # 最终报告
    error: Optional[str]                             # 错误信息

小贴士:可以把状态模型想象成一个"共享笔记本",每个节点(函数)都可以读取和写入这个笔记本。

3.2 代理组件 (Agents)

Agent 依赖三个核心代理组件来执行具体操作:

┌─────────────────────────────────────────────────────────────────┐
│                         Agent 依赖关系                           │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   ┌─────────────┐   ┌─────────────┐   ┌─────────────────────┐  │
│   │  K8sAgent   │   │ ChaosAgent  │   │  DataPlaneAgent     │  │
│   │             │   │             │   │                     │  │
│   │ • list_pods │   │ • inject_   │   │ • deploy_validation │  │
│   │ • list_ns   │   │   fault     │   │   _pod              │  │
│   │ • get_pod   │   │ • check_    │   │ • execute_data_     │  │
│   │   _details  │   │   injection │   │   plane_test        │  │
│   │ • collect   │   │   _status   │   │ • query_logs        │  │
│   │   _traces   │   │             │   │                     │  │
│   │ • list_     │   │             │   │                     │  │
│   │   events    │   │             │   │                     │  │
│   └─────────────┘   └─────────────┘   └─────────────────────┘  │
│                                                                 │
│   用于 K8s 资源     用于 Chaos Mesh     用于数据面验证           │
│   查询和操作        故障注入            和日志收集               │
└─────────────────────────────────────────────────────────────────┘

3.3 智能分析器 (IntelligentFaultAnalyzer)

智能分析器是 Agent 的"大脑",负责:

  1. 规则引擎分析:基于预设规则判断故障表现
  2. LLM 增强分析:调用大语言模型进行深度推理
  3. 综合评估:给出置信度和建议
# 使用工厂模式获取分析器实例(解决竞态条件问题)
class AnalyzerFactory:
    _instance: Optional[IntelligentFaultAnalyzer] = None
    _lock = asyncio.Lock()
    
    @classmethod
    async def get_analyzer(cls) -> IntelligentFaultAnalyzer:
        """获取线程安全的分析器实例"""
        if cls._instance is None:
            async with cls._lock:
                if cls._instance is None:  # 双重检查锁定
                    cls._instance = IntelligentFaultAnalyzer()
        return cls._instance

4. 工作节点详解

4.1 节点 1:init_context(状态初始化)

职责:验证环境、收集所有 Pod 信息

┌──────────────────────────────────────────────────────────────┐
│                    init_context 工作流程                      │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  Step 1: 验证命名空间是否存在                                  │
│          └── 调用 k8s_agent.list_namespaces()                │
│                                                              │
│  Step 2: 获取所有运行中的 Pod                                  │
│          └── 调用 k8s_agent.list_pods(ns, "status.phase=Running") │
│                                                              │
│  Step 3: 区分主要目标 Pod 和辅助 Pod                           │
│          ├── 主要目标:符合 label 或 name 指定的 Pod          │
│          └── 辅助 Pod:命名空间中的其他 Pod(用于拓扑分析)     │
│                                                              │
│  Step 4: 丰富 Pod 数据                                        │
│          └── 调用 _enrich_pod_data() 获取详细信息:            │
│              ├── 状态(phase、ready、restarts)               │
│              ├── 资源使用(CPU、内存)                         │
│              ├── Top 指标                                     │
│              └── 环境变量                                     │
│                                                              │
│  输出:cluster_info, target_pods, primary_target_pods,       │
│        auxiliary_pods, all_pods                              │
└──────────────────────────────────────────────────────────────┘

关键代码解析

@ErrorHandler.safe_node_execution("init_context", required_state_fields=["target_namespace"])
async def init_context(state: ChaosAnalysisState) -> Dict[str, Any]:
    # 1. 验证命名空间
    namespaces = await k8s_agent.list_namespaces()
    if ns not in namespaces:
        return ErrorHandler.create_error(...)  # 命名空间不存在
    
    # 2. 获取所有运行中的 Pod
    all_pods = await k8s_agent.list_pods(ns, field_selector="status.phase=Running")
    
    # 3. 区分主要目标和辅助 Pod
    primary_target_pods = []
    if state.target_pod_name:
        primary_target_pods = [p for p in all_pods if get_pod_name(p) == state.target_pod_name]
    elif state.target_pod_label and "=" in state.target_pod_label:
        k, v = state.target_pod_label.split("=", 1)
        primary_target_pods = [p for p in all_pods 
                               if p.get('metadata', {}).get('labels', {}).get(k) == v]
    
    # 4. 丰富 Pod 数据(获取详细状态、资源使用等)
    for pod in primary_target_pods:
        enriched_pod = await _enrich_pod_data(pod, ns, k8s_agent)
        enriched_pod["analysis_role"] = "primary_target"
        enriched_target_pods.append(enriched_pod)
    
    return {
        "cluster_info": {...},
        "target_pods": enriched_target_pods,
        "primary_target_pods": enriched_target_pods,
        "auxiliary_pods": enriched_auxiliary_pods,
        "all_pods": ...
    }

4.2 节点 2:pre_injection_data_plane_validation(预注入验证)

职责:在故障注入前验证数据面正常,建立基线

┌──────────────────────────────────────────────────────────────┐
│             pre_injection_data_plane_validation 工作流程      │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  检查:是否配置了 data_plane_cluster_host?                    │
│          │                                                   │
│          ├── 否 → 跳过验证,返回 {"status": "skipped"}        │
│          │                                                   │
│          └── 是 → 继续执行验证                                │
│                                                              │
│  Step 1: 检查命名空间是否存在                                  │
│                                                              │
│  Step 2: 自动发现数据面验证 Pod 名称                           │
│          └── 调用 _discover_data_plane_pod_name()            │
│              尝试常见名称模式:                                │
│              • data-plane-redis-0 (StatefulSet)              │
│              • data-plane-redis (普通 Pod)                    │
│              • redis-data-plane-0                            │
│                                                              │
│  Step 3: 检查 Pod 是否存在且镜像一致                           │
│          └── 调用 data_plane_agent.check_pod_exists_validation() │
│                                                              │
│  Step 4: 如需要则部署/重新部署 Pod                             │
│          └── 调用 data_plane_agent.deploy_validation_pod_if_needed() │
│                                                              │
│  Step 5: 执行数据面测试                                        │
│          └── 调用 data_plane_agent.execute_data_plane_test_validation() │
│              测试类型:consistency(一致性)或 performance(性能)│
│                                                              │
│  输出:pre_injection_validation, pre_injection_baseline      │
└──────────────────────────────────────────────────────────────┘

4.3 节点 3:inject_fault(故障注入)

职责:调用 Chaos Mesh 执行故障注入

┌──────────────────────────────────────────────────────────────┐
│                    inject_fault 工作流程                      │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  Step 1: 准备故障注入目标                                      │
│          target = {                                          │
│              "namespace": state.target_namespace,            │
│              "pods": [state.target_pod_name],  # 如果指定    │
│              "label_selector": state.target_pod_label  # 如果指定 │
│          }                                                   │
│                                                              │
│  Step 2: 调用 Chaos Agent 执行注入                            │
│          result = await chaos_agent.inject_fault(            │
│              state.fault_type,   # 如 "pod-kill"             │
│              target,              # 目标配置                  │
│              state.fault_params   # 如 {"duration": "60s"}   │
│          )                                                   │
│                                                              │
│  输出:injection_id, injection_status="initiated"            │
└──────────────────────────────────────────────────────────────┘

支持的故障类型

故障类型说明
pod-kill杀死 Pod
pod-failurePod 故障模拟
container-kill杀死容器
network-delay网络延迟
network-loss网络丢包
network-partition网络分区
cpu-stressCPU 压力
memory-stress内存压力
io-stressIO 压力

4.4 节点 4:verify_injection(注入验证)

职责:验证故障注入是否成功

┌──────────────────────────────────────────────────────────────┐
│                   verify_injection 工作流程                   │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  Step 1: 检查 injection_id 是否存在                           │
│          └── 不存在则返回错误                                  │
│                                                              │
│  Step 2: 查询注入状态                                         │
│          status_result = await chaos_agent.check_injection_status( │
│              state.injection_id                              │
│          )                                                   │
│                                                              │
│  Step 3: 标准化状态值                                         │
│          ├── "success", "completed", "finished""success"  │
│          ├── "failed", "error", "failure""failed"         │
│          └── "running", "in_progress", "pending""running" │
│                                                              │
│  输出:injection_status (success/failed/running)             │
└──────────────────────────────────────────────────────────────┘

4.5 节点 5:wait_retry(等待重试)

职责:当注入状态为 running 时智能等待

┌──────────────────────────────────────────────────────────────┐
│                     wait_retry 工作流程                       │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  智能等待策略:                                               │
│                                                              │
│  前 3 次重试:固定 5 秒间隔(快速确认)                         │
│                                                              │
│  后续重试:基于故障持续时间按比例等待                           │
│          └── 等待时间 = min(30s, max(5s, 剩余时间 × 30%))     │
│                                                              │
│  最大重试次数 = max(3, 故障持续时间/5 + 3)                     │
│                                                              │
│  例如:故障持续 60 秒                                         │
│          ├── 最大重试:15 次                                  │
│          ├── 前 3 次:每次等 5 秒                             │
│          └── 后续:动态计算等待时间                            │
│                                                              │
│  输出:retry_count = retry_count + 1                         │
│        → 返回 verify_injection 继续检查                       │
└──────────────────────────────────────────────────────────────┘

4.6 节点 6:monitor_data_plane(数据面监控)

职责:收集故障后的系统状态数据

┌──────────────────────────────────────────────────────────────┐
│                  monitor_data_plane 工作流程                  │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  Step 1: 重新获取所有 Pod 的当前状态(故障后)                  │
│          └── 调用 _get_current_pod_states()                  │
│                                                              │
│  Step 2: 对比故障前后的状态变化                                │
│          └── 调用 _compare_pod_states() 分析:                │
│              ├── 状态变化(phase、ready)                     │
│              ├── 重启次数变化                                 │
│              ├── IP 地址变化(Pod 重启后 IP 会变)             │
│              ├── 资源使用变化(CPU、内存)                     │
│              └── 节点变化(重新调度)                          │
│                                                              │
│  Step 3: 分析资源变化趋势                                     │
│          └── 调用 _analyze_resource_trends() 分析:           │
│              ├── CPU 趋势(增加/减少/稳定)                   │
│              ├── 内存趋势                                    │
│              └── 重启趋势                                    │
│                                                              │
│  Step 4: 查询数据面执行脚本日志(带时间过滤)                   │
│          └── 调用 data_plane_agent.query_data_plane_execution_logs() │
│              时间窗口:                                       │
│              ├── 故障前 30 秒开始                             │
│              └── 故障持续 + 30 秒结束                         │
│              过滤:只保留 ERROR 级别日志                       │
│                                                              │
│  Step 5: 收集并过滤 K8s 事件                                  │
│          └── 调用 filter_k8s_events() 去除噪声:              │
│              保留重要事件:Pod 调度、重启、健康检查失败等       │
│              过滤噪声:常规心跳、拉取镜像成功等                 │
│                                                              │
│  输出:pod_state_changes, data_plane_validation_results,     │
│        k8s_events, monitoring_summary                        │
└──────────────────────────────────────────────────────────────┘

4.7 节点 7:collect_trace(追踪收集)

职责:收集分布式追踪数据

┌──────────────────────────────────────────────────────────────┐
                    collect_trace 工作流程                     
├──────────────────────────────────────────────────────────────┤
                                                              
  Step 1: 优先收集主要目标 Pod 的追踪数据                       
          for pod in target_pods:                             
              trace_data = await k8s_agent.collect_traces(    
                  namespace, pod_name                         
              )                                               
              target_traces.append({                          
                  "pod_name": pod_name,                       
                  "trace_data": trace_data,                   
                  "analysis_role": "primary_target"           
              })                                              
                                                              
  Step 2: 收集辅助 Pod 的追踪数据(拓扑上下文)                  
          for pod in auxiliary_pods:                          
              ...(同样流程,但标记为 auxiliary)              
                                                              
  输出:traces = {                                            
      "all_traces": [...],                                    
      "target_traces": [...],    # 主要目标追踪                │
      "auxiliary_traces": [...], # 辅助追踪                    │
      "summary": {...}                                        
  }                                                           
└──────────────────────────────────────────────────────────────┘

4.8 节点 8:analyze(智能分析)

职责:基于规则引擎和 LLM 分析故障表现

┌──────────────────────────────────────────────────────────────┐
│                      analyze 工作流程                         │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  Step 1: 数据验证                                            │
│          ├── 检查 target_pods 是否存在                       │
│          ├── 检查 data_plane_validation_results 是否有效     │
│          └── 检查 k8s_events 和 pod_state_changes            │
│                                                              │
│  Step 2: 获取分析器实例                                       │
│          analyzer = await AnalyzerFactory.get_analyzer()     │
│                                                              │
│  Step 3: 设置故障上下文                                       │
│          analyzer.decision_engine.set_fault_context(         │
│              fault_type, fault_params                        │
│          )                                                   │
│                                                              │
│  Step 4: 准备分析数据                                         │
│          chaos_event = {                                     │
│              "fault_type": "pod-kill",                       │
│              "parameters": {"duration": "60s"},              │
│              "primary_target_pod": ...,                      │
│              "auxiliary_topology": ...                       │
│          }                                                   │
│                                                              │
│          data_plane_validation = {                           │
│              "data_plane_validation_results": ...,           │
│              "k8s_events": ...,                              │
│              "pod_state_changes": ...                        │
│          }                                                   │
│                                                              │
│  Step 5: 执行分析                                            │
│          result = await analyzer.analyze(                    │
│              chaos_event,                                    │
│              data_plane_validation,                          │
│              enhanced_context                                │
│          )                                                   │
│          分析方法:                                           │
│          ├── 规则引擎:基于预设规则判断                        │
│          └── LLM 分析:调用大语言模型深度推理                  │
│                                                              │
│  Step 6: 保存原始分析数据(供人工核实)                         │
│          保存到 reports/raw_analysis_data_xxx.json           │
│                                                              │
│  输出:analysis_result = {                                   │
│      "is_reasonable": True/False,  # 故障表现是否合理         │
│      "confidence": 0.85,           # 置信度                  │
│      "explanation": "...",         # 解释                    │
│      "recommendations": [...],     # 建议                    │
│      "llm_reasoning": "..."        # LLM 推理过程            │
│  }                                                           │
└──────────────────────────────────────────────────────────────┘

4.9 节点 9:report(报告生成)

职责:汇总所有结果,生成最终报告

┌──────────────────────────────────────────────────────────────┐
│                       report 工作流程                         │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  Step 1: 构建最终报告结构                                     │
│          final_report = {                                    │
│              "status": "completed",                          │
│              "timestamp": "2024-01-01T12:00:00",             │
│              "summary": {                                    │
│                  "target_namespace": "default",              │
│                  "fault_type": "pod-kill",                   │
│                  "injection_status": "success",              │
│                  "analysis_status": "reasonable",            │
│                  "confidence": 0.85                          │
│              },                                              │
│              "analysis": analysis_result,                    │
│              "topology_data": {                              │
│                  "cluster_info": ...,                        │
│                  "complete_pod_topology": ...,               │
│                  "primary_target_pods": ...,                 │
│                  "k8s_events": ...,                          │
│                  "distributed_traces": ...                   │
│              }                                               │
│          }                                                   │
│                                                              │
│  Step 2: 清理控制字符(确保 JSON 序列化正常)                   │
│          cleaned_report = clean_control_chars(final_report)  │
│                                                              │
│  Step 3: 保存报告文件                                         │
│          文件名:chaos_report_{namespace}_{fault_type}_{timestamp}.json │
│          位置:reports/ 目录                                  │
│                                                              │
│  输出:final_report, report_file                             │
└──────────────────────────────────────────────────────────────┘

5. 数据流转

5.1 状态更新机制

LangGraph 使用累加更新机制,每个节点返回的字典会合并到状态中:

初始状态 (initial_state)
        │
        ▼
┌───────────────────────────────────────────────────────┐
│                   init_context 返回                    │
│  {                                                    │
│      "cluster_info": {...},                           │
│      "target_pods": [...],                            │
│      "primary_target_pods": [...],                    │
│      "auxiliary_pods": [...],                         │
│      "all_pods": [...]                                │
│  }                                                    │
└───────────────────────────────────────────────────────┘
        │
        ▼ 状态合并
┌───────────────────────────────────────────────────────┐
│                   当前状态                             │
│  {                                                    │
│      "target_namespace": "default",        # 原始     │"fault_type": "pod-kill",             # 原始     │"cluster_info": {...},                # 新增     │"target_pods": [...],                 # 新增     │
│      ...                                              │
│  }                                                    │
└───────────────────────────────────────────────────────┘
        │
        ▼
┌───────────────────────────────────────────────────────┐
│            pre_injection_data_plane_validation 返回   │
│  {                                                    │
│      "pre_injection_validation": {...},               │
│      "pre_injection_baseline": {...}                  │
│  }                                                    │
└───────────────────────────────────────────────────────┘
        │
        ▼ 状态合并
       ...

5.2 完整数据流转图

┌─────────────────────────────────────────────────────────────────────────────┐
│                              完整数据流转                                    │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  输入参数                                                                    │
│  ├── target_namespace                                                       │
│  ├── fault_type                                                             │
│  ├── fault_params                                                           │
│  └── data_plane_cluster_host (可选)                                         │
│                                                                             │
│  init_context                                                               │
│  │   └── 输出: cluster_info, target_pods, primary_target_pods,             │
│  │            auxiliary_pods, all_pods                                      │
│  │                                                                          │
│  pre_injection_data_plane_validation                                        │
│  │   └── 输出: pre_injection_validation, pre_injection_baseline            │
│  │                                                                          │
│  inject_fault                                                               │
│  │   └── 输出: injection_id, injection_status                              │
│  │                                                                          │
│  verify_injection                                                           │
│  │   └── 输出: injection_status (success/failed/running)                   │
│  │                                                                          │
│  [wait_retry 循环]                                                          │
│  │   └── 输出: retry_count++                                               │
│  │                                                                          │
│  monitor_data_plane                                                         │
│  │   └── 输出: pod_state_changes, data_plane_validation_results,           │
│  │            k8s_events, monitoring_summary                               │
│  │                                                                          │
│  collect_trace                                                              │
│  │   └── 输出: traces (target_traces, auxiliary_traces, all_traces)        │
│  │                                                                          │
│  analyze                                                                    │
│  │   └── 输出: analysis_result (is_reasonable, confidence, explanation)    │
│  │                                                                          │
│  report                                                                     │
│      └── 输出: final_report, report_file                                   │
│                                                                             │
│  最终输出:reports/chaos_report_xxx.json                                    │
└─────────────────────────────────────────────────────────────────────────────┘

6. 错误处理机制

6.1 统一错误处理框架

# 错误严重程度
class ErrorSeverity(Enum):
    LOW = "low"           # 低严重性
    MEDIUM = "medium"     # 中等严重性
    HIGH = "high"         # 高严重性
    CRITICAL = "critical" # 致命错误

# 错误分类
class ErrorCategory(Enum):
    VALIDATION = "validation"   # 验证错误
    NETWORK = "network"         # 网络错误
    RESOURCE = "resource"       # 资源错误
    INJECTION = "injection"     # 注入错误
    MONITORING = "monitoring"   # 监控错误
    ANALYSIS = "analysis"       # 分析错误
    SYSTEM = "system"           # 系统错误

6.2 节点安全执行装饰器

每个节点函数都被 @ErrorHandler.safe_node_execution 装饰器包装:

@ErrorHandler.safe_node_execution("init_context", required_state_fields=["target_namespace"])
async def init_context(state: ChaosAnalysisState) -> Dict[str, Any]:
    # 节点实现...

装饰器功能:

  1. 前置状态检查:检查是否有前置错误
  2. 必需字段验证:验证必需的状态字段是否存在
  3. 异常捕获:捕获并标准化异常
  4. 错误日志记录:记录详细的错误信息

6.3 错误处理流程

┌──────────────────────────────────────────────────────────────┐
│                      错误处理流程                             │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  节点执行开始                                                 │
│      │                                                       │
│      ▼                                                       │
│  检查前置错误?                                               │
│      │                                                       │
│      ├── 有错误 → 跳过执行,返回错误                          │
│      │                                                       │
│      └── 无错误 → 验证必需字段                                │
│                      │                                       │
│                      ▼                                       │
│              必需字段完整?                                   │
│                      │                                       │
│                      ├── 缺失 → 返回 VALIDATION 错误          │
│                      │                                       │
│                      └── 完整 → 执行节点函数                   │
│                                      │                       │
│                                      ▼                       │
│                              执行成功?                       │
│                                      │                       │
│                                      ├── 成功 → 返回结果      │
│                                      │                       │
│                                      └── 异常 → 捕获并分类    │
│                                              │               │
│                                              ▼               │
│                                      返回标准化错误响应       │
└──────────────────────────────────────────────────────────────┘

7. 辅助函数

7.1 Pod 名称提取

def _get_pod_name(pod: Dict[str, Any]) -> str:
    """从各种数据格式中提取 Pod 名称"""
    if 'name' in pod:
        return pod['name']
    elif 'metadata' in pod and isinstance(pod['metadata'], dict):
        return pod['metadata'].get('name', 'unknown')
    return 'unknown'

7.2 持续时间解析

def _parse_duration(duration_str: str) -> int:
    """解析持续时间字符串为秒数
    
    支持格式:
    - 纯数字: "60" → 60
    - 秒: "60s" → 60
    - 分钟: "5m" → 300
    - 小时: "1h" → 3600
    - 组合: "1h30m" → 5400
    """

7.3 Pod 状态对比

def _compare_pod_states(initial_pod: Dict, current_pod: Dict) -> Dict[str, Any]:
    """对比故障前后的 Pod 状态变化
    
    检测项:
    1. 状态变化(phase 变化)
    2. 重启次数变化
    3. Ready 状态变化
    4. IP 地址变化
    5. 资源使用变化(CPU、内存)
    6. 节点变化(重新调度)
    """

7.4 资源趋势分析

def _analyze_resource_trends(pod_changes_list: List[Dict]) -> Dict[str, Any]:
    """分析资源使用趋势
    
    输出:
    {
        "cpu_trends": {"increasing": 2, "decreasing": 1, "stable": 5, "unknown": 0},
        "memory_trends": {"increasing": 1, "decreasing": 2, "stable": 5, "unknown": 0},
        "restart_trends": {"increased": 1, "decreased": 0, "stable": 7},
        "overall_impact": {"affected_pods": 3, "total_pods": 8}
    }
    """

7.5 数据面 Pod 发现

async def _discover_data_plane_pod_name(namespace: str) -> Optional[str]:
    """自动发现数据面验证 Pod 名称
    
    尝试常见名称模式:
    - data-plane-redis-0 (StatefulSet)
    - data-plane-redis (普通 Pod)
    - redis-data-plane-0
    """

8. 快速上手示例

8.1 基本用法

from core.graph import create_chaos_graph

async def run_chaos_analysis():
    # 1. 创建工作流图
    graph = create_chaos_graph()
    
    # 2. 准备初始状态
    initial_state = {
        "target_namespace": "default",
        "target_pod_label": "app=redis",
        "fault_type": "pod-kill",
        "fault_params": {
            "duration": "60s"
        },
        "data_plane_cluster_host": "redis-cluster.default.svc.cluster.local",
        "data_plane_redis_type": "proxy",
        "data_plane_test_type": "consistency"
    }
    
    # 3. 执行工作流
    result = await graph.ainvoke(initial_state)
    
    # 4. 查看结果
    print(f"分析结果: {result['analysis_result']}")
    print(f"报告文件: {result['report_file']}")

8.2 查看报告

报告会保存在 reports/ 目录下:

reports/
├── chaos_report_default_pod-kill_20240101_120000.json    # 最终报告
└── raw_analysis_data_default_pod-kill_20240101_120000.json # 原始分析数据

8.3 报告结构示例

{
  "status": "completed",
  "timestamp": "2024-01-01T12:00:00",
  "summary": {
    "target_namespace": "default",
    "fault_type": "pod-kill",
    "injection_status": "success",
    "analysis_status": "reasonable",
    "confidence": 0.85
  },
  "analysis": {
    "is_reasonable": true,
    "confidence": 0.85,
    "explanation": "Pod 被杀死后正常重启,服务恢复正常...",
    "recommendations": [
      "建议增加 Pod 健康检查超时时间",
      "考虑添加 Pod 反亲和性配置"
    ]
  },
  "topology_data": {
    "complete_pod_topology": [...],
    "k8s_events": [...],
    "distributed_traces": [...]
  }
}

附录:常见问题

Q1: 如果命名空间不存在会怎样?

A: init_context 节点会检测并返回错误,工作流直接跳转到 report 节点生成错误报告。

Q2: 如果故障注入失败会怎样?

A: verify_injection 节点会检测到 failed 状态,工作流跳转到 report 节点。

Q3: 如果没有配置数据面验证会怎样?

A: pre_injection_data_plane_validation 节点会跳过验证,继续执行后续节点。

Q4: 最大重试次数是多少?

A: 动态计算:max(3, 故障持续时间/5 + 3)。例如 60 秒故障最大重试 15 次。

Q5: 分析结果如何判断?

A: 分析器会综合规则引擎和 LLM 的分析结果,给出:

  • is_reasonable: 故障表现是否合理
  • confidence: 置信度 (0-1)
  • explanation: 解释说明
  • recommendations: 改进建议

文档版本: 1.0
最后更新: 2024年
作者: Chaos Redis Analyzer Team