当K3s内置etcd因磁盘满触发mvcc: database space exceeded错误时,需先压缩历史版本、再碎片整理、最后解除告警;严禁直接删文件,须按revision生命周期操作,并配置自动压缩与扩容预防复发。

当 K3s 内置 etcd 因磁盘满触发 mvcc: database space exceeded 错误时,写操作会失败,集群可能进入只读或降级状态。这不是单纯删文件就能解决的问题,必须按 etcd 数据生命周期逻辑操作:先压缩历史版本、再整理碎片、最后解除告警,同时避免误删关键数据。
确认当前空间使用和 revision 状态
先快速判断是否真满、满到什么程度:
- 运行
ETCDCTL_API=3 etcdctl --endpoints=http://127.0.0.1:2379 --write-out=table endpoint status,查看DBSize和IsLeader字段;若 DBSize 接近或等于配额(默认 2GB),且状态栏显示dbm full或报警,则确认已满 - 获取最新 revision:
rev=$(ETCDCTL_API=3 etcdctl --endpoints=http://127.0.0.1:2379 endpoint status --write-out=json | grep -o '"revision":[0-9]*' | grep -o '[0-9]*'),这个值将用于后续压缩
执行安全压缩与碎片整理
压缩不是删除键,而是清理旧版本的 MVCC 历史记录;defrag 是回收物理磁盘空间。二者缺一不可,顺序不能颠倒:
- 先压缩:运行
ETCDCTL_API=3 etcdctl --endpoints=http://127.0.0.1:2379 compact $rev。注意:该命令仅保留 revision ≥ $rev 的版本,Kubernetes 对象的更新历史会被精简,但不会丢失当前状态 - 再整理:立即执行
ETCDCTL_API=3 etcdctl --endpoints=http://127.0.0.1:2379 defrag。这一步真正释放磁盘空间,耗时取决于数据量,期间 etcd 可能短暂响应变慢,但不中断服务 - 解除告警:
ETCDCTL_API=3 etcdctl --endpoints=http://127.0.0.1:2379 alarm disarm,否则即使空间已释放,etcd 仍拒绝写入
针对性清理高增长路径(可选但推荐)
K3s 中 /registry/events/ 和 /registry/minions/ 等路径常因频繁事件或节点心跳产生大量键,可按前缀批量清理:
- 查事件数量:
ETCDCTL_API=3 etcdctl --endpoints=http://127.0.0.1:2379 get --prefix /registry/events/ | wc -l,若远超千条,说明事件积压严重 - 清理旧事件:
ETCDCTL_API=3 etcdctl --endpoints=http://127.0.0.1:2379 del --prefix /registry/events/。Kubernetes 本身不依赖长期事件存档,清理后控制器会重建必要事件 - 谨慎操作:
/registry/pods/、/registry/nodes/等核心路径绝对不要用--prefix删除,否则导致集群失联
预防再次发生(必须做)
临时清理只能救急,K3s 启动参数需固化配置:
- 在
/etc/rancher/k3s/config.yaml中添加:etcd-experimental-backup-lease-duration: "60s"etcd-quota-backend-bytes: 8589934592(即 8GB)etcd-auto-compaction-retention: "1h" - 重启 K3s:
sudo systemctl restart k3s,新配置生效后,etcd 每小时自动压缩一次,并将上限提升至 8GB,大幅降低满盘风险 - 建议同步开启定期快照:
etcd-snapshot-schedule-cron: "0 */6 * * *(每6小时)+etcd-snapshot-dir: "/var/lib/rancher/k3s/server/db/snapshots"










