therealruthvik/edge-router-sim

GitHub: therealruthvik/edge-router-sim

基于 Envoy 的自托管边缘/CDN 流量路由与混沌注入演练平台,附带完整的监控告警和真实 on-call 响应链路。

Stars: 0 | Forks: 0

# edge-router-sim 一个基于 Envoy 构建的自托管 edge/CDN 流量路由器,它模拟了 Akamai Cloudlets 的核心能力(Edge Redirector、Forward Rewrite),并配有一套真实的合成故障注入和 on-call 响应系统: 检测、告警、分流、缓解和总结,所有这些都在实际运行的堆栈中 进行了演练,而不是纸上谈兵。 这里的所有内容都通过 Docker Compose(或 Terraform)在本地运行, 由真实的 HTTP 请求驱动,并且本仓库历史记录中的每个仪表板/告警/呼叫 都来自于实际执行该操作的容器。 ## 架构 ``` flowchart LR Client(["Client / curl"]) subgraph EdgeLayer["Edge layer"] Edge["Envoy edge
:10000 HTTP / :10443 HTTPS"] Policy["policy-server
xDS-over-REST control plane"] end Origin["origin
FastAPI mock backend"] subgraph Obs["Observability"] Prom["Prometheus"] Alert["Alertmanager"] Pager["pager"] Grafana["Grafana"] CertExp["cert-exporter"] end Ntfy[["ntfy.sh topic
(real push notification)"]] Chaos["chaos.py CLI"] Client -->|HTTP / HTTPS| Edge Edge -->|passthrough, redirect, rewrite| Origin Policy -.->|routes.yaml, polled every 2s| Edge Edge -->|/stats/prometheus| Prom Origin -->|/metrics| Prom CertExp -->|/metrics| Prom CertExp -.->|live TLS probe| Edge Prom --> Alert Alert --> Pager Pager --> Ntfy Prom --> Grafana Chaos -.->|edits| Policy Chaos -.->|pause / unpause| Origin Chaos -.->|swap cert, restart| Edge Chaos -.->|synthetic load| Edge ``` **Edge 层** — Envoy 终止 HTTP (10000) 和 HTTPS (10443)。 路由策略 (`edge/rules/routes.yaml`) 是一个声明式的 YAML 文件 — 相当于 Akamai Cloudlets 策略的直接类似物 — 通过基于 REST 的 xDS 由一个小型 Python 控制面 (`edge/policy-server`) 提供给 Envoy。Envoy 每 2 秒轮询一次,因此策略更改可以实现**零 Envoy 重启和零停机** 上线。(最初尝试了基于文件系统监视的 RDS 方法,但在三次不同的尝试中均未能可靠地重新加载后将其放弃 — 有关无效的内容以及为何选择 REST 轮询的详细信息,请参阅 Phase 3 提交。) **Origin** — 一个 FastAPI 应用,为每个 路由规则类别(地理、设备、重写目标、活动)提供不同的模拟 endpoint, 以便在 edge 之后有真实的路由目标和可破坏的对象。 **可观测性** — Prometheus 抓取 Envoy 原生的 `/stats/prometheus`、Origin 经检测的 `/metrics`,以及 一个自定义的 `cert-exporter`,它像真实的 客户端一样监视 edge 的活动 TLS 证书。Grafana 根据这些数据 渲染 RED(Rate/Errors/Duration)面板。 **告警** — Prometheus 告警规则评估真实的指标; Alertmanager 将触发的告警路由到一个小型 `pager` 服务,该服务对其进行重新格式化并发布到真实的 ntfy.sh 主题 — 实际的推送通知会发送到手机/浏览器,而不仅仅是日志文件中的一行记录。 **混沌** — `chaos/chaos.py` 直接针对运行中的堆栈 注入四种真实的故障模式 (错误的路由规则/重定向循环、origin 挂起、TLS 证书过期、 流量激增)。 ## 仓库布局 ``` edge/ envoy/envoy.yaml Envoy bootstrap: listeners, TLS, clusters envoy/certs/ TLS cert/key (gitignored, generated by chaos.py) rules/routes.yaml Declarative routing policy policy-server/ xDS-over-REST control plane serving routes.yaml origin/ FastAPI mock backend observability/ prometheus/ Scrape config + alert rules alertmanager/ Alert routing config pager/ Alertmanager webhook -> ntfy.sh adapter cert-exporter/ Blackbox TLS cert-expiry probe grafana/ Datasource + dashboard provisioning chaos/chaos.py Failure-injection CLI runbooks/ One per failure scenario postmortems/ Real, filled-out postmortems from actual drill runs terraform/ Same stack, as Terraform (Docker provider) tests/ Integration tests against the edge layer ``` ## 安装说明 需要 Docker Desktop(或兼容环境)和 Python 3.10+。 ``` git clone && cd edge-router-sim cp .env.example .env # 编辑 .env:将 ALERT_WEBHOOK_URL 设置为真实的 ntfy.sh topic # (选择任何难以猜测的 topic 名称,例如 https://ntfy.sh/your-name-a1b2c3 —— # 无需注册;在 ntfy app 或浏览器中的该 URL 订阅它) pip install -r chaos/requirements.txt python3 chaos/chaos.py tls-expiry setup # one-time: generates a valid self-signed cert docker compose up -d --build ``` 验证: ``` curl http://localhost:10000/home # origin passthrough curl -H "X-Geo-Country: US" http://localhost:10000/home # -> 302 /us/home curl http://localhost:10000/legacy/articles/1 # transparently rewritten to /v2/articles/1 open http://localhost:3000 # Grafana (admin/admin) — RED dashboard open http://localhost:9090 # Prometheus open http://localhost:9093 # Alertmanager ``` ## 运行路由规则 | 规则类型 | 示例 | |---|---| | 地理重定向 | `curl -H "X-Geo-Country: DE" localhost:10000/home` → 302 `/eu/home` | | 设备重定向 | `curl -A "...Mobile..." localhost:10000/home` → 302 `/mobile/home` | | 正则路径重写 | `curl localhost:10000/legacy/articles/2` → 200,透明地从 `/v2/articles/2` 提供服务 | | 查询字符串规则 | `curl "localhost:10000/promo?campaign=summer2026"` → 302 `/promo/summer2026` | 编辑 `edge/rules/routes.yaml` 并重新运行上述任何命令 — 更改在约 2 秒内生效,无需重启。 ## 混沌场景 ``` python3 chaos/chaos.py bad-rule inject # push a redirect-loop rule python3 chaos/chaos.py bad-rule restore # revert it python3 chaos/chaos.py origin-timeout hang # pause origin (accepts, never responds) python3 chaos/chaos.py origin-timeout resume python3 chaos/chaos.py tls-expiry inject # swap in an expired cert, restart edge python3 chaos/chaos.py tls-expiry restore python3 chaos/chaos.py traffic-spike /promo/summer2026 --rps 100 --duration 60 python3 chaos/chaos.py hammer --rps N --duration S # generic load generator ``` 每个场景在 `runbooks/` 中都有一个 runbook,并且在 `postmortems/` 中有一份真实的、填写完整的 postmortem,这些都是在实际运行演练后立即编写的 — 时间线、PromQL 查询和 ntfy 交付 确认信息都是从实际运行中复制的,而不是事后重建的。 其中两份 postmortem 记录了在第一次尝试中*未*按预期 工作的情况(chaos 工具吞吐量不足, 以及无法区分“挂起”和“宕机”的告警) — 故意保留它们,因为这才是运行这些 演练的真实情况。 ## Terraform `terraform/` 通过 [kreuzwerker/docker](https://registry.terraform.io/providers/kreuzwerker/docker) 提供程序而不是 `docker compose` 来建立相同的堆栈 — 作为原生 `docker_image`/`docker_container` 资源,具有相同的镜像、挂载、端口 和容器名称别名。 ``` cd terraform cp terraform.tfvars.example terraform.tfvars # fill in your ntfy topic terraform init terraform plan terraform apply ``` 不要与 `docker compose up` 同时运行 — 两者绑定相同的 主机端口。 ## 测试 ``` pip install -r tests/requirements.txt docker compose up -d --build pytest tests/ ``` 集成测试通过真实的 HTTP 访问运行中的 edge 层,并 断言上述记录的相同路由行为。 ## 展示的技能 | 领域 | 位置 | |---|---| | **Edge/CDN 路由逻辑** — 地理、设备、路径重写、查询字符串规则;声明式策略;无需重新部署的热重载 | `edge/rules/routes.yaml`, `edge/policy-server/`, Phase 3 提交 | | **故障检测** — 真实的指标,真实的 Prometheus 告警规则,而非预设的演示 | `observability/prometheus/alert_rules.yml`, 四次混沌演练 | | **告警/呼叫** — 真实的通知确实到达了某处,端到端 | `observability/alertmanager/`, `observability/pager/`, 在每份 postmortem 中确认的 ntfy.sh 交付 | | **On-call 分流与根因分析** — 区分在告警层看起来相似的故障模式(例如挂起与宕机的 origin) | `runbooks/origin-timeout.md`, `postmortems/2026-07-15-origin-timeout.md` | | **无指责的 postmortem** — 真实的时间线,坦诚的“出了什么问题”部分,具体的行动项 | `postmortems/` | | **可观测性工程** — RED 指标,自定义黑盒导出器(TLS 证书过期),基础设施即代码的仪表板 | `observability/grafana/dashboards/edge-router-red.json`, `observability/cert-exporter/` | | **基础设施即代码** — 完整的堆栈代码化,而不仅仅是手动执行 `docker-compose up` | `terraform/` | | **运维诚实/工程判断** — 了解“热重载”声明何时才是真实的,并在不真实时如实说明(这里的 TLS 证书需要重启;路由策略不需要) | `runbooks/tls-cert-expiry.md` | ## 已知缺陷(已记录,未隐藏) - edge HTTPS 监听器上的 TLS 证书在 Envoy 启动时从静态文件加载一次 — 与路由策略不同,轮换它们 需要重启。要解决此问题,需要通过 Envoy 的 SDS 结合真实的交付机制来配置证书 (在 `runbooks/tls-cert-expiry.md` 中被列为未来工作)。 - `chaos.py hammer` 的负载生成器是单线程的,并且在 负载下无法达到其标称的 `--rps` — 请参阅 `postmortems/2026-07-15-traffic-spike.md`,了解在演练中遇到此限制时的真实数据。 - `OriginDown` 无法区分挂起的 origin 和完全停止的 origin, 因为两者在 Prometheus 的抓取中失败的方式完全相同 — 请参阅 `postmortems/2026-07-15-origin-timeout.md`。
标签:API集成, CDN/边缘计算, Envoy, 可观测性, 安全规则引擎, 故障注入, 流量路由, 混沌工程, 版权保护, 自定义请求头, 逆向工具