本地 K3s 节点此前在 Kubelet 中登记为宿主机资源,负载可挤压 etcd 并在 server 重启后继续污染同一 Run。现在为三节点设置真实可调度预算、独立 etcd/数据卷和锁定依赖镜像,并持续核对 server 与 API/etcd 健康。\n\n每次验收生成独立 Run ID,报告使用独占或原子写入,负载错误记录具体阶段;数据库鉴权不可用返回带 Retry-After 的 503,避免基础设施故障被误报为 401。\n\n验证:Go 全量测试、go vet、gofmt、OpenAPI、bash -n、ShellCheck、报告测试和 k3d 配置解析均通过。
130 lines
6.2 KiB
Markdown
130 lines
6.2 KiB
Markdown
# 本地三节点同构验收
|
||
|
||
## 链路边界
|
||
|
||
本地验收不使用旧 `simulation` 请求模式。压测端发送正式 Gemini `generateContent` 和正式
|
||
多参考图视频请求,完整经过:
|
||
|
||
```text
|
||
双 TLS 入口 → API 鉴权与 validation 门禁 → 生产候选路由
|
||
→ Base64 解码及媒体物化 → PostgreSQL/River → Worker/租约
|
||
→ 真实 Gemini/Volces 客户端 → 协议模拟上游
|
||
→ 结果持久化 → 独立钱包结算 → 独立回调收集器 → 客户端响应
|
||
```
|
||
|
||
只有候选已经确定后的 Base URL 和凭据被验收 Run 替换。模拟上游实现真实协议、延迟、
|
||
异步轮询及示例媒体返回;API、Worker、候选选择、账务和恢复代码不走测试旁路。
|
||
|
||
## 资源和工具
|
||
|
||
本地集群名固定为 `easyai-acceptance-local`,包含三个 k3d/K3s server:
|
||
|
||
| 节点 | Docker 上限 | 调度职责 |
|
||
|---|---:|---|
|
||
| server-0 / ningbo | 4 CPU / 8 GiB | API、Worker、PostgreSQL |
|
||
| server-1 / hongkong | 4 CPU / 8 GiB | API、Worker、PostgreSQL |
|
||
| server-2 / los-angeles | 2 CPU / 4 GiB | 控制面和 etcd,`NoSchedule` |
|
||
|
||
Docker Desktop 必须配置至少 24 GiB 内存,宿主工作盘必须至少保留 30 GiB 可用空间;
|
||
脚本只检查,不修改 Docker 或宿主设置。依赖预载后会先用锁定 K3s 镜像执行 10 秒容器
|
||
启动探针,应用镜像构建后再用本次验收的最小镜像复检,确保 Docker daemon 不只是 API
|
||
可读、而是真的能创建容器,再进入 K3d。
|
||
k3d、K3s 和
|
||
CNPG 版本及 SHA-256 位于
|
||
`deploy/kubernetes/local-acceptance/dependencies.lock`。高并发阶段使用宿主原生架构镜像,
|
||
最后才导入 release manifest 中精确的 `linux/amd64@sha256` 制品做启动、迁移和媒体冒烟。
|
||
|
||
K3s 启动时会通过 Kubelet `system-reserved`/`kube-reserved` 将两个业务节点的可调度资源
|
||
固定为 3 CPU/6656 MiB,将见证节点固定为 1 CPU/2560 MiB;随后 Docker 硬上限分别设置为
|
||
4C/8GiB、4C/8GiB、2C/4GiB。API CPU 为 250m/750m,Worker 为 750m/1500m,Worker
|
||
内存仍为 1536Mi/2Gi。etcd 与 PostgreSQL `local-path` 使用不同的命名卷,避免和业务媒体
|
||
目录共用 Docker writable layer。依赖镜像会在部署应用前按锁定 digest 预拉取并导入;若
|
||
Docker daemon 的系统代理不可用,则使用锁定版本的 `crane` 按同一 digest 拉取 OCI 内容,
|
||
再导入本地 Docker/K3s,不会退化为未校验 Tag。
|
||
|
||
```bash
|
||
scripts/acceptance/local-cluster.sh install-tools
|
||
scripts/acceptance/local-cluster.sh preflight
|
||
```
|
||
|
||
失败的 `up` 默认保留集群。只有下面的显式命令会销毁:
|
||
|
||
```bash
|
||
scripts/acceptance/local-cluster.sh down --confirm
|
||
```
|
||
|
||
## 脱敏生产快照
|
||
|
||
先使用只有 `SELECT` 权限的数据库角色导出 `acceptance-snapshot/v1`:
|
||
|
||
```bash
|
||
AI_GATEWAY_ACCEPTANCE_SNAPSHOT_DATABASE_URL='<只读连接>' \
|
||
scripts/acceptance/export-production-snapshot.sh \
|
||
--release-sha <当前线上完整SHA> \
|
||
--output .local-secrets/acceptance/production-snapshot.json
|
||
```
|
||
|
||
快照只包含一个 Gemini 图片候选和一个 `omni_video.max_images >= 9` 视频候选所需的能力、
|
||
协议、路由、限流、价格、重试和运行策略。导出器拒绝密码、Secret、Token、认证、代理和
|
||
连接串字段,文件权限固定为 `0600`,并记录配置哈希和快照 SHA-256。
|
||
|
||
本地导入必须先匹配 `acceptance_local_cluster_id` 数据库标记,否则拒绝写入。集群内创建
|
||
32 个隔离身份/API Key、独立钱包和专属 Run;Key 与 Run Token 只保存在 `0600` 临时文件,
|
||
不进入 Pod Spec、报告或日志。
|
||
|
||
## 创建与验收
|
||
|
||
源码必须已提交且工作区干净,确保本地镜像和报告中的完整 Git SHA 可复现:
|
||
|
||
```bash
|
||
scripts/acceptance/local-cluster.sh up \
|
||
--snapshot .local-secrets/acceptance/production-snapshot.json
|
||
|
||
scripts/acceptance/run-local-acceptance.sh quick
|
||
|
||
# P24 基线应使用三个不同 Run ID 连续通过
|
||
scripts/acceptance/run-local-acceptance.sh quick
|
||
scripts/acceptance/run-local-acceptance.sh quick
|
||
|
||
scripts/acceptance/run-local-acceptance.sh full \
|
||
--release-manifest dist/releases/<完整SHA>.json
|
||
```
|
||
|
||
`full` 依次执行:
|
||
|
||
1. Gemini、3/6/9 图视频、账务和回调快速验收。
|
||
2. 固定 `1+1` Worker 的 P24、P28、P32,每档完整运行三次。
|
||
3. 1000×256 KiB、128×2 MiB、32×8 MiB Gemini 与 1200/96 视频负载。
|
||
4. 40±20 ms/0.5% 丢包、上游断链 10 秒、Worker—数据库断链 30 秒。
|
||
5. 确实持有远程任务的 Worker 强杀,以及容量控制器 Leader 切换。
|
||
6. `1+1 → 1+2/2+2 → drain → 1+1` 弹性验证。
|
||
7. 80% 两小时混合流量和 120% 十分钟主动限流。
|
||
8. 精确 amd64 release 镜像的迁移、启动与媒体冒烟。
|
||
|
||
每次 `quick`、`full` 或独立 `artifact-smoke` 都会先生成新的 Run ID;前一 Run 只有在队列
|
||
和 running 已归零后才会被本地安全终止。负载报告使用独占创建,已有文件不会被覆盖。
|
||
负载期间每 2 秒核对三个 K3s server 的容器 ID、restartCount、启动时间、IP、Node UID、
|
||
API readiness;任一 server 重启立即以 `local_control_plane_restarted` 终止。etcd 出现严重
|
||
心跳、fdatasync、ReadIndex 或请求超时则以 `local_etcd_latency` 阻断。本地 P24 基线先把
|
||
6K 图片归一化并发固定为 1,确认稳定后才允许单独测试更高媒体并发。
|
||
|
||
网络故障只能作用于带 `easyai.io/environment=local-acceptance` 标签的代理 Pod:
|
||
|
||
```bash
|
||
scripts/acceptance/network-fault.sh baseline
|
||
scripts/acceptance/network-fault.sh weak-link
|
||
scripts/acceptance/network-fault.sh upstream-outage
|
||
scripts/acceptance/network-fault.sh database-outage hongkong
|
||
scripts/acceptance/network-fault.sh reset
|
||
```
|
||
|
||
统一报告为 `acceptance-report/v1`,位于
|
||
`dist/acceptance/local/<run-id>/acceptance-report.json`。本地吞吐只用于筛选候选档位;
|
||
生产 certified profile 必须在线上模拟验收中重新确定。
|
||
|
||
## 不能被本地替代的门禁
|
||
|
||
本地环境不能认证真实 WireGuard 六向链路、生产磁盘、跨地域 CNPG 同步、供应商配额或
|
||
生产节点混部资源。线上 `--execute` 会重新导出生产候选配置;配置哈希与本地快照不一致时
|
||
立即停止,必须基于新快照重跑本地阻断验收。
|