前言

前面几周我们把业务迁移、监控、日志全部搭完,集群已经能正常跑、能看指标、能查日志。但说实话:能跑不代表稳,能看不代表扛故障

做过生产运维都懂,K8s 最大的隐患永远不是业务 Pod,而是集群本身。尤其是 ETCD,一旦崩掉、数据损坏、误删数据,整个集群直接瘫痪,所有资源全部失效。

这周我直接带大家落地生产真正能用的高可用、备份、故障恢复、节点替换全套流程。所有内容都是我线上真实踩坑沉淀下来的,没有空话,每一套操作、每一个报错、每一个修复命令,都是生产实战打磨出来的。

一、为什么生产 K8s 必须做 ETCD 备份?

干运维三年最深刻的体会:平时从不备份,出事连夜跑路。

K8s 所有集群数据全部存在 ETCD:Pod、Deployment、Service、Ingress、PVC、权限、状态、配置、调度记录,全部在 ETCD 里。

ETCD 一旦损坏:

  • kube-apiserver 直接起不来
  • kubectl 全部命令超时
  • 所有业务虽然还在跑,但无法变更、无法发布、无法扩容
  • 节点慢慢失联,集群彻底瘫痪

很多新人踩坑:觉得集群好好的不用备份,等误删 ns、etcd 崩了、磁盘坏道,直接傻眼。

生产标准底线:每日自动备份 + 备份有效性校验 + 定期恢复演练

二、环境说明

  • 标准 kubeadm 三 master 高可用集群
  • ETCD 静态 pod 运行
  • 所有节点已时间同步
  • 集群业务正常运行中

三、ETCD 手动快照备份(生产标准操作)

日常做变更、升级、改核心配置前,必须手动快照一次

1. 先确认 ETCD 集群健康状态

ETCDCTL_API=3 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

全部返回 healthy 再继续操作,有异常坚决不做变更。

2. 创建备份目录

我生产统一放在 /data/etcd-backup,统一管理

mkdir -p /data/etcd-backup

3. 手动快照备份命令(生产通用)

ETCDCTL_API=3 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 \
snapshot save /data/etcd-backup/etcd-$(date +%Y%m%d-%H%M).db

4. 校验备份是否有效(很多人漏这一步)

备份文件生成不代表能用,磁盘满、中断、IO 异常都会导致备份损坏。

校验命令:

ETCDCTL_API=3 etcdctl snapshot status /data/etcd-backup/你的备份文件.db

能输出 hash、revision、keys 数量,才算真正备份成功。

四、企业级自动定时备份脚本(带自动清理 + 校验)

手动备份不靠谱,人会忘,生产必须脚本定时跑。

1. 编写 etcd-backup.sh

#!/bin/bash
BAK_DIR="/data/etcd-backup"
DATE=$(date +%Y%m%d-%H%M%S)
mkdir -p $BAK_DIR

# 执行快照备份
ETCDCTL_API=3 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 \
snapshot save $BAK_DIR/etcd-$DATE.db

# 校验备份有效性
ETCDCTL_API=3 etcdctl snapshot status $BAK_DIR/etcd-$DATE.db
if [ $? -eq 0 ];then
    echo "[$DATE] 备份成功" >> $BAK_DIR/success.log
else
    echo "[$DATE] 备份失败" >> $BAK_DIR/error.log
fi

# 自动清理7天前旧备份
find $BAK_DIR -name "etcd-*.db" -mtime +7 -delete

2. 授权并测试

chmod +x /data/etcd-backup/etcd-backup.sh
bash /data/etcd-backup/etcd-backup.sh

3. 配置定时任务

每天凌晨 2 点自动备份

crontab -e

写入:

0 2 * * * /data/etcd-backup/etcd-backup.sh >> /data/etcd-backup/run.log 2>&1

五、ETCD 故障完整恢复流程(集群瘫痪救命操作)

我线上遇到过好几次:误删集群资源、etcd 数据损坏、节点异常导致集群无法读写。

恢复核心经验(三年运维总结)

  1. 三台 master 必须全部停止 kubelet,不能只恢复一台
  2. 三台 master 全部清空旧 etcd 数据目录
  3. 三台必须用同一份快照文件恢复
  4. 恢复完必须修正权限,不然 apiserver 起不来

1. 所有 Master 停止 kubelet

systemctl stop kubelet

2. 所有 Master 备份损坏的旧数据目录

千万不要直接删,防止恢复失败需要回退

mv /var/lib/etcd /var/lib/etcd-bak-err

3. 在任意一台 Master 执行快照恢复

ETCDCTL_API=3 etcdctl \
snapshot restore /data/etcd-backup/有效备份.db \
--data-dir=/var/lib/etcd

4. 关键步骤:修复目录权限(90% 的人恢复失败都是因为这步)

etcd 运行用户是 etcd,root 恢复后的目录权限不对,直接起不来

chown -R etcd:etcd /var/lib/etcd
chmod 700 /var/lib/etcd

5. 所有 Master 启动 kubelet

systemctl start kubelet

6. 集群恢复校验

等待 2~3 分钟集群自愈

kubectl get nodes
kubectl get all -A

资源全部恢复、节点全部 Ready 即为恢复成功。

六、生产节点故障替换实战

线上机器硬件损坏、磁盘坏道、内核崩掉是常态,必须熟练替换节点。

1. Worker 节点故障下线

先驱逐业务,再删节点,绝对不能直接删机器

# 驱逐节点业务
kubectl drain k8s-worker01 --ignore-daemonsets --delete-emptydir-data

# 删除故障节点
kubectl delete node k8s-worker01

新节点重装系统后,重新获取 join 命令加入集群:

kubeadm token create --print-join-command

2. Master 节点故障替换(高可用核心)

master 故障不能直接删,要先清理 etcd 成员,不然集群一直异常

# 查看异常成员
ETCDCTL_API=3 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

# 删除故障节点ID
ETCDCTL_API=3 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

# 删除故障节点
kubectl delete node k8s-master03

新 master 加入高可用集群:

kubeadm join 集群IP:6443 \
--token=xxxx \
--discovery-token-ca-cert-hash sha256:xxxx \
--control-plane

七、生产真实踩坑 + 超详细解决方法

坑 1:只备份不校验,出事发现备份全部损坏

现象平时定时备份看着日志正常,集群崩了准备恢复,发现备份文件为空、损坏、无法识别。

真实原因服务器磁盘满、IO 卡顿、备份过程中断,脚本退出但没有报错提示,肉眼看不出异常。

详细解决方法必须在备份脚本里加入自动校验,我现在所有生产脚本都带校验:

ETCDCTL_API=3 etcdctl snapshot status $BAK_DIR/etcd-$DATE.db
if [ $? -eq 0 ];then
    echo "[$DATE] 备份成功" >> $BAK_DIR/success.log
else
    echo "[$DATE] 备份失败" >> $BAK_DIR/error.log
fi

每天看一眼 error.log,有问题立刻处理。


坑 2:ETCD 恢复后 kube-apiserver 一直 CrashLoopBackOff

现象etcd 恢复看着没问题,但是 apiserver 起不来,集群完全不可用。

真实原因用 root 账号恢复快照,生成的 /var/lib/etcd 目录属主是 root,etcd 进程没有读写权限,直接卡死。

详细解决方法所有 master 节点统一执行权限修复:

chown -R etcd:etcd /var/lib/etcd
chmod 700 /var/lib/etcd
systemctl restart kubelet

执行完等待 1~2 分钟集群自动恢复。


坑 3:只恢复单台 master,导致集群脑裂、数据分裂

现象恢复完一台 master,另外两台旧数据还在,集群状态混乱,一会正常一会异常。

真实原因ETCD 集群三节点数据不一致,新旧数据共存,直接脑裂。

详细解决方法生产恢复硬性规范:

  1. 三台 master 全部停止 kubelet
  2. 三台全部移动旧数据目录
  3. 三台全部用同一份快照恢复
  4. 三台统一修复权限
  5. 三台同时启动 kubelet

严格按我上面的完整恢复流程操作,不会出问题。


坑 4:备份目录日积月累,磁盘爆满

现象没人管备份目录,几十天备份堆积,磁盘 100%,导致节点卡死。

详细解决方法脚本强制自动清理 7 天前备份,无需人工干预:

find /data/etcd-backup -name "etcd-*.db" -mtime +7 -delete

坑 5:节点时间不同步,ETCD 集群不健康

现象节点时间差几秒,etcd 集群间歇性 unhealthy,集群不稳定。

详细解决方法所有节点统一部署时间同步:

yum install chrony -y
systemctl enable --now chronyd
chronyc tracking

确保所有节点时间一致,这是集群稳定的基础。

八、生产运维规范(面试超级加分)

  1. 生产 K8s 禁止单 master,必须三 master 高可用
  2. 所有核心变更前,手动快照备份
  3. 每天自动备份 + 自动校验 + 自动清理
  4. 每季度必须做一次灾备恢复演练,保证备份可用
  5. 故障节点先驱逐、再删除,绝不直接删节点
  6. 严禁手动修改、删除 /var/lib/etcd 目录

九、本周总结

这周内容属于运维保命级技能。平时开发、部署业务谁都会,但真正拉开运维差距的,就是故障处理、灾备恢复、集群维稳

学完这周你彻底掌握:

  • ETCD 手动 + 自动企业级备份
  • 集群瘫痪完整恢复流程
  • Master、Worker 节点故障替换
  • 生产高频坑点全套解决方案

现在你的 K8s 集群,不仅能跑业务,还能扛故障、可恢复、可灾备,完全达到企业生产标准。

下周预告

第 8 周:K8s 网络深度实战,Service 负载均衡、NodePort、Ingress 七层路由、NetworkPolicy 隔离、Cilium eBPF 网络优化,吃透 K8s 最难点网络体系。

更多推荐