4.4 /health 豁免
机制原理
/health 是 CubeAPI 内置的 liveness / readiness 探针,不受 auth callback / rate limit 约束。
docs/guide/authentication.md:8-12:
Every request (except
/health) must carry anAuthorization: Bearer <token>orX-API-Key: <key>header
中间件层面:
async fn unified_auth(...) -> Result<Response> {
if req.path() == "/health" {
return Ok(next.run(req).await); // 直接放行
}
// ... 走 callback 验证
}
为什么 CubeSandbox 这样设计
- 健康检查不该被认证挡死 —— 否则一旦 callback 服务挂掉,CubeAPI 自己被 K8s 重启,既检测不到也拉不起来
- readiness 端点 由 K8s 在 rolling update 时高速轮询,需要每次 < 10ms 响应,如果走 callback 路径可能延迟几十 ms 甚至 timeout
- 健康检查常常来自 untrusted agent —— 如果未来 CubeAPI 把健康端点公开给 internet,默认还要 auth 就是 anti-pattern
- 故障恢复路径 —— 生产常见操作"我把 callback 搞挂,先 fix callback,等它返回,但 CubeAPI 自己需要保持 healthy";
/health不受此牵连
如何使用 / 配置
客户端调用
# 不需要任何 header
curl http://cube-api:3000/health
# 输出
{"status": "ok", "components": {"mysql": "ok", "redis": "ok"}}
K8s 探针
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 1
LB 层
# HAProxy config
backend cube_api
balance roundrobin
option httpchk GET /health
http-check expect status 200
安全注意
- /health 不带 sensitive 信息 —— 不能返回 mysql 密码 / vm 列表等
- 真要分细:liveness vs readiness 拆成
/livez和/readyz /health不论何人都可触发 DoS——上 NGINX 前限速- 监控
/health触达频率,如果 K8s endpoint controller 频繁调,说明状态不是真的 healthy
最佳实践:
- 对 health 端点做 K8s 专用 ServiceAccount + NetworkPolicy,避免对外网暴露
- 内部回调才走 auth callback,但 health 端点禁用 callback
- 如果组件是 mysql / redis,即便主库挂也建议返回 degraded,不要直接 500 —— 否则 K8s 频繁重启 CubeAPI
- 高频轮询时,
/health端点响应小于 1ms,latency 由组件轮询频率决定
注意:
- /health 端点本身默认 200,除非状态 down;如果业务希望 truthy 反映 sandbox 创建失败,需要 inline 探测
- 不要把 /health 改名为其他字符串——大量 daemon-side 配置(K8s manifest, Prometheus)都 hard-code 它
- 实验新 auth callback 时首先验证 /health 工作正常,否则一旦误配 callback 路由,CubeAPI 不可恢复
- 如果想改 /health 行为(添加 custom checks),需要 fork 源码