# 常见故障

Raise 常见故障的排查与恢复指南。当系统出现 OpenBao 密钥封存、服务重启重连、身份中心启动慢或租户开通异常、域名证书错误、模型网关数据不一致、请求频次限流 429、磁盘空间与数据库复制槽异常时，你可以按照现象逐步排查并恢复服务。

## 谁能用

不同角色在故障排查中的职责分工与权限要求如下：

| 角色 / 身份 | 具备权限与工具 | 排查职责与范围 |
|---|---|---|
| 部署运维人员 | 主机权限、`docker compose` / `kubectl`、解封份额、`.env` 配置文件 | 负责底层容器状态排查、日志分析、OpenBao 密钥解封、磁盘清理、环境变量调整与服务重启。 |
| 平台运营人员 | 平台运营管理台操作权限（`platform.ops`） | 负责检查模型供应商与网关的数据一致性、执行重新同步，以及在开通租户失败时进行重试。 |
| 组织管理员 | [工作台](/guide/workspace)与「我的组织」管理权限 | 负责在组织内部查看与配置自定义域名、存储与模型页面，排查组织层面的配置问题。 |
| 普通成员 | 组织普通成员权限 | 无底层运维与解封权限。在遇到故障时仅会看到登录失败、连接重连或请求限流的界面文案提示。 |

## 怎么打开

你可以通过以下入口与命令检查系统健康状态或执行排障操作：

| 检查项目 / 工具 | 访问入口 / 执行命令 | 说明 |
|---|---|---|
| 容器运行状态 | 在服务器终端执行 `docker compose ps` | 查看各服务容器的运行状态与健康标记（healthy / unhealthy）。 |
| 服务健康探针 | 访问 HTTP 健康接口 `/readyz`，或在容器内执行 `kwork healthcheck` | 返回 200 表示服务就绪；若返回 503 表示底层数据库或密钥后端异常。 |
| 监控与日志大盘 | 访问 Grafana 与 Loki 控制台（`https://grafana.ops.{base}:8443`） | 部署时需启用 `--obs` 组件。用于检索容器启动与服务运行日志。 |
| 生产密钥解封 | 在终端执行 `docker compose exec openbao bao operator unseal` | 由持有份额的保管人输入密钥份额完成解封。 |
| 本地开发解封 | 在终端执行 `bash test/local/unseal-openbao.sh` | **仅限本地开发环境**使用。生产环境严禁依赖本地脚本。 |
| 运营台排障入口 | 浏览器访问 `https://ops.{base}:8443` | 检查模型网关一致性、重试租户开通操作。 |
| 组织管理入口 | 登录 [工作台](/guide/workspace)，打开「我的组织」 | 排查自定义域名解析状态与组织配置。 |

## 界面一览

Raise 系统未设立独立的「故障」产品页面。当服务异常或受到安全拦截时，用户会在各个对应界面看到以下文案与提示：

| 界面位置 | 出现的提示文案与现象 | 说明与触发场景 |
|---|---|---|
| 工作台顶部或连接层 | 「连接中断，正在重新连接…」 | 网络连接抖动或后端服务重启时显示。 |
| 登录界面 | 「身份服务暂时连不上，稍后再试。」 | Zitadel 身份服务未就绪或无法连通。 |
| 登录界面 | 「企业登录没有成功……」 | 企业身份源（IdP）配置异常或验证未通过。 |
| 登录界面 | 「无法登录」 | 登录流程发生未预期的异常中断。 |
| 登录界面 | 「尝试得太频繁了」 | 短时间内多次输错密码，触发 Zitadel 底层频率限制。 |
| 组织应用独立访问 | 「请从工作台打开」 | 在浏览器中直接打开 `https://organization.apps.{base}` 时的拦截提示。 |
| 模型与助手界面 | 「没有部署模型网关」 | 系统未部署模型网关组件。 |
| 模型与助手界面 | 「模型网关不可用」 | 模型网关服务异常或网络不可达。 |
| 模型与助手界面 | 「请求太频繁，超过了每分钟上限。」 | 组织或成员的模型调用频率超出了每分钟限制。 |
| 工作台通用提示 | 「请求太频繁」或「请稍后重试。」 | 短时间内发送过多请求，触发系统限流。 |
| 成员邀请与开通 | 「席位已满，联系平台运营增加席位」 | 租户成员数量已达到购买或分配的席位上限。 |
| 网关错误兜底页 | 标题为服务正在重启，正文说明通常几秒钟就好，页面会自动重新打开。 | 租户访问地址整页刷新若遇网关 502、503 或 504 错误时展示，页面每 3 秒 自动重试重新打开。 |

## 常用操作

### OpenBao 重启封存排查与解封

当采用私有化部署（`onprem` 环境包）时，OpenBao 采用文件后端存储。**OpenBao 每次容器重启后均会默认恢复为封存（sealed）状态**。

- **异常现象**：服务健康检查 `/readyz` 返回 503 错误（错误信息为 `openbao: sealed`），容器健康状态显示为 unhealthy，监控触发 `KworkNotReady` 告警。凡需要解密密钥的操作（例如租户自带的 BYO 对象存储凭据或自定义模型密钥）均会执行失败。
- **生产环境解封步骤**：
  1. 在服务器终端执行命令查看容器状态：
     ```bash
     docker compose ps
     ```
     确认 `openbao` 容器正在运行但处于封存状态。
  2. 召集至少 3 位密钥份额保管人（系统首次初始化共生成 5 个份额，解封门限为 3）。
  3. 执行解封命令并输入第 1 位保管人的密钥份额：
     ```bash
     docker compose exec openbao bao operator unseal
     ```
  4. 再次执行上述解封命令，分别输入第 2 位与第 3 位保管人的密钥份额（累计执行 3 次）。
  5. 达到 3 份门限后，OpenBao 自动解除封存状态。再次检查 `/readyz`，服务恢复健康。

> **云上自动解封**
>
> 若在云平台部署，可以将 OpenBao 配置为使用云 KMS 服务实现自动解封，无需人工手动输入份额。

> **初始密钥安全处理**
>
> 首次执行安装脚本初始化时，系统会生成 5 个解封份额（门限 3）并写入 `compose/state/openbao-init.json`（文件权限为 600）。你必须立刻将份额分发给不同保管人，随后**立即删除该文件并吊销 root token**。生产环境中严禁将解封份额保存在主机磁盘上。

- **本地开发环境解封**：本地开发栈可直接执行脚本完成解封：
  ```bash
  bash test/local/unseal-openbao.sh
  ```
  该脚本会自动读取 `compose/state/openbao-init.json`。若附加 `--watch` 参数，脚本会在 Docker 虚拟机重启后等待约 15 秒 自动完成解封。

### 服务重启与容器异常排查

- **双容器同时启动**：当 `kwork` 与 `kwork-agent` 容器在同一秒启动时，网关可能会产生短暂的 502 错误。在 Loki 中检索日志查看启动情况：
  ```text
  {service_name=~"kwork|kwork-agent"} |= "kwork started"
  ```
- **助手服务排空机制**：`kwork-agent` 在停止前会执行排空流程，排空等待时长由环境变量 `KWORK_AGENT_DRAIN_S` 控制（默认 60 秒）。系统日志中会记录 `agent-runtime: worker stopped` 并附带等待毫秒数 `waited_ms`。排空期间系统会尽量将正在生成的回答推送完毕；若排空超时或 `docker stop -t` 设定的超时时间过短，当前步骤会被标记为 `context canceled`，服务在 15 秒 心跳超时后会自动重新执行该任务。
- **页面断线重连**：服务重启过程中，工作台界面会显示「连接中断，正在重新连接…」。知识库文档同步关闭码 1012 表示 kwork 主服务正在重启，关闭码 1001 表示网关重载（`stream_close_delay 5m`）。
- **容器崩溃定位**：若非主动重启而是发生异常崩溃，通常只有一个容器的 `RestartCount` 计数增加。致命崩溃（panic）信息仅记录在标准错误中，必须通过终端命令查看：
  ```bash
  docker logs <容器名>
  ```
  标准错误日志不会采集进入 Loki。请注意，一旦容器被删除重建，崩溃日志将彻底丢失。
- **Kubernetes 探针行为**：在使用 Helm 部署的环境中，系统配置了 `preStop` 钩子等待 5 秒 并结合排空。若 `/readyz` 返回 503 超过约 15 秒（检测周期 5 秒 × 3 次），该副本会被服务自动摘除，网关会出现短暂 502 错误；底层数据库恢复后，副本将在数秒内恢复上线。

### Zitadel 启动慢与开通租户 502 排查

- **初始化启动等待**：在执行安装脚本时，系统会等待 `zitadel ready` 并且状态文件 `state/provisioner.pat` 非空，最长等待 90 × 2 秒（约 180 秒）。若超时，终端会输出错误：
  ```text
  zitadel did not become ready; see: docker compose logs zitadel
  ```
- **Zitadel 异常影响**：当 Zitadel 容器停止运行时，用户登录、租户开通以及组织成员修改均会失败；但对于已经签发的登录令牌，在令牌过期前仍可正常使用（平台对 JWKS 公钥设有本地缓存）。Zitadel 的所有身份数据均保存在 PostgreSQL 的 `zitadel` 数据库中，只需执行命令重启容器即可恢复：
  ```bash
  docker compose restart zitadel
  ```
- **开通租户返回 502 错误**：
  1. 查看接口响应中的 Zitadel 错误详情。
  2. 检查环境变量 `PROVISIONER_PAT_EXPIRY` 设定的 PAT 访问令牌是否已过期。
  3. 直接重试开通：开通失败时系统已自动回滚租户记录，排查服务正常后重新提交开通即可。
- **修改组织显示名返回 502 错误**：表示 Zitadel 拒绝了所提交的组织名称，此时平台数据表中已自动完成回滚。
- **Kubernetes 环境变量注入**：在 Kubernetes 环境中，若将 Service 命名为 `zitadel`，环境会自动注入 `ZITADEL_PORT` 变量导致服务启动失败（官方 Helm Chart 已默认处理该兼容问题）。

### 磁盘空间不足与存储清理排查

- **主机安装预检限制**：执行安装脚本时，预检会检查 `/var/lib/docker` 所在分区的磁盘可用空间。若可用空间小于 40 GB（针对 single 最小化配置）或小于 100 GB（针对 onprem 私有化或 shell 配置），终端会输出 `✗ disk …` 并中止安装。
- **容器日志大小限制**：Docker 容器默认配置了日志轮转策略，单个日志文件大小上限为 50 MB（`max-size=50m`），最多保留 5 个 日志文件（`max-file=5`）。
- **PostgreSQL 备份复制槽限制**：PostgreSQL 的 WAL 复制槽最大保留大小为 8 GB（`max_slot_wal_keep_size=8GB`）。若复制延迟超过 8 GB，数据库会主动放弃该复制槽（数据库继续运行，但备份会出现数据缺口）。
- **复制槽清理步骤**：若停止了 `pg-backup` 备份服务，必须在数据库中手动执行命令删除复制槽：
  ```sql
  SELECT pg_drop_replication_slot('slot_name');
  ```
  若复制槽状态变为 lost，需先删除失效槽，重启 `pg-backup` 容器，并立刻手动触发一次全量备份。
- **单机存储损坏风险**：若采用单机部署且将 SeaweedFS 备份存储保存在同一台机器上，主机或磁盘发生物理损坏时，数据与备份将同时丢失。
- **磁盘清理操作**：
  1. 在主机终端执行 `df -h` 检查各分区占用，执行 `docker system df` 查看镜像与容器空间。
  2. 对主机磁盘或存储卷执行扩容。
  3. 执行清理命令移除未使用的 Docker 镜像与停止的容器。
  4. 将备份环境变量 `BACKUP_S3_*` 指向外部独立的对象存储，避免占用本地存储空间。

### 全部 API 401 与角色 403 故障排查

- **全部 API 返回 401 Unauthorized**：
  1. 检查 OIDC JWKS 地址可达性：确认环境变量 `KWORK_OIDC_JWKS_URL` 配置的地址是否能够正常访问。
  2. 检查 Host 头部配置：确认环境变量 `KWORK_OIDC_JWKS_HOST` 是否正确配置为 `id.{base}`。
  3. 检查系统时钟同步：检查服务器与客户端的时钟偏差，系统允许的最大时钟偏差为 30 秒。
- **角色匹配但返回 403 Forbidden**：
  1. 确认角色授予范围：检查对应角色是否正确授予在用户当前所属的组织内（不能跨组织使用权限）。
  2. 检查租户映射记录：确认该租户在平台中真实存在，且租户记录中已成功写入 Zitadel 组织映射标识（`zitadel_org_id`）。

### 自定义域名与租户地址无法访问排查

- **自定义域名无法访问**：
  1. 检查域名验证状态：组织管理员需在工作台打开「我的组织」→「企业设置」→「域名」，确认域名状态已显示为「已验证」。系统对品牌与域名配置设有 30 秒 缓存。
  2. 检查证书签发状态：首次通过自定义域名访问时，网关会按需向证书机构申请签发证书。若打开页面显示空白，通常为证书签发过程中的短暂等待。
- **租户专属地址打不开**：
  1. 检查租户是否配置组织地址：在「我的组织」→「域名」中确认「组织的地址」是否已设置。
  2. 检查回调地址登记：若系统日志中出现「the sign-in could not learn the address」，需重启 kwork 主服务以补齐回调地址登记。
- **直接访问组织应用提示**：若成员在浏览器地址栏中直接打开 `https://organization.apps.{base}`，页面会弹出提示「请从工作台打开」，必须登录工作台后嵌入使用。
- **内置 CA 根证书不受信任**：若部署时采用内网 TLS 模式（`internal`），浏览器会提示证书不安全。管理员需将 `deploy/compose/state/gateway-root-ca.crt` 根证书文件导入客户端系统或浏览器的受信任根证书颁发机构。

### 模型网关与运营台数据不一致排查与同步

- **状态说明**：模型网关的管理界面（`llm.ops.{base}`）对模型供应商与租户密钥提供只读查看，不支持在网关界面中直接编辑。模型网关容器在重建启动后，会自动从系统拉取并同步一次数据。
- **手动重新同步步骤**：
  1. 在浏览器中打开平台运营台（`https://ops.{base}:8443`）。
  2. 在左侧导航中进入「模型供应商」管理页面。
  3. 找到「与网关的一致性」配置区域。
  4. 点击操作按钮「重新同步」，系统将立即把运营台中的模型配置全量同步至模型网关。

### 匿名访问与接口限流 429 排查

- **组织或客户端匿名限流**：
  - 提示信息：`too many anonymous requests from this address or for this organisation`。
  - 原因与配置：该租户或该客户端 IP 耗尽了安装级别的请求额度。由环境变量 `KWORK_APP_RPS` 控制，生产环境默认限制为 50/s（突发上限 100），本地开发栈通常限制为 5/s。
- **整应用匿名限流**：
  - 提示信息：`… for this App`。
  - 原因与配置：整应用下所有匿名请求累计超限，达到 `KWORK_APP_ANON_CEILING` 设定的倍数上限（默认限制为 `KWORK_APP_RPS` 的 10 倍）。
- **登录接口频率限制（HTTP 429）**：
  - 限制规则：10 分钟 内针对同一用户名最多尝试 10 次，针对同一客户端 IP 最多尝试 40 次。
  - Zitadel 提示：若触发 Zitadel 底层频率防护，页面会提示「尝试得太频繁了」。
- **修改密码锁定（HTTP 429）**：若连续输错旧密码累计 5 次，系统将锁定该账号 15 分钟。
- **模型调用频率限制**：超出每分钟限制时，界面提示「请求太频繁，超过了每分钟上限。」。
- **工作台常规限流**：频繁操作时，界面提示「请求太频繁」或「请稍后重试。」。
- **客户端 IP 识别与代理配置**：系统获取 `X-Forwarded-For` 头部中从右往左数第一个公网 IP 作为真实客户端地址。若网关前面部署了其它公网反向代理，必须将前置代理 IP 加入网关 Caddy 的 `trusted_proxies` 配置中，避免多用户共享同一代理 IP 导致误触发限流。

### WebSocket 连接故障排查

- **常见错误代码排查**：
  - **401 Unauthorized**：检查请求头中的 WebSocket 子协议是否为 `["k3.v1", "k3.token." + 令牌]`。连接令牌有效期仅为 10 分钟，过期需重新申请。
  - **403 Forbidden**：检查请求的 `Origin` 头部是否匹配 `{app}.apps.{base}` 格式；若为独立 ISV 应用，检查应用清单中是否配置了 `runtime.websocket: true` 权限。
  - **405 Method Not Allowed**：使用了助手（Agent）令牌尝试建立连接，系统不支持该凭据类型。
  - **429 Too Many Requests**：单租户并发连接数达到 `KWORK_APP_WS_PER_INSTALL` 限制（默认 200 个），或单用户并发连接数达到 `KWORK_APP_WS_PER_USER` 限制（默认 10 个）。
- **正常连接确认**：WebSocket 握手成功后，系统访问日志中会记录状态码 `status=101`。

### 主机安装与初始化常见问题排查

| 异常现象 | 排查定位与处理方法 |
|---|---|
| 主机预检失败 | 终端提示磁盘空间不足或端口被占用。根据提示扩容磁盘或释放 80、443、8443 端口；若确认跳过预检可附加 `--force` 参数。 |
| 浏览器提示证书错误（acme 模式） | 确认域名 DNS 解析已指向本机公网 IP，且服务器的 80 端口 在公网可正常访问。执行命令查看网关证书日志：<br>`docker compose logs gateway \| grep -i acme` |
| 浏览器提示证书错误（internal 模式） | 将网关根证书文件 `state/gateway-root-ca.crt` 导入操作系统或浏览器的受信任根证书存储库，完成后重启浏览器。 |
| 运营台登录后报 500 错误或循环跳转 | 执行命令查看代理日志：`docker compose logs oauth2-proxy`。<br>若使用内置 CA，必须确保存在配置文件 `deploy/compose/oauth2-proxy.env`，并在其中配置 `OAUTH2_PROXY_PROVIDER_CA_FILES` 指向网关根证书。 |
| Zitadel 容器一直未就绪 | 执行命令查看日志：`docker compose logs zitadel`。<br>常见原因为主机可用内存不足，或 `.env` 中的数据库密码与已有数据卷密码不一致。 |
| 国内网络拉取 Docker 镜像失败 | 执行安装脚本时附加 `--registry-mirror` 参数指定国内镜像源；或在有外网的机器上通过 `docker save` 导出镜像后在目标机执行 `docker load`。 |
| 编译构建时 Go 依赖拉取失败 | 执行安装脚本时附加 `--mirror cn` 参数启用国内代理源（goproxy.cn）。 |

### 其它常见异常速查

| 异常现象 | 处理方法 |
|---|---|
| 未配置 SMTP 发信服务 | 在运营台开通租户时必须勾选「直接返回邮箱验证码」；系统在平台自建登录页中会自动隐藏「发送验证码」按钮。 |
| 草稿应用冲突（HTTP 409） | 说明在草稿审阅后条目已被其它操作修改。处理方法：重新打开审阅页面，比对最新数据后再接受。 |
| Redis 启动失败导致服务无法启动 | 部署时若启用了 `--coord` 协调器模式，启动时连不上 Redis 会导致 kwork 主服务起不来。需排查 Redis 容器状态与网络连通性。 |
| PostgreSQL 备份复制槽丢失（lost） | 在数据库中删除失效的复制槽，执行 `docker compose restart pg-backup` 重启备份容器，并立刻手动触发一次全量备份。 |

## 状态说明

### 服务健康状态

| 状态 | 表现特征 | 说明 |
|---|---|---|
| 健康（healthy） | `/readyz` 接口返回 200（正文为 `ready`） | 数据库与密钥后端均正常连通，服务就绪。 |
| 不健康（unhealthy） | `/readyz` 接口返回 503，容器标记为 unhealthy | 数据库连接断开或 OpenBao 处于封存状态，系统触发 `KworkNotReady` 告警。 |

### OpenBao 密钥管理状态

```
容器重启 ───> 封存状态（Sealed，健康检查 503） ───[ 输入 3 份解封密钥 ]───> 正常解封（Unsealed，恢复加解密）
```

| 状态 | 说明 |
|---|---|
| 封存（sealed） | 容器重启后的默认状态。主加密密钥处于密封状态，无法加解密模型或存储密钥，健康检查返回 503。 |
| 已解封（unsealed） | 保管人输入 3 份解封份额后解除封存，服务恢复加解密能力。 |

### 客户端连接与重连状态

| 状态 | 界面表现 | 机制与行为 |
|---|---|---|
| 正常在线 | 各应用正常显示，无顶部提示 | WebSocket 成功连接（日志记录 `status=101`）。 |
| 断线重连 | 工作台提示「连接中断，正在重新连接…」 | 网络连接中断或服务端重启，前端自动执行重连流程。 |
| 服务重启过渡 | 浏览器展示网关兜底页，标题显示服务正在重启 | 访问地址遇到网关 502/503/504 错误，页面提示通常几秒钟就好、页面会自动重新打开，每 3 秒 自动重试。 |

## 让助手帮你做

助手无法执行底层故障排查和运维操作。助手不能解封 OpenBao、不能重启 Docker 容器、不能修改网关路由配置，也不能签发个人访问令牌（PAT）。

你可以向助手咨询常见故障的原因、排查命令与配置说明：

> OpenBao 重启后为什么显示封存？解封命令是什么？
> 工作台提示「连接中断，正在重新连接…」是什么原因？
> 登录提示「尝试得太频繁了」需要等待多长时间？
> 运营台与模型网关数据不一致该怎么处理？

> **注意**
>
> 解除 OpenBao 密钥封存、重启故障容器与修改环境变量涉及基础设施安全，必须由具备权限的运维人员在服务器终端手动执行。

## 设置

排查与调整系统限流、排空与认证常用的环境变量如下：

| 环境变量 / 设置项 | 默认值 | 说明 |
|---|---|---|
| `OPS_BIND` | `127.0.0.1` | 运维管理网络监听绑定地址。默认仅限本机访问，生产环境可通过 SSH 隧道连接。 |
| `CADDY_GLOBAL_OPTIONS` | — | 网关全局配置。内网环境使用内置 CA 时设置为 `local_certs`。 |
| `KWORK_AGENT_DRAIN_S` | `60` | 助手服务停止时的优雅排空等待时长（单位为秒）。 |
| `KWORK_APP_RPS` | `50` | 应用每秒请求频次上限（突发上限 100；本地开发栈常为 5）。 |
| `KWORK_APP_ANON_CEILING` | `10` | 整应用匿名请求总额度的倍数上限（相对于 `KWORK_APP_RPS`）。 |
| `KWORK_APP_WS_PER_INSTALL` | `200` | 单租户安装的并发 WebSocket 连接数上限。 |
| `KWORK_APP_WS_PER_USER` | `10` | 单用户的并发 WebSocket 连接数上限。 |
| `KWORK_OIDC_JWKS_URL` | — | Zitadel 身份中心的 JWKS 公钥获取地址。 |
| `KWORK_OIDC_JWKS_HOST` | `id.{base}` | 请求 JWKS 公钥时的主机头配置。 |
| `PROVISIONER_PAT_EXPIRY` | — | 平台管理员自动化拨备令牌（PAT）的有效期限。 |

## 注意事项

- **生产解封份额离线保管**：生产环境初始化生成的 5 个解封份额必须分发给不同保管人，严禁将包含明文密钥的 `compose/state/openbao-init.json` 保留在主机磁盘上，分发后必须立即删除该文件并吊销 root token。
- **致命崩溃排查方式**：服务致命崩溃（panic）信息仅输出在标准错误中，不会采集进入 Loki 日志大盘。排查时必须通过 `docker logs` 查看原始容器日志，且容器一旦被重建，旧日志即会丢失。
- **本地开发多会话冲突**：多个会话共同使用同一个本地开发栈时，会共享并互相挤占登录频次限额（10 分钟 内 10 次）。
- **单机备份损毁风险**：若采用单机部署且将 SeaweedFS 备份保存在同一台主机上，主机或磁盘发生整体物理损坏时备份将一同损毁。生产环境需配置 `BACKUP_S3_*` 将备份转储到外部独立存储。
- **数据库复制槽清理**：停止 `pg-backup` 备份服务后，必须在数据库中手动执行 `pg_drop_replication_slot` 删除复制槽；若未清理导致复制槽堆积超过 8 GB，数据库会丢弃复制槽导致数据断档。

## 目前不支持

- **面向租户的系统状态页**：系统当前未提供面向租户成员的统一系统状态展示页面。
- **自动化磁盘告警规则**：系统的 SLO 监控告警规则中暂未包含磁盘空间指标的自动告警。

## 常见问题

### 为什么执行容器重启后，服务健康检查一直报 503？

使用私有化部署（`onprem` 环境包）时，OpenBao 采用文件后端，每次容器重启后均会恢复为封存（sealed）状态。封存期间系统无法解密密钥，健康检查接口 `/readyz` 返回 503，容器显示为 unhealthy。你需要由 3 位保管人分别在服务器终端执行 `docker compose exec openbao bao operator unseal` 输入份额完成解封。

### 服务重启时，最终用户会看到什么现象？会丢失正在生成的回答吗？

容器同时启动时网关可能出现短暂 502。若用户整页刷新，会看到网关兜底页，标题为服务正在重启，正文提示通常几秒钟就好、页面会自动重新打开，并每 3 秒 自动重试。在工作台内的用户会看到提示「连接中断，正在重新连接…」。服务重启前会执行最多 60 秒（`KWORK_AGENT_DRAIN_S`）的优雅排空，尽量发送正在生成的回答；若排空超时，当前步骤标记为 `context canceled`，服务重启后在 15 秒 心跳后重新执行。

### 运营台开通租户或修改组织显示名返回 502 错误是什么原因？

开通租户返回 502 通常是因为 Zitadel 身份服务返回异常或 `PROVISIONER_PAT_EXPIRY` 令牌过期。开通失败时系统已自动回滚租户记录，排查确认 Zitadel 日志正常后直接重试即可。修改组织显示名返回 502 是因为 Zitadel 拒绝了所提交的名称，平台数据表同样已自动回滚，可更换合规名称后重新提交。

### 用户在登录或调用接口时遇到 429 限流如何恢复？

登录接口在 10 分钟 内对同一用户名限制 10 次、对同一 IP 限制 40 次，超出需等待冷却；修改密码输入错误旧密码 5 次会锁定 15 分钟；模型调用超出分钟限额会提示「请求太频繁，超过了每分钟上限。」。如果多台机器共用反向代理导致所有用户共享同一个 IP，需将前置代理 IP 配置到网关 Caddy 的 `trusted_proxies` 中，确保系统正确解析真实的客户端公网 IP。
