环境:Kuboard v3 单节点部署
## 故障现象

某天突然访问 Kuboard 界面,报错如下:

```json
{
  "message": "Failed to connect to the database.",
  "type": "Internal Server Error"
}

浏览器直接白屏或无法登录,SSO 认证也失败。这不是 Kuboard 本身的数据库问题,而是它依赖的 etcd(Kuboard v3 把 etcd 跑在同一个容器内)出了状况,导致 Kuboard 无法连接 etcd。问题根源

  1. 进入 Kuboard 容器(docker exec -it <kuboard-container> /bin/bash)

  2. 执行 etcd 状态检查:

bash

etcdctl endpoint status --write-out=table

发现经典症状:

  • DB SIZE: 2.1 GB(正好卡在 etcd 默认 quota 2GB 上)

  • ERRORS: alarm:NOSPACE

  • 详细 JSON 查看:dbSize ≈ 2.1GB,dbSizeInUse 极小(几百 KB)

etcd 一旦触发 NOSPACE 报警,就会进入永久只读模式(只能读和删,不能写新数据),Kuboard 作为 etcd 的重度使用者,自然就“连不上数据库”了。修复流程(我实际执行的顺序)因为之前集群已经开启了自动 compaction(或手动压缩过),历史 revision 已经被压缩,所以直接 compact 会报错,但这不影响后续清理。完整步骤如下:

  1. 进入 Kuboard 容器,确认 etcd 状态

    bash

    etcdctl endpoint status --write-out=table
    # 或 JSON 版
    ETCDCTL_API=3 etcdctl --endpoints=127.0.0.1:2379 endpoint status --write-out=json

    确认 NOSPACE 报警和 dbSize 超限。

  2. 获取当前 revision(用于参考)

    bash

    REV=$(ETCDCTL_API=3 etcdctl --endpoints=127.0.0.1:2379 endpoint status --write-out=json | grep -o '"revision":[0-9]*' | grep -o '[0-9]*' | head -1)
    echo "当前 revision: $REV"

    (我的例子中是 6079702 左右)

  3. 尝试 compaction压缩

    bash

    ETCDCTL_API=3 etcdctl --endpoints=127.0.0.1:2379 --command-timeout=300s compact $((REV - 10000))

  4. 执行 defrag 释放碎片(加超时参数,避免卡住)因为 etcd 操作有时较慢(尤其 dbSize 大时),我加了 --command-timeout=300s

    bash

    ETCDCTL_API=3 etcdctl --endpoints=127.0.0.1:2379 --command-timeout=300s defrag

    成功输出:

    Finished defragmenting etcd member[127.0.0.1:2379]
  5. 检查 dbSize 是否下降再次运行:

    bash

    ETCDCTL_API=3 etcdctl --endpoints=127.0.0.1:2379 endpoint status --write-out=json

    我的情况:dbSizeInUse 只有几百 KB,defrag 后 dbSize 下降到低于 2GB(实际降到 几百 MB 左右)。关键:我等到确认 dbSize < 2GB 后,才进行下一步 disarm(虽然很多文档说可以先 disarm,但我更保守,先确保空间够用)。

  6. 手动 disarm NOSPACE 报警(恢复写权限)

    bash

    ETCDCTL_API=3 etcdctl --endpoints=127.0.0.1:2379 alarm disarm

    输出类似:

    memberID:xxx alarm:NOSPACE disarmed


退出容器,刷新 Kuboard 页面 → 登录成功,界面恢复。