Kuboard 单节点 etcd 触发 NOSPACE 报警的真实排查与修复过程
环境:Kuboard v3 单节点部署
## 故障现象
某天突然访问 Kuboard 界面,报错如下:
```json
{
"message": "Failed to connect to the database.",
"type": "Internal Server Error"
}浏览器直接白屏或无法登录,SSO 认证也失败。这不是 Kuboard 本身的数据库问题,而是它依赖的 etcd(Kuboard v3 把 etcd 跑在同一个容器内)出了状况,导致 Kuboard 无法连接 etcd。问题根源
进入 Kuboard 容器(docker exec -it <kuboard-container> /bin/bash)
执行 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 会报错,但这不影响后续清理。完整步骤如下:
进入 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 超限。
获取当前 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 左右)
尝试 compaction压缩
bash
ETCDCTL_API=3 etcdctl --endpoints=127.0.0.1:2379 --command-timeout=300s compact $((REV - 10000))执行 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]检查 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,但我更保守,先确保空间够用)。
手动 disarm NOSPACE 报警(恢复写权限)
bash
ETCDCTL_API=3 etcdctl --endpoints=127.0.0.1:2379 alarm disarm输出类似:
memberID:xxx alarm:NOSPACE disarmed
退出容器,刷新 Kuboard 页面 → 登录成功,界面恢复。