关于KubeKey的etcd备份

  1. 备份存储位置 :KubeKey创建的etcd备份,默认存放在每个etcd节点的 /var/backups/kube_etcd/ 目录下。你之前恢复时用到的etcd-2026-08-14-02-00-01这个目录,应该就在这个路径里。

  2. 备份保留策略 :根据一些社区反馈,etcd的自动备份脚本虽然设计了保留最近N个备份的机制(例如保留6个),但在某些版本中可能没有完全按预期工作,导致所有历史备份都被保留了下来。这也解释了为什么你能看到像 08-14 这样的历史备份。这意味着你手上的备份很可能比预期的更丰富,可以用更早的时间点来尝试恢复。

  3. 恢复的依赖条件 :之前恢复失败,一个核心原因是集群中其他etcd节点(master2、master3)的数据与master1上的备份数据产生了冲突(Cluster ID不匹配),导致无法形成一致的集群。因此,恢复的关键在于确保所有节点基于同一份备份数据启动

基于备份的恢复思路

有了备份,我们可以调整策略,不再纠结于修复当前混乱的状态,而是直接使用一个一致的、干净的备份来重建etcd集群。这样能从根本上解决Cluster ID冲突的问题。

  1. 选定一个可靠的备份 :目录 etcd-2026-08-14-02-00-01 下的 snapshot.db 就是我们之前尝试恢复的文件。如果它仍存在问题,可以考虑检查是否有更早或更晚的备份。

  2. 清理所有节点,统一恢复 :这是最关键的一步。我们需要在所有三个etcd节点(master1、master2、master3)上,都使用同一份 snapshot.db 文件进行恢复,这样它们启动后就会拥有相同的集群ID和数据,从而能够组成一个健康的集群。

  3. 恢复后的节点添加:当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 服务实现了自动备份。

  1. 备份脚本 :主要的逻辑都写在一个 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
​

⚙️ 备份脚本如何工作

这个脚本的核心工作流程如下:

  1. 环境准备 :它会设置 ETCDCTL_API=3 来使用 etcd 的 v3 API。

  2. 创建快照 :脚本会调用 etcdctl snapshot save 命令,并指定证书文件路径(通常在 /etc/ssl/etcd/ssl/ 下)来连接本地 etcd 服务,生成一个名为 snapshot.db 的快照文件,并保存在一个以备份时间命名的目录下,比如 /var/backups/kube_etcd/etcd-2026-08-14-02-00-01/

  3. 清理旧备份 :为了避免备份文件无限增长,脚本默认会尝试保留最新的 6 个 备份,并删除更早的备份文件。

💡 需要留意的一个已知问题

社区有反馈提到,etcd-backup.sh 脚本中用于计算旧备份数量的逻辑,在某些系统环境下可能无法正常工作,导致旧备份不会被自动清理,最终可能占用大量磁盘空间。

为了保险起见,你可以去检查一下备份目录 /var/backups/kube_etcd/,看看历史上是否累积了过多的备份文件夹。如果太多了,记得手动清理一些,防止磁盘被写满。

🛠️ 手动执行备份来测试

如果想把问题定位得更准确一些,可以尝试手动执行一次备份脚本,看看它是否会报错,以及能否正常清理旧文件:

bash

复制代码
bash /usr/local/bin/kube-scripts/etcd-backup.sh

如果执行时遇到和"删除旧备份"相关的错误,那么手动删除一些旧备份文件夹也是目前最直接的办法。

相关推荐
最强小杰2 小时前
gpt-5.6-sol 频繁报 503 怎么办?区分容量熔断和限速 429 的排查方法 + 可复用 retry wrapper
java·人工智能·gpt·ai
今天AI了吗2 小时前
Python 基础语法(一):常量、变量、输入输出与运算符
开发语言·数据库·人工智能·python·sql·深度学习·机器学习
lilian2334 小时前
Harmony os 技术实战|拼豆制图27:用单字符编码承载 50 张 70×70 图纸
前端·数据库·华为·harmonyos
吠品4 小时前
Wine 在 Linux 上运行 Windows 软件完整指南
java·linux·服务器
皮卡丘不断更4 小时前
手机优先的 Personal Ledger:把账目、学习和复盘放到同一个入口
数据库·sqlite·fastapi·开源项目·个人效率
保卫大狮兄5 小时前
设备管理从台账到报废,完整生命周期一次讲清
数据库·设备管理·设备
亚历克斯神5 小时前
智能搜索系统的升级复盘——从 Elasticsearch 到混合检索的检索质量提升
java·spring·微服务
数据安全技术观察5 小时前
数据动态脱敏:让脱敏策略跟着数据目录走
大数据·网络·数据库
金銀銅鐵6 小时前
[Java] 一个方法最多可以有多少个入参?
java·jvm
小席是个热心肠6 小时前
Redis的自我学习
数据库·redis·学习