kubeadm安装的三个masterd的k8s的etcd数据库故障,如何通过备份数据进行恢复

当 kubeadm 部署的三 master 节点 K8s 集群中 etcd 数据库发生故障时,需结合 etcd 的备份文件(快照)进行恢复。

一、前提条件

  1. 存在有效的 etcd 快照备份 :需提前通过etcdctl snapshot save生成的快照文件(如etcd-snapshot-20251208.db),且备份时间点的数据完整。若未手动备份,可检查 etcd 数据目录(默认/var/lib/etcd)是否有残留的快照文件(如自动备份的member/snap/db),但该文件为 etcd 内部快照,恢复风险较高,优先使用手动备份。

  2. 确认 etcd 故障类型

    • 单节点 etcd 故障:仅某一 master 节点的 etcd 实例损坏,集群仍可用(etcd 集群需至少 1 个健康节点);
    • 多节点 / 全集群 etcd 故障:etcd 集群多数节点损坏(如 2/3 节点故障),集群不可用,需重建 etcd 集群并恢复数据

二、环境准备

  1. 停止故障节点的 control-plane 组件:若 etcd 与 control-plane 共节点(stacked 模式),需先停止 kubelet 管理的静态 Pod(etcd、kube-apiserver、kube-controller-manager、kube-scheduler):

    复制代码
    docker ps | grep -E "etcd|kube-apiserver"  #使用docker运行时
    或者
    crictl ps | grep -E "etcd|kube-apiserver"  #使用containerd运行时

    2.备份故障节点的 etcd 数据目录:避免数据覆盖,先备份现有 etcd 数据(若有残留):

    mv /var/lib/etcd /var/lib/etcd.bak-$(date +%Y%m%d%H%M%S)
    mkdir -p /var/lib/etcd

三、单节点 etcd 故障恢复(集群仍可用)

若 etcd 集群仅单节点故障,可通过etcd 集群成员重新加入 + 数据恢复完成修复:

1. 从 etcd 集群中移除故障节点(在健康 master 节点执行)
复制代码
# 1. 获取etcd集群成员列表,找到故障节点的ID/名称
etcdctl --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  member list



# 2. 移除故障节点(替换<故障节点ID>)
etcdctl --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  member remove <故障节点ID>
2. 恢复 etcd 快照到故障节点
复制代码
# 1. 从快照恢复etcd数据(替换<快照文件路径>)
etcdctl snapshot restore <快照文件路径> \
  --data-dir=/var/lib/etcd \
  --name=master-03 \  # 故障节点的etcd名称(需与原集群一致)
  --initial-cluster=master-01=https://192.168.1.10:2380,master-02=https://192.168.1.11:2380,master-03=https://192.168.1.12:2380 \  # 全集群成员地址
  --initial-cluster-token=etcd-cluster-token \  # 原集群token(可从健康节点/etc/kubernetes/manifests/etcd.yaml中获取)
  --initial-advertise-peer-urls=https://192.168.1.12:2380  # 故障节点的etcd peer地址(与原集群一致)

# 2. 修复etcd数据目录权限
chown -R root:root /var/lib/etcd
chmod 700 /var/lib/etcd
3. 重新加入 etcd 集群(在健康 master 节点执行)
复制代码
# 添加故障节点到etcd集群(替换<故障节点IP>和<节点名称>)
etcdctl --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  member add <节点名称> --peer-urls=https://<故障节点IP>:2380
4. 恢复故障节点的静态 Pod 配置
复制代码
# 移回静态Pod配置文件,kubelet会自动重启etcd和control-plane组件
mv /tmp/* /etc/kubernetes/manifests/
# 验证etcd集群状态(故障节点应重新加入,集群健康)
etcdctl --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  endpoint health --cluster

四、全集群 etcd 故障恢复(集群不可用)

若 etcd 集群全节点故障,需重建 etcd 集群 + 恢复快照,再重建 control-plane 组件:

1. 停止所有 master 节点的 control-plane 组件

在所有 master 节点执行:

复制代码
mv /etc/kubernetes/manifests/* /tmp/
rm -rf /var/lib/etcd/*
2. 从快照恢复 etcd 集群(选择一个 master 节点作为第一个节点)
复制代码
# 1. 恢复etcd快照到第一个节点(替换参数为实际值)
etcdctl snapshot restore <快照文件路径> \
  --data-dir=/var/lib/etcd \
  --name=master-01 \
  --initial-cluster=master-01=https://192.168.1.10:2380,master-02=https://192.168.1.11:2380,master-03=https://192.168.1.12:2380 \
  --initial-cluster-token=etcd-cluster-token \
  --initial-advertise-peer-urls=https://192.168.1.10:2380

# 2. 修复权限
chown -R root:root /var/lib/etcd
chmod 700 /var/lib/etcd
3. 启动第一个节点的 etcd 静态 Pod

编辑第一个节点的/etc/kubernetes/manifests/etcd.yaml,确保command中的参数与恢复时的initial-clustername等一致,然后启动 etcd:

复制代码
# 复制etcd.yaml到manifests目录(若已移走)
cp /tmp/etcd.yaml /etc/kubernetes/manifests/
# 验证etcd单节点启动成功
etcdctl --endpoints=https://192.168.1.10:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  endpoint health
4. 加入其他 etcd 节点到集群

在第一个节点执行:

复制代码
# 添加master-02节点(替换参数)
etcdctl --endpoints=https://192.168.1.10:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  member add master-02 --peer-urls=https://192.168.1.11:2380

# 添加master-03节点(替换参数)
etcdctl --endpoints=https://192.168.1.10:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  member add master-03 --peer-urls=https://192.168.1.12:2380

在 master-02 和 master-03 节点执行快照恢复(步骤同 2,但initial-advertise-peer-urls为对应节点 IP),然后启动 etcd 静态 Pod。

5. 重建 control-plane 组件

在所有 master 节点恢复/etc/kubernetes/manifests/下的所有静态 Pod 配置文件(kube-apiserver、kube-controller-manager、kube-scheduler),kubelet 会自动重启组件:

复制代码
mv /tmp/* /etc/kubernetes/manifests/
# 验证control-plane组件启动成功
kubectl get pods -n kube-system | grep -E "apiserver|controller-manager|scheduler"

恢复完成后,需验证:

  • etcd 集群健康:etcdctl endpoint health --cluster
  • K8s 集群资源正常:kubectl get nodeskubectl get pods -A
  • 服务可用性:验证 Pod 调度、Service 访问等核心功能。

参考消息

kubeadm 1.21 及以上版本提供了etcd 快照的自动化备份与恢复工具(没有测试过,感兴趣的可以验证一下)

复制代码
# 1. 备份etcd快照(kubeadm方式)
kubeadm alpha etcd snapshot save /backup/etcd-snapshot-$(date +%Y%m%d).db

# 2. 恢复etcd快照(kubeadm方式,需停止control-plane组件)
kubeadm alpha etcd snapshot restore /backup/etcd-snapshot-20251208.db \
  --data-dir=/var/lib/etcd \
  --kubeconfig=/etc/kubernetes/admin.conf \
  --cert-dir=/etc/kubernetes/pki
相关推荐
码农阿豪2 小时前
从 Oracle 到金仓:一次真实数据库迁移的避坑实录
数据库·oracle
金海境科技2 小时前
亲测正规数据库修复恢复数据标准
数据库
robin59112 小时前
容器-汇总所有环境下的日志排查问题
linux·容器·kubernetes
weixin_46682 小时前
ks8核心组件、Pod分类、网络模型
云原生·容器·kubernetes
Hello.Reader2 小时前
Flink SQL 中的 OVER 聚合——为每一行算“窗口统计
数据库·sql·flink
JIngJaneIL2 小时前
基于Java旅游信息推荐系统(源码+数据库+文档)
java·开发语言·数据库·vue.js·spring boot·旅游
LSL666_2 小时前
mybatisplus入门案例
数据库·mysql·mybatisplus
ZePingPingZe3 小时前
DriverManager、DataSource、数据库驱动以及数据库连接池的关系
android·数据库·adb
Loiioฅ3 小时前
ctfshow-web入门-sql注入-171-186
数据库·sql