debug-buttercup

debug-buttercup

热门

用于排查部署在 Kubernetes 上的 Buttercup CRS(网络推理系统)故障。当诊断 `crs` 命名空间内的 Pod 崩溃、无限重启、Redis 异常、资源紧缺、磁盘满载、DinD 故障或其他服务运行异常时使用。涵盖故障初筛、日志分析、队列排查以及针对以下服务的常见故障模式分析:redis、fuzzer-bot、coverage-bot、seed-gen、patcher、build-bot、scheduler、task-server、task-downloader、program-model、litellm、dind、tracer-bot、merger-bot、competition-api、pov-reproducer、scratch-cleaner、registry-cache、image-preloader、ui。

6336Star
545Fork
更新于 2026/7/30
SKILL.md
只读
名称
debug-buttercup
描述

用于排查部署在 Kubernetes 上的 Buttercup CRS(网络推理系统)故障。当诊断 `crs` 命名空间内的 Pod 崩溃、无限重启、Redis 异常、资源紧缺、磁盘满载、DinD 故障或其他服务运行异常时使用。涵盖故障初筛、日志分析、队列排查以及针对以下服务的常见故障模式分析:redis、fuzzer-bot、coverage-bot、seed-gen、patcher、build-bot、scheduler、task-server、task-downloader、program-model、litellm、dind、tracer-bot、merger-bot、competition-api、pov-reproducer、scratch-cleaner、registry-cache、image-preloader、ui。

排查 Buttercup 故障

何时使用

  • crs 命名空间内的 Pod 处于 CrashLoopBackOff、OOMKilled 或反复重启状态
  • 多个服务同时重启(级联故障)
  • Redis 无响应或抛出 AOF 警告
  • 队列持续积压但任务没有任何进展
  • 节点出现 DiskPressure(磁盘压力)、MemoryPressure(内存压力)或 PID pressure(PID 压力)
  • Build-bot 无法连接 Docker 守护进程(DinD 故障)
  • Scheduler 卡死,无法推进任务状态
  • 健康检查探针(Health check probes)意外失败
  • 已部署的 Helm values 与实际 Pod 配置不一致

何时不使用

  • 部署或升级 Buttercup(请参考 Helm 及部署指南)
  • 排查 crs Kubernetes 命名空间之外的问题
  • 与故障现象无关的性能调优

命名空间与服务

所有 Pod 均运行在 crs 命名空间中。核心服务分布如下:

分层 服务组件
基础设施 (Infra) redis, dind, litellm, registry-cache
编排调度 (Orchestration) scheduler, task-server, task-downloader, scratch-cleaner
模糊测试 (Fuzzing) build-bot, fuzzer-bot, coverage-bot, tracer-bot, merger-bot
分析推理 (Analysis) patcher, seed-gen, program-model, pov-reproducer
交互接口 (Interface) competition-api, ui

初筛工作流

排查故障时务必先进行初筛。首先运行以下三条命令:

# 1. 查看 Pod 状态 - 重点关注重启次数、CrashLoopBackOff、OOMKilled
kubectl get pods -n crs -o wide

# 2. 查看事件 - 了解异常发生的时间线
kubectl get events -n crs --sort-by='.lastTimestamp'

# 3. 仅查看警告 - 过滤干扰信息
kubectl get events -n crs --field-selector type=Warning --sort-by='.lastTimestamp'

接下来缩小排查范围:

# 查看特定 Pod 的重启原因:检查 Last State Reason(如 OOMKilled、Error、Completed)
kubectl describe pod -n crs <pod-name> | grep -A8 'Last State:'

# 对比实际资源限制与预期配置
kubectl get pod -n crs <pod-name> -o jsonpath='{.spec.containers[0].resources}'

# 已崩溃容器的日志(--previous 表示已被杀掉的前一个容器)
kubectl logs -n crs <pod-name> --previous --tail=200

# 当前运行容器的日志
kubectl logs -n crs <pod-name> --tail=200

历史问题 vs 当前正在发生的问题

重启次数高并不一定意味着当前存在问题 —— 重启次数是在 Pod 的整个生命周期内累计的。务必区分:

  • --tail 输出的是日志缓冲区末尾的内容,其中可能包含历史报错。建议结合 --since=300s 来确认故障是否在当前活跃发生。
  • 在日志输出中加上 --timestamps 有助于跨服务对比并关联事件时间线。
  • 检查 describe pod 中的 Last State 时间戳,确认最近一次崩溃发生的具体时间。

级联故障检测

当大量 Pod 在几乎同一时间重启时,在调查单个 Pod 前应先排查是否存在共享依赖故障。最常见的级联场景为:Redis 宕机 -> 所有服务抛出 ConnectionError/ConnectionRefusedError -> 引发大规模连带重启。
查看多个容器的 --previous 日志,如果都报 redis.exceptions.ConnectionError,请优先排查 Redis 自身,而不是去修各个独立服务。

日志分析

# 一次性查看某个服务的所有副本日志
kubectl logs -n crs -l app=fuzzer-bot --tail=100 --prefix

# 实时查看日志流
kubectl logs -n crs -l app.kubernetes.io/name=redis -f

# 将所有日志收集导出到磁盘(使用已有脚本)
bash deployment/collect-logs.sh

资源压力排查

# 查看各个 Pod 的 CPU/内存占用
kubectl top pods -n crs

# 查看节点层级的资源占用
kubectl top nodes

# 查看节点状态(磁盘压力、内存压力、PID 压力)
kubectl describe node <node> | grep -A5 Conditions

# 进入 Pod 内部查看磁盘使用率
kubectl exec -n crs <pod> -- df -h

# 查看是哪些目录占用了磁盘
kubectl exec -n crs <pod> -- sh -c 'du -sh /corpus/* 2>/dev/null'
kubectl exec -n crs <pod> -- sh -c 'du -sh /scratch/* 2>/dev/null'

Redis 故障排查

Redis 是核心骨干组件。一旦 Redis 宕机,全线服务都会受到级联影响。

# 查看 Redis Pod 状态
kubectl get pods -n crs -l app.kubernetes.io/name=redis

# 查看 Redis 日志(关注 AOF 警告、OOM、连接问题)
kubectl logs -n crs -l app.kubernetes.io/name=redis --tail=200

# 连接至 Redis CLI
kubectl exec -n crs <redis-pod> -- redis-cli

# 在 redis-cli 内部进行关键诊断
INFO memory          # used_memory_human, maxmemory
INFO persistence     # aof_enabled, aof_last_bgrewrite_status, aof_delayed_fsync
INFO clients         # connected_clients, blocked_clients
INFO stats           # total_connections_received, rejected_connections
CLIENT LIST          # 查看当前连接客户端
DBSIZE               # Key 总数

# 查看 AOF 配置
CONFIG GET appendonly     # 是否开启了 AOF?
CONFIG GET appendfsync   # fsync 策略:everysec、always 或 no

# 查看 /data 挂载的是什么存储?(disk 还是 tmpfs,这会直接影响 AOF 性能)
kubectl exec -n crs <redis-pod> -- mount | grep /data
kubectl exec -n crs <redis-pod> -- du -sh /data/

队列排查

Buttercup 基于带消费者组(Consumer Groups)的 Redis Stream 实现队列机制。队列名称映射如下:

队列功能 Stream Key
构建队列 (Build) fuzzer_build_queue
构建输出 (Build Output) fuzzer_build_output_queue
崩溃队列 (Crash) fuzzer_crash_queue
已确认漏洞 (Confirmed Vulns) confirmed_vulnerabilities_queue
下载任务 (Download Tasks) orchestrator_download_tasks_queue
就绪任务 (Ready Tasks) tasks_ready_queue
补丁队列 (Patches) patches_queue
索引队列 (Index) index_queue
索引输出 (Index Output) index_output_queue
追溯漏洞 (Traced Vulns) traced_vulnerabilities_queue
POV 请求 (POV Requests) pov_reproducer_requests_queue
POV 响应 (POV Responses) pov_reproducer_responses_queue
删除任务 (Delete Task) orchestrator_delete_task_queue
# 检查 Stream 长度(未处理消息数)
kubectl exec -n crs <redis-pod> -- redis-cli XLEN fuzzer_build_queue

# 检查消费者组延迟情况(Lag)
kubectl exec -n crs <redis-pod> -- redis-cli XINFO GROUPS fuzzer_build_queue

# 检查每个消费者的 Pending 消息数
kubectl exec -n crs <redis-pod> -- redis-cli XPENDING fuzzer_build_queue build_bot_consumers - + 10

# 任务注册表大小
kubectl exec -n crs <redis-pod> -- redis-cli HLEN tasks_registry

# 各状态任务计数
kubectl exec -n crs <redis-pod> -- redis-cli SCARD cancelled_tasks
kubectl exec -n crs <redis-pod> -- redis-cli SCARD succeeded_tasks
kubectl exec -n crs <redis-pod> -- redis-cli SCARD errored_tasks

消费者组包括:build_bot_consumersorchestrator_grouppatcher_groupindex_grouptracer_bot_group

健康检查

Pod 会定期向 /tmp/health_check_alive 写入时间戳,Liveness Probe(存活探针)通过检查该文件的更新时间来判断探针状态。

# 查看健康检查文件的新鲜度/更新时间
kubectl exec -n crs <pod> -- stat /tmp/health_check_alive
kubectl exec -n crs <pod> -- cat /tmp/health_check_alive

如果某个 Pod 陷入循环重启,大概率是因为主进程被阻塞(例如在等待 Redis 响应或卡在 I/O 上),导致健康检查文件未能按时更新。

遥测与追踪 (OpenTelemetry / Signoz)

所有服务均通过 OpenTelemetry 导出 Trace 和 Metric 监控数据。如果部署了 Signoz(global.signoz.deployed: true),可通过其 Web UI 查看跨服务的分布式链路追踪。

# 检查 OTEL 环境变量配置
kubectl exec -n crs <pod> -- env | grep OTEL

# 确认 Signoz Pod 是否正常运行(如果已部署)
kubectl get pods -n platform -l app.kubernetes.io/name=signoz

链路追踪(Trace)对于分析任务处理缓慢、定位流水线瓶颈服务,以及关联 scheduler -> build-bot -> fuzzer-bot 链路事件非常有用。

卷与存储 (Volume and Storage)

# 查看 PVC 状态
kubectl get pvc -n crs

# 检查 corpus tmpfs 是否挂载、其容量大小及底层存储类型
kubectl exec -n crs <pod> -- mount | grep corpus_tmpfs
kubectl exec -n crs <pod> -- df -h /corpus_tmpfs 2>/dev/null

# 检查 CORPUS_TMPFS_PATH 是否已设置
kubectl exec -n crs <pod> -- env | grep CORPUS

# 完整磁盘布局 - 查看实际磁盘与 tmpfs 的分布
kubectl exec -n crs <pod> -- df -h

global.volumes.corpusTmpfs.enabled: true 时,会自动设置环境变量 CORPUS_TMPFS_PATH。这会影响 fuzzer-botcoverage-botseed-genmerger-bot

部署配置校验

当实际行为与预期不符时,请校验 Helm values 是否真正生效:

# 查看 Pod 实际生效的资源限制配置
kubectl get pod -n crs <pod-name> -o jsonpath='{.spec.containers[0].resources}'

# 查看 Pod 实际生效的挂载卷定义
kubectl get pod -n crs <pod-name> -o jsonpath='{.spec.volumes}'

Helm values 模板中的拼写错误(如 Key 名称拼错)会静默退回 Chart 的默认配置。如果已部署资源与 Values 模板不匹配,请检查 Key 名称是否对应。

服务专项排查指南

针对各服务的详细异常现象、根因分析及修复方案,请参阅 references/failure-patterns.md

速查索引:

  • DinDkubectl logs -n crs -l app=dind --tail=100 -- 重点排查 Docker 守护进程崩溃、存储驱动错误
  • Build-bot:检查构建队列积压、DinD 连通性、编译过程中的 OOM
  • Fuzzer-bot:Corpus 磁盘占用、CPU 限频(throttling)、Crash 队列积压
  • Patcher:LiteLLM 连通性、LLM 超时、Patch 队列积压
  • Scheduler:核心控制大脑 -- kubectl logs -n crs -l app=scheduler --tail=-1 --prefix | grep "WAIT_PATCH_PASS\|ERROR\|SUBMIT"

诊断脚本

运行自动化初筛诊断脚本:

bash {baseDir}/scripts/diagnose.sh

传入 --full 参数可同时导出所有 Pod 最近的日志:

bash {baseDir}/scripts/diagnose.sh --full

该脚本将一次性收集 Pod 状态、事件、资源使用率、Redis 健康度及队列积压情况。