
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。
用于排查部署在 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 及部署指南)
- 排查
crsKubernetes 命名空间之外的问题 - 与故障现象无关的性能调优
命名空间与服务
所有 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_consumers、orchestrator_group、patcher_group、index_group、tracer_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-bot、coverage-bot、seed-gen 和 merger-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。
速查索引:
- DinD:
kubectl 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 健康度及队列积压情况。





