记录 Pingora 直连窗口准备
补充 dev final-prep 审计结果 记录 direct env 候选与 dry-run runbook 明确 active env 提升前不得执行公网切换
This commit is contained in:
@@ -2371,6 +2371,7 @@
|
||||
- 现象:在 dev 上用临时 env 启动高端口 Pingora direct 演练时,shell 报 `/tmp/pingora-direct-highport-*.env: line ...: max-age=31536000,: command not found`,或者临时演练进程启动后没有按预期监听 `18443/18080`。
|
||||
- 原因:`pingora-gateway.env` 是 systemd EnvironmentFile 口径,允许 `GENARRATIVE_PINGORA_GATEWAY_ASSET_CACHE_CONTROL=public, max-age=31536000, immutable` 这类带空格的值;它不是可安全 `source` 的 shell 脚本。用 shell `source` 会把空格后的内容拆成命令或参数。另一个容易误判的点是 Pingora 默认优雅退出窗口较长,停止临时 systemd unit 后可能短暂停在 `stop-sigterm`,即使监听端口已经释放。
|
||||
- 处理:高端口真实演练优先用临时 systemd unit 启动 current release 的 `/opt/genarrative/current/pingora-gateway`,通过 `systemd-run --property=EnvironmentFile=/tmp/<run>.env --property=User=genarrative --property=WorkingDirectory=/opt/genarrative/current ...` 让 systemd 解析 env;或使用显式安全 env 解析器,禁止直接 `source`。临时 env 要把正式 shadow 端口改到独立 loopback 端口,例如 `127.0.0.1:18084`,HTTPS / HTTP redirect 用 `127.0.0.1:18443` / `127.0.0.1:18080`,access log 写独立文件。演练结束先 `systemctl stop <临时unit>`,再用 `ss -ltnp` 确认高端口已释放;若临时 unit 仍停在 `deactivating/stop-sigterm` 且只剩演练进程,可对该临时 unit 执行 `systemctl kill -s SIGKILL <临时unit>` 收尾,不要碰正式 `genarrative-pingora-gateway.service`。
|
||||
- 处理补充:正式 `plan:pingora-direct-cutover` / `check-pingora-release-readiness.mjs --dry-run-cutover --require-direct` 生成的 runbook 默认读取 active `/etc/genarrative/pingora-gateway.env`,不会自动使用 `/tmp` 候选 env。若只生成了候选 direct env,必须先在维护窗口内把候选 env 提升为 active env,并确认 Nginx 已释放 `80/443`,再执行 runbook 的 direct preflight、enable dry-run 和 enable apply;否则 runbook 第 5 步仍会按 shadow env 报缺 `TLS_LISTEN`、`HTTP_REDIRECT_LISTEN`、cert/key、`FORWARDED_PROTO=https` 以及 direct-entry capability。不要把候选 env 的 loopback / 高端口预检通过误解为 active env 已满足正式直连门禁。
|
||||
- 验证:先跑 `check-pingora-direct-preflight.mjs --env-file <临时env> --require-live-env --check-cert-readable --check-service-user-cert-readable --check-ports-free --allow-loopback-only`;启动临时 unit 后跑 `check-pingora-direct-live.mjs --https-base-url https://127.0.0.1:18443 --http-base-url http://127.0.0.1:18080 --host <域名> --redirect-host <域名> --redirect-base-url https://<域名> --require-wss-upgrade --pingora-access-log <临时log> --insecure-tls --json`,要求 `OK` 且 `direct-access-log matchedCount == checked`。收尾后复核 `80/443` 仍由 Nginx 监听,正式 Pingora shadow 仍为 `127.0.0.1:18081`。
|
||||
- 关联:`scripts/check-pingora-direct-preflight.mjs`、`scripts/check-pingora-direct-live.mjs`、`deploy/pingora/pingora-gateway.env.example`、`docs/technical/【开发运维】Pingora独立网关试点-2026-06-11.md`。
|
||||
|
||||
|
||||
@@ -437,6 +437,14 @@ dev 根盘空间在安装后曾接近满盘;2026-06-17 进入 canary 前已清
|
||||
- 复核 `http://127.0.0.1:8082/healthz` 与 `/readyz` 正常,`curl --resolve dev.genarrative.world:443:127.0.0.1 https://dev.genarrative.world/` 返回 Nginx `HTTP/2 200`,`http://127.0.0.1:18081/__genarrative_pingora/healthz` 带 probe token 返回 `{"ok":true,"gateway":"pingora-shadow","maintenance":false}`。
|
||||
- 经验:临时 env 含 `GENARRATIVE_PINGORA_GATEWAY_ASSET_CACHE_CONTROL=public, max-age=31536000, immutable` 这类带空格值,不能用 shell `source` 直接加载;演练进程应交给 systemd `EnvironmentFile=` 或使用安全 env 解析器,否则 shell 会把 `max-age=31536000,` 当命令执行。
|
||||
|
||||
同日继续进入正式窗口前 final-prep,不执行公网切换:
|
||||
|
||||
- `node -- /opt/genarrative/current/scripts/ops/pingora-direct-rehearsal-status.mjs --release-root /opt/genarrative/current --expect-public-gateway nginx --require-pingora-shadow --require-realpath-canary --require-current-release-gateway --fail-on-critical` 返回 `summary.status=OK`:公网 `80/443` 为 Nginx,Pingora shadow 为 `127.0.0.1:18081`,realpath canary 为 Nginx `127.0.0.1:18083`,health patrol env 为 `nginx` 模式且 public base URL 为 `https://dev.genarrative.world`。
|
||||
- `node -- /opt/genarrative/current/scripts/ops/pingora-current-release-audit.mjs --release-root /opt/genarrative/current --require-pingora-gateway --systemd-show` 返回 `summary.status=OK`,确认 current release 自包含、`api-server.sha256` / `pingora-gateway.sha256` 匹配、manifest 登记 `pingora-gateway`,且 `genarrative-pingora-gateway.service` 的 `ExecStart` 指向 `/opt/genarrative/current/pingora-gateway`。
|
||||
- 生成正式 direct env 候选 `/tmp/pingora-direct-dev-20260618T1548-final-prep.pingora-gateway.env`,与正式 `/etc/genarrative/pingora-gateway.env` 的差异仅为 `FORWARDED_PROTO=https`,追加 `TLS_LISTEN=0.0.0.0:443`、`HTTP_REDIRECT_LISTEN=0.0.0.0:80`、`TLS_CERT_FILE=/etc/genarrative/pingora-tls/dev.genarrative.world/fullchain.pem`、`TLS_KEY_FILE=/etc/genarrative/pingora-tls/dev.genarrative.world/privkey.pem`、`HTTP_REDIRECT_TARGET_SCHEME=https`。该候选 env 的 `check-pingora-direct-preflight.mjs --require-live-env --check-cert-readable --check-service-user-cert-readable` 通过,证明 direct env 内容和证书权限就绪。
|
||||
- 生成正式 dry-run cutover runbook `/tmp/pingora-direct-dev-20260618T1548-final-prep.runbook.json`,共 22 步,cutover run id 为 `pingora-direct-dev-20260618T1548-final-prep`,覆盖 pre-cutover 证据、enable/rollback 命令证据、post-enable/post-rollback 证据和最终根目录总审计。
|
||||
- 注意:该 runbook 仍按正式切换窗口读取 active `/etc/genarrative/pingora-gateway.env`。因此正式执行前必须在维护窗口内先把已审阅的 direct env 提升为 `/etc/genarrative/pingora-gateway.env`,确认 Nginx 释放 `80/443`,再进入 runbook 第 5 步 preflight;否则第 5 步会继续按当前 shadow env 失败。当前阶段未替换 active env、未安装 direct-entry drop-in、未释放 Nginx 端口、未执行 `pingora-direct-enable.sh --apply`。
|
||||
|
||||
## 环境变量
|
||||
|
||||
| 变量 | 默认值 | 说明 |
|
||||
|
||||
Reference in New Issue
Block a user