内容
# 克劳德运维调查员
一款基于克劳德代码、MCP、实时集群信号、Prometheus、日志搜索、运行手册、证据内存和结构化事件报告的上下文感知型Kubernetes事件调查助手。
克劳德运维调查员通过结合只读操作工具、外部证据存储、紧凑的调查内存和人为控制的修复边界,帮助工程师安全地调查Kubernetes事件。
目标不是给予AI无限制的生产访问权限。目标是暴露狭窄、可审计的只读接口,帮助工程师收集证据、形成假设、排除原因并更快地生成可靠的事件报告。
## 本项目提供的内容
- 狭窄的MCP样式工具,而不是通用的`kubectl`
- 只读的实时Kubernetes调查
- 克劳德代码项目指令
- MCP资源、工具和提示
- 技能、斜杠命令和作用域项目规则
- 协调员/子代理样式的调查工作流
- 结构化的工具错误
- 破坏性操作的钩子和门
- 结构化的事件报告输出
- 风险或模糊操作的 人工升级
## 安全规则
从只读开始。不要给予克劳德无限制的shell、`kubectl`、Helm或生产变更权限。
此脚手架中允许的操作:
- `kubectl get`
- `kubectl describe`
- `kubectl logs`
- `kubectl top`
阻止的操作包括:
- `kubectl delete`
- `kubectl apply`
- `kubectl patch`
- `kubectl scale`
- `kubectl rollout restart`
- `helm upgrade`
- 默认情况下的`kubectl exec`
## 快速开始
```bash
cd claude-ops-investigator
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
```
检查Kubernetes访问权限:
```bash
kubectl config current-context
kubectl auth can-i get pods -n si
kubectl auth can-i get pods/log -n si
```
运行只读快照:
```bash
python -m claude_ops.main investigate --namespace si --service event-data --since-minutes 60
```
运行测试:
```bash
pytest
```
## 克劳德代码斜杠命令
主要的交互式工作流是 `/investigate-incident` 斜杠命令:
```
/investigate-incident namespace=<命名空间> service=<服务> symptom="<具体症状>" since_minutes=<分钟数>
```
`symptom` 是必需的 - 此工作流是基于症状驱动的,而不是通用的服务健康检查。如果没有给出症状,克劳德会要求提供一个症状后再进行调查。
示例:
```
/investigate-incident namespace=si service=multi-system-processor symptom="最近滚动更新期间就绪探测失败" since_minutes=60
/investigate-incident namespace=si service=event-data symptom="KafkaConsumerCommitRateLow警报触发" since_minutes=120
/investigate-incident namespace=si service=multi-system-processor symptom="OOMKilled重启观察到" since_minutes=180
```
它执行的操作:
1. 生成一个 `investigation_id` 并创建 `runs/<investigation_id>/scratchpad/`,然后委托给 `incident-coordinator` 子代理(如果子代理不可用,则回退到单个代理,并显式声明该回退)。
2. 协调器读取服务目录和运行手册目录,然后将症状路由到最相关的专业子代理:
- `k8s-evidence-collector` - pod列表、描述、实时日志、命名空间事件、当前资源使用
- `prometheus-analyst` - 重启计数/增加、CPU、内存、HTTP错误率、延迟p95
- `log-analyst` - 历史IBM云日志搜索(错误、探测失败、任意文本)跨重启/部署
- `runbook-analyst` - 将症状与本地运行手册匹配
3. 每个专家存储原始证据作为 `evidence_ref`,并仅返回摘要/发现 - 协调器从不直接收集证据。每个还写入一个简洁的markdown草稿(范围、调用的工具、关键发现、evidence_refs、未知/空白、决策、交接摘要)到其指定的 `runs/<investigation_id>/scratchpad/wave<N>-<subagent-name>.md` 文件 - 永远不会是原始日志/指标体,只有摘要和evidence_refs。协调器维护自己的运行结构化发现简报在 `coordinator-brief.md` 在同一目录下,并将该简报和任何相关的草稿路径传递给每个子代理在其任务提示中。
4. `incident-reporter` 最后运行,将所有子代理的发现(从不它自己的)综合成一个单一的基于证据的、符合模式的报告
5. 最终输出包括一个 "子代理使用审计" 表格:哪些子代理运行,做了什么,使用了哪些工具/evidence_refs/草稿路径及其结果
它不执行的操作:
- 不修改Kubernetes资源
- 不重启pod
- 不应用修复
- 不运行破坏性命令
- 除非需要,否则不获取原始证据详情
### 可选工具的环境
Prometheus:
- `PROMETHEUS_URL`
- `PROMETHEUS_AUTO_PORT_FORWARD`
- `PROMETHEUS_PF_SERVICE`
- `PROMETHEUS_PF_NAMESPACE`
IBM云日志:
- `IBM_LOGS_ENDPOINT`
- `IBM_CLOUD_API_KEY`
复制`.env.example`到`.env`并填写本地值。永远不要提交`.env`。MCP服务器在启动时自动加载它,以便这些工具可以访问,而不会有任何秘密进入`.mcp.json`。
### 无令牌本地测试
这些测试工具和结构化错误路径,不需要任何实际的Prometheus、IBM云或Kubernetes凭证:
```bash
python -m pytest
python scripts/mcp_smoke_client.py
```
直接工具检查:
```bash
python - <<'PY'
from claude_ops.tools.prometheus_preflight import ensure_prometheus
import json
print(json.dumps(ensure_prometheus(), indent=2))
PY
python - <<'PY'
from claude_ops.tools.ibm_logs_tools import ibm_logs_search_errors
import json
print(json.dumps(ibm_logs_search_errors("si", "multi-system-processor", limit=1), indent=2))
PY
```
## 本地环境
MCP服务器需要用于可选的Prometheus和IBM云日志工具的环境变量(`PROMETHEUS_URL`、`IBM_LOGS_ENDPOINT`、`IBM_CLOUD_API_KEY`等)。使用`.env`文件在本地配置它们 - 它被gitignore并且自动加载,不需要任何秘密进入`.mcp.json`。
```bash
cp .env.example .env
# 使用本地值编辑.env
source .venv/bin/activate
claude
```
`src/claude_ops/mcp/server.py`在启动时调用`load_dotenv()`,因此MCP服务器在克劳德代码启动时自动拾取`.env` - 不需要手动`export`。缺少`.env`是可以的;需要变量的工具如果变量仍然未设置,则返回结构化的配置错误而不是静默失败。
## 套件钩子(安全门 + 审计跟踪)
`.claude/settings.json`在`.claude/hooks/`下连接了四个只读克劳德代码钩子。它们是应用层安全网和审计跟踪,与应用层防护措施(`src/claude_ops/hooks.py`、`schemas/incident_report_schema.py`)并存 - 它们都不调用Kubernetes、Prometheus、IBM云日志或克劳德API;它们只检查克劳德代码已经传递给它们的JSON输入,并且它们只写入`runs/`下的JSONL审计日志(像该目录的其他部分一样被gitignore)。
| 钩子 | 事件 | 它执行的操作 |
|---|---|---|
| `block_unsafe_shell.py` | `PreToolUse`上的`Bash` | 拒绝原始shell `kubectl delete/apply/patch/scale/rollout restart/exec`和`helm upgrade` - 第二个防护措施,防止破坏性命令通过输入的MCP工具到达`Bash`,而`hooks.py::validate_kubectl_verb`已经防护了这些命令。 |
| `audit_mcp_tool_calls.py` | `PostToolUse`上的`mcp__claude-ops-investigator__.*` | 为每个完成的MCP工具调用追加 `{tool_name, timestamp, status, evidence_ref, session_id}` 到 `runs/mcp-tool-audit.jsonl`。 |
| `audit_subagent_lifecycle.py` | `SubagentStart` / `SubagentStop` | 为每个事件追加 `{event, timestamp, session_id, subagent_type, description}` 到 `runs/subagent-audit.jsonl`。 |
| `validate_final_report.py` | `Stop` | 如果最后一个助手消息看起来像事件报告(提到了"子代理使用审计"、"事件报告"或`requires_human`),则检查它是否包含`evidence_ref`、"子代理使用审计"表格、`ruled_out`、`unknowns`和明确的确认/未确认声明 - 如果缺少任何一个,则阻止停止并说明原因。普通的对话回合则不受影响。 |
### 在本地禁用钩子
两种方法,从最不手术到最手术:
- **禁用所有内容**:将`"disableAllHooks": true`添加到`.claude/settings.local.json`(被gitignore,是个人设置 - 永远不要提交到项目的共享`.claude/settings.json`)。
- **仅禁用这四个**:在启动`claude`之前,在shell环境中设置`CLAUDE_OPS_HOOKS_DISABLED=1`。每个脚本在顶部检查它并立即跳过 - 没有写入审计行,没有阻止shell命令,没有验证报告。
## 推荐的首次实时使用
首先使用非生产命名空间。
```bash
python -m claude_ops.main investigate --namespace si --service multi-system-processor --since-minutes 120
```
然后将生成的JSON快照粘贴到克劳德/克劳德代码中,并要求它使用`src/claude_ops/schemas/incident_report_schema.py`中的模式生成事件报告。
## MCP客户端/服务器映射
在此项目中:
```text
克劳德代码 = MCP客户端
src/claude_ops/mcp/server.py = 本地MCP服务器
.mcp.json = 项目级MCP客户端配置,用于克劳德代码
```
手动启动MCP服务器进行快速语法检查:
```bash
python -m claude_ops.mcp.server
```
对于克劳德代码,请将`.mcp.json`保留在项目根目录。克劳德代码读取配置并通过STDIO启动服务器。
可选的烟雾测试:
```bash
pip install -e ".[dev,mcp]"
python scripts/mcp_smoke_client.py
```
MCP服务器公开:
资源:
- `ops://runbook-catalog`
- `ops://service-catalog`
工具:
- `k8s_list_pods`
- `k8s_describe_pod`
- `k8s_get_pod_logs`
- `k8s_get_recent_namespace_events`
- `k8s_top_pods`
- `runbook_search`
- `prom_query_instant`
- `prom_get_pod_restart_counts`
- `prom_get_pod_restart_increase`
- `prom_get_pod_cpu_usage`
- `prom_get_pod_memory_usage`
- `prom_get_http_error_rate`
- `prom_get_latency_p95`
- `prom_ensure_connection`
- `ibm_logs_search`
- `ibm_logs_search_errors`
- `ibm_logs_search_probe_failures`
- `ibm_logs_search_text`
- `evidence_get_detail`
提示:
- `investigate_incident`