目 录CONTENT

文章目录
k8s

K8s master1节点彻底崩溃后的恢复实战

天行1st
2026-07-16 / 0 评论 / 0 点赞 / 1 阅读 / 0 字

前几天有个现场,使用了新华三超融合云的3台虚拟机做了3 master 节点的 K8s 集群,部署节点master1系统崩溃,云厂家运维使用master2镜像克隆恢复master1,导致集群彻底崩溃,亟待修复。那么如何一步步恢复?本文记录了一次的真实恢复过程,涵盖 etcd 成员清理、HAProxy 修复、kubeadm-config 重建、节点 NotReady 排查、本地存储 PVC 重建等 6 个关键阶段。

1 背景

生产环境 K8s 集群基本信息:

项目配置
部署工具KubeKey 2.x
K8s 版本v1.22.12
Master 节点3 台(master1/2/3,172.16.198.201/202/203)
etcd外置 systemd 服务,3 副本
高可用方案内置 HAProxy(lb.kubesphere.local → 127.0.0.1:6443)
存储方案Rook-Ceph + local-path
监控KubeSphere 自带 Prometheus

本文记录了恢复过程,希望给遇到类似情况的同学一份可操作的参考。

2 恢复流程总览

当前状态: master1 已重装(空机器), master2/3 正常, etcd 有 quorum

Phase 0: 安全备份 etcd 快照
    ↓
Phase 1: 清理死节点 —— 移除 etcd 死成员 + 删除 k8s node
    ↓
Phase 2: 执行 kk add nodes —— 遭遇 HAProxy 连接拒绝
    ↓
Phase 3: 修复 HAProxy + 重建 kubeadm-config.yaml (缺少 ClusterConfiguration)
    ↓
Phase 4: master1 加入集群 —— 遭遇 NotReady + Pod 全部 Pending
    ↓
Phase 5: 修复 Prometheus PVC (local 存储丢失)
    ↓
恢复完成: 3 节点 Ready, 所有 Pod Running

3 恢复创建集群配置文件

从当前已创建的集群恢复配置文件

./kk create config --from-cluster

恢复了一半,我们使用离线部署还需要继续修改

手动修改配置文件

3 备份etcd数据

master2执行

export ETCDCTL_API=3

ETCDCTL=$(command -v etcdctl || echo /usr/local/bin/etcdctl)
ETCDUTL=$(command -v etcdutl || echo /usr/local/bin/etcdutl)

HOSTNAME=$(hostname)
BACKUP_DIR=/root/etcd-backup-$(date +%F-%H%M%S)
mkdir -p "$BACKUP_DIR"

ls /etc/ssl/etcd/ssl/

export ETCDCTL_API=3

CACERT=/etc/ssl/etcd/ssl/ca.pem
CERT=/etc/ssl/etcd/ssl/admin-master2.pem
KEY=/etc/ssl/etcd/ssl/admin-master2-key.pem
ENDPOINT=https://127.0.0.1:2379

# 检测 etcd 健康
$ETCDCTL \
  --endpoints="$ENDPOINT" \
  --cacert="$CACERT" \
  --cert="$CERT" \
  --key="$KEY" \
  endpoint health

备份

SNAPSHOT="$BACKUP_DIR/etcd-snapshot.db"

$ETCDCTL \
  --endpoints="$ENDPOINT" \
  --cacert="$CACERT" \
  --cert="$CERT" \
  --key="$KEY" \
  snapshot save "$SNAPSHOT"

验证

$ETCDCTL snapshot status "$SNAPSHOT" -w table

备份证书

cp -a /etc/ssl/etcd/ssl /root/etcd-backup-2026-07-04-112311/etcd-ssl

4 剔除master1成员

./kk delete node master1 -f config-sample.yaml

由于master1系统已重装,数据也全部丢失,执行失败,改为手动剔除

检查 etcd 成员状态

export ETCDCTL_API=3

CACERT=/etc/ssl/etcd/ssl/ca.pem
CERT=/etc/ssl/etcd/ssl/admin-master2.pem
KEY=/etc/ssl/etcd/ssl/admin-master2-key.pem
ENDPOINT=https://127.0.0.1:2379

etcd集群状态

移除 etcd 死成员

查看etcd成员情况

$ETCDCTL \
  --endpoints="$ENDPOINT" \
  --cacert="$CACERT" \
  --cert="$CERT" \
  --key="$KEY" \
  member list -w table

找到 master1 那一行的 ID,然后删除它:

$ETCDCTL \
  --endpoints="$ENDPOINT" \
  --cacert="$CACERT" \
  --cert="$CERT" \
  --key="$KEY" \
  member remove d1da9cc07dfdff01

删除master1节点

kubectl delete node master1

5 重新添加master1节点

./kk add nodes -f config-sample.yaml

报错:

备份

cp /etc/kubernetes/kubeadm-config.yaml /etc/kubernetes/kubeadm-config.yaml.bak

修复kubeadm-config

master2和master3执行

kubectl get configmap kubeadm-config -n kube-system -o jsonpath='{.data.ClusterConfiguration}' > /tmp/clusterconfig.yaml
echo "---" >> /etc/kubernetes/kubeadm-config.yaml
cat /tmp/clusterconfig.yaml >> /etc/kubernetes/kubeadm-config.yaml
cat /etc/kubernetes/kubeadm-config.yaml

kubeadm init phase upload-certs --upload-certs --config /etc/kubernetes/kubeadm-config.yaml

重新执行

./kk add nodes -f config-sample.yaml

6 kubelet 与 CNI 问题

报错现象

kk add nodes 成功完成后,master1 已加入集群,但状态为 NotReady,所有调度到 master1 的 Pod 全部 Pending

kubectl get nodes
NAME      STATUS     ROLES                         AGE     VERSION
master1   NotReady   control-plane,master,worker   3m26s   v1.22.12
master2   Ready      control-plane,master,worker   3y36d   v1.22.12
master3   Ready      control-plane,master,worker   3y36d   v1.22.12

排查方法

第一步:查看 Node Conditions

kubectl describe node master1 | grep -A5 Conditions

重点关注 ReadyKubeletReady 的 Message,常见两种情况:

  • container runtime not running → containerd 没起来
  • network not ready → CNI 插件未安装

第二步:在 master1 上检查组件状态

ssh root@172.16.198.201

# 检查 kubelet 和 containerd
systemctl status kubelet
systemctl status containerd

# 查看 kubelet 日志
journalctl -u kubelet --no-pager -n 50

修复方法

根据日志中的具体错误,通常需要:

情况 A:containerd 未启动

systemctl start containerd
systemctl enable containerd
crictl info  # 确认正常
systemctl restart kubelet

情况 B:CNI 插件缺失

# 检查 CNI 配置
ls /etc/cni/net.d/

# 如果为空,从 master2 拷贝
scp root@172.16.198.202:/etc/cni/net.d/* /etc/cni/net.d/

# 检查 CNI 二进制
ls /opt/cni/bin/

# 如果为空,从 master2 拷贝
scp -r root@172.16.198.202:/opt/cni/bin/* /opt/cni/bin/

systemctl restart kubelet

修复后验证

kubectl get nodes

7 重建local-pvc

删除master1上local的pvc,重建对应服务

8 经验总结

1. 引导节点的特殊性

K8s 集群中第一个 Master 节点(引导节点)拥有其他 Master 没有的配置文件——完整的 kubeadm-config.yaml(包含 InitConfiguration + ClusterConfiguration)。一旦引导节点丢失,这些配置也随之消失。

建议: 在所有 Master 节点上备份 /etc/kubernetes/kubeadm-config.yaml/etc/kubernetes/pki/ 目录。或者至少记住:ClusterConfiguration 可以从 kube-system/kubeadm-config ConfigMap 中恢复。

2. etcd 死成员必须先清理

etcd 不会自动移除死掉的成员。如果不手动 etcdctl member remove,新节点加入时 peer URL 会冲突,导致添加失败。

3. HAProxy 配置变更需谨慎

KubeKey 内置 HAProxy 的 HA 方案,一旦 HAProxy 配置异常会导致整个集群失联。恢复技巧:临时修改 kubeconfig 直连某个 MasterIP,绕过 HAProxy 恢复指挥权,再修复 HAProxy 配置。

4. local 存储的 Pod 需要手动清理 PVC

使用 local-path 或 local volume 的 StatefulSet Pod,在节点重装后 PVC 会卡住。需要手动删除 PVC、PV、Pod,让 StatefulSet 重建。

5. 恢复顺序很重要

备份 etcd → 清理死成员 → 删除 node → 修复 kubeadm-config → kk add nodes → 修复 CNI → 清理 PVC

每一步都有可能遇到坑,但只要 quorum 还在(2/3 存活),数据就不会丢,集群一定能恢复。

0
k8s
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区