Skip to content

常见故障 ​

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

谁能用 ​

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

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

怎么打开 ​

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

检查项目 / 工具访问入口 / 执行命令说明
容器运行状态在服务器终端执行 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检查模型网关一致性、重试租户开通操作。
组织管理入口登录 工作台,打开「我的组织」排查自定义域名解析状态与组织配置。

界面一览 ​

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 端口 在公网可正常访问。执行命令查看网关证书日志:
docker compose logs gateway | grep -i acme
浏览器提示证书错误(internal 模式)将网关根证书文件 state/gateway-root-ca.crt 导入操作系统或浏览器的受信任根证书存储库,完成后重启浏览器。
运营台登录后报 500 错误或循环跳转执行命令查看代理日志:docker compose logs oauth2-proxy。
若使用内置 CA,必须确保存在配置文件 deploy/compose/oauth2-proxy.env,并在其中配置 OAUTH2_PROXY_PROVIDER_CA_FILES 指向网关根证书。
Zitadel 容器一直未就绪执行命令查看日志:docker compose logs zitadel。
常见原因为主机可用内存不足,或 .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_BIND127.0.0.1运维管理网络监听绑定地址。默认仅限本机访问,生产环境可通过 SSH 隧道连接。
CADDY_GLOBAL_OPTIONS—网关全局配置。内网环境使用内置 CA 时设置为 local_certs。
KWORK_AGENT_DRAIN_S60助手服务停止时的优雅排空等待时长(单位为秒)。
KWORK_APP_RPS50应用每秒请求频次上限(突发上限 100;本地开发栈常为 5)。
KWORK_APP_ANON_CEILING10整应用匿名请求总额度的倍数上限(相对于 KWORK_APP_RPS)。
KWORK_APP_WS_PER_INSTALL200单租户安装的并发 WebSocket 连接数上限。
KWORK_APP_WS_PER_USER10单用户的并发 WebSocket 连接数上限。
KWORK_OIDC_JWKS_URL—Zitadel 身份中心的 JWKS 公钥获取地址。
KWORK_OIDC_JWKS_HOSTid.{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。