现场是这样的。自建 K8s 1.26 集群误删了 namespace,从三天前的 etcd 快照恢复,恢复完成后 apiserver 启动报 unable to find a suitable etcd version,集群起不来。

中间走过弯路,把「集群里还有节点在跑旧数据,恢复后成员列表对不上」当成主因,改完现象没变。

这类报错背后常见的原因有几处,逐个排除就行。恢复时用的 etcdctl 版本和快照生成时的版本差了小版本;快照恢复到新的数据目录,但 etcd 的启动参数还指向旧路径;恢复前没有停 kube-apiserver,写入把恢复的数据又覆盖了。

上来先停掉控制面组件再动数据

systemctl stop kube-apiserver kube-controller-manager kube-scheduler

再往下查看快照的元信息确认版本

etcdctl snapshot status /backup/etcd-1101.db -w table

恢复到全新数据目录并核对成员信息

etcdctl snapshot restore /backup/etcd-1101.db --data-dir=/var/lib/etcd-restore

末了改启动参数指向新目录后重启 etcd

systemctl restart etcd && etcdctl endpoint health

怎么算真的好了,看的是同一批现象。etcdctl endpoint health 返回 healthy,kube-apiserver 正常启动,kubectl get ns 能看到恢复时间点之前的对象。

容易忽略的是,恢复前务必停掉 apiserver,否则恢复出来的数据立刻又被写脏;快照和 etcd 二进制版本要保持一致,跨小版本恢复经常失败。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。

作者 9823189