-
备份存储位置 :KubeKey创建的etcd备份,默认存放在每个etcd节点的
/var/backups/kube_etcd/目录下。你之前恢复时用到的etcd-2026-08-14-02-00-01这个目录,应该就在这个路径里。 -
备份保留策略 :根据一些社区反馈,etcd的自动备份脚本虽然设计了保留最近N个备份的机制(例如保留6个),但在某些版本中可能没有完全按预期工作,导致所有历史备份都被保留了下来。这也解释了为什么你能看到像
08-14这样的历史备份。这意味着你手上的备份很可能比预期的更丰富,可以用更早的时间点来尝试恢复。 -
恢复的依赖条件 :之前恢复失败,一个核心原因是集群中其他etcd节点(master2、master3)的数据与master1上的备份数据产生了冲突(Cluster ID不匹配),导致无法形成一致的集群。因此,恢复的关键在于确保所有节点基于同一份备份数据启动。
基于备份的恢复思路
有了备份,我们可以调整策略,不再纠结于修复当前混乱的状态,而是直接使用一个一致的、干净的备份来重建etcd集群。这样能从根本上解决Cluster ID冲突的问题。
-
选定一个可靠的备份 :目录
etcd-2026-08-14-02-00-01下的snapshot.db就是我们之前尝试恢复的文件。如果它仍存在问题,可以考虑检查是否有更早或更晚的备份。 -
清理所有节点,统一恢复 :这是最关键的一步。我们需要在所有三个etcd节点(master1、master2、master3)上,都使用同一份
snapshot.db文件进行恢复,这样它们启动后就会拥有相同的集群ID和数据,从而能够组成一个健康的集群。 -
恢复后的节点添加:当etcd集群恢复健康后,再通过Kube
查看etcd节点信息
cat /etc/etcd.env
诊断ETCD启动状态
# 1. 查看 etcd 服务状态
systemctl status etcd
# 2. 查看 etcd 详细日志(重点关注错误信息)
journalctl -u etcd -n 100 --no-pager
# 3. 检查 etcd 是否在监听端口
netstat -tlnp | grep -E "2379|2380"
ss -tlnp | grep -E "2379|2380"
# 4. 检查证书文件是否存在且可读
ls -la /etc/ssl/etcd/ssl/ | grep master3
# 5. 检查数据目录权限
ls -la /var/lib/ | grep etcd
完整的恢复步骤
步骤 1:在每个节点上停止 etcd 并清理数据
在 master1、master2、master3 上分别执行:
bash
systemctl stop etcd
rm -rf /var/lib/etcd
恢复前,需要清空各节点 的/var/lib/etcd 目录
步骤 2:使用同一份备份文件在每个节点上恢复
确保所有节点使用同一份 snapshot.db 文件。你可以将备份文件复制到其他节点:
bash
# 在 master1 上,将备份文件复制到其他节点
scp /root/etcd-2026-08-14-02-00-01/snapshot.db master2:/root/
scp /root/etcd-2026-08-14-02-00-01/snapshot.db master3:/root/
步骤 3:按顺序恢复
先在 master1 上执行恢复和启动:
bash
# 在 master1 上
ETCDCTL_API=3 etcdctl snapshot restore /root/snapshot.db \
--name=etcd-master1 \
--initial-cluster="etcd-master1=https://162.16.3.212:2380,etcd-master2=https://162.16.3.213:2380,etcd-master3=https://162.16.3.214:2380" \
--initial-advertise-peer-urls="https://162.16.3.212:2380" \
--data-dir=/var/lib/etcd
# chown -R etcd:etcd /var/lib/etcd 恢复时未操作此步骤
systemctl start etcd
systemctl status etcd
然后 master2:
bash
# 在 master2 上
ETCDCTL_API=3 etcdctl snapshot restore /root/snapshot.db \
--name=etcd-master2 \
--initial-cluster="etcd-master1=https://162.16.3.212:2380,etcd-master2=https://162.16.3.213:2380,etcd-master3=https://162.16.3.214:2380" \
--initial-advertise-peer-urls="https://162.16.3.213:2380" \
--data-dir=/var/lib/etcd
# chown -R etcd:etcd /var/lib/etcd 恢复时未操作此步骤
systemctl start etcd
systemctl status etcd
最后 master3:
bash
# 在 master3 上
ETCDCTL_API=3 etcdctl snapshot restore /root/snapshot.db \
--name=etcd-master3 \
--initial-cluster="etcd-master1=https://162.16.3.212:2380,etcd-master2=https://162.16.3.213:2380,etcd-master3=https://162.16.3.214:2380" \
--initial-advertise-peer-urls="https://162.16.3.214:2380" \
--data-dir=/var/lib/etcd
# chown -R etcd:etcd /var/lib/etcd 恢复时未操作此步骤
systemctl start etcd
systemctl status etcd
步骤 4:验证 etcd 集群健康
在 master1 上执行:
bash
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \
--cacert=/etc/ssl/etcd/ssl/ca.pem \
--cert=/etc/ssl/etcd/ssl/member-master1.pem \
--key=/etc/ssl/etcd/ssl/member-master1-key.pem \
endpoint health --cluster
测试环境恢复脚本,分别在各节点执行
ETCDCTL_API=3 etcdctl snapshot restore snapshot.db \
--name=etcd-master1 \
--initial-cluster="etcd-master1=https://162.16.3.212:2380,etcd-master3=https://162.16.3.214:2380,etcd-master2=https://162.16.3.213:2380" \
--initial-advertise-peer-urls="https://162.16.3.212:2380" \
--data-dir=/var/lib/etcd
ETCDCTL_API=3 etcdctl snapshot restore /home/snapshot.db \
--name=etcd-master2 \
--initial-cluster="etcd-master1=https://162.16.3.212:2380,etcd-master3=https://162.16.3.214:2380,etcd-master2=https://162.16.3.213:2380" \
--initial-advertise-peer-urls="https://162.16.3.213:2380" \
--data-dir=/var/lib/etcd
ETCDCTL_API=3 etcdctl snapshot restore /home/snapshot.db \
--name=etcd-master3 \
--initial-cluster="etcd-master1=https://162.16.3.212:2380,etcd-master3=https://162.16.3.214:2380,etcd-master2=https://162.16.3.213:2380" \
--initial-advertise-peer-urls="https://162.16.3.214:2380" \
--data-dir=/var/lib/etcd
KubeKey 确实会在安装集群时,自动在每个 etcd 节点上部署一个用于备份的定时任务(CronJob),这个任务的实现和配置通常是由几个部分共同完成的。
📍 定时任务和脚本的位置
KubeKey 通过 backup-etcd.timer 定时器 + backup-etcd.service 服务实现了自动备份。
- 备份脚本 :主要的逻辑都写在一个 Shell 脚本里,你在每个 etcd 节点的以下路径可以找到它:
/usr/local/bin/kube-scripts/etcd-backup.sh
[root@master1 kube-scripts]# cat etcd-backup.sh
#!/bin/bash
set -o errexit
set -o nounset
set -o pipefail
ETCDCTL_PATH='/usr/local/bin/etcdctl'
ENDPOINTS='https://162.16.3.212:2379'
ETCD_DATA_DIR="/var/lib/etcd"
BACKUP_DIR="/var/backups/kube_etcd/etcd-$(date +%Y-%m-%d-%H-%M-%S)"
KEEPBACKUPNUMBER='6'
ETCDBACKUPSCIPT='/usr/local/bin/kube-scripts'
ETCDCTL_CERT="/etc/ssl/etcd/ssl/admin-master1.pem"
ETCDCTL_KEY="/etc/ssl/etcd/ssl/admin-master1-key.pem"
ETCDCTL_CA_FILE="/etc/ssl/etcd/ssl/ca.pem"
[ ! -d $BACKUP_DIR ] && mkdir -p $BACKUP_DIR
export ETCDCTL_API=2;$ETCDCTL_PATH backup --data-dir $ETCD_DATA_DIR --backup-dir $BACKUP_DIR
sleep 3
{
export ETCDCTL_API=3;$ETCDCTL_PATH --endpoints="$ENDPOINTS" snapshot save $BACKUP_DIR/snapshot.db \
--cacert="$ETCDCTL_CA_FILE" \
--cert="$ETCDCTL_CERT" \
--key="$ETCDCTL_KEY"
} > /dev/null
sleep 3
cd $BACKUP_DIR/../ && ls -lt |awk '{if(NR > '$KEEPBACKUPNUMBER'){print "rm -rf "$9}}'|sh
查看和管理备份任务
[root@master1 kubekey]# systemctl list-timers --all | grep etcd
五 2026-08-21 02:00:00 CST 17h left 四 2026-08-20 02:00:01 CST 6h ago backup-etcd.timer backup-etcd.service
你可以用这些命令来管理这个定时器:
bash
# 1. 查看定时器的详细状态(包括下一次触发时间)
systemctl status backup-etcd.timer
# 2. 查看关联的服务(备份脚本实际上在这里执行)
systemctl status backup-etcd.service
# 3. 查看服务单元的完整配置
systemctl cat backup-etcd.service
systemctl cat backup-etcd.timer
# 4. 查看备份脚本的具体内容
cat /usr/local/bin/kube-scripts/etcd-backup.sh
⚙️ 备份脚本如何工作
这个脚本的核心工作流程如下:
-
环境准备 :它会设置
ETCDCTL_API=3来使用 etcd 的 v3 API。 -
创建快照 :脚本会调用
etcdctl snapshot save命令,并指定证书文件路径(通常在/etc/ssl/etcd/ssl/下)来连接本地 etcd 服务,生成一个名为snapshot.db的快照文件,并保存在一个以备份时间命名的目录下,比如/var/backups/kube_etcd/etcd-2026-08-14-02-00-01/。 -
清理旧备份 :为了避免备份文件无限增长,脚本默认会尝试保留最新的 6 个 备份,并删除更早的备份文件。
💡 需要留意的一个已知问题
社区有反馈提到,etcd-backup.sh 脚本中用于计算旧备份数量的逻辑,在某些系统环境下可能无法正常工作,导致旧备份不会被自动清理,最终可能占用大量磁盘空间。
为了保险起见,你可以去检查一下备份目录 /var/backups/kube_etcd/,看看历史上是否累积了过多的备份文件夹。如果太多了,记得手动清理一些,防止磁盘被写满。
🛠️ 手动执行备份来测试
如果想把问题定位得更准确一些,可以尝试手动执行一次备份脚本,看看它是否会报错,以及能否正常清理旧文件:
bash
bash /usr/local/bin/kube-scripts/etcd-backup.sh
如果执行时遇到和"删除旧备份"相关的错误,那么手动删除一些旧备份文件夹也是目前最直接的办法。