Kubernetes 备份与恢复(etcd)
etcd 3.6 将备份与恢复功能拆分:
etcdctl负责在线备份,etcdutl负责恢复。
一、准备 etcdctl 和 etcdutl 二进制
从 etcd 镜像中提取:
# 创建临时容器
docker create --name demo reg.westos.org/k8s/etcd:3.6.6-0
# 从容器拷贝二进制到本机
docker cp demo:/usr/local/bin/etcdctl /usr/local/bin
docker cp demo:/usr/local/bin/etcdutl /usr/local/bin
# 拷贝到 master 节点
scp /usr/local/bin/etcdctl k8s-master:/usr/local/bin/
scp /usr/local/bin/etcdutl k8s-master:/usr/local/bin/
二、备份 etcd
在 master 节点执行:
mkdir -p /backup/etcd
ETCDCTL_API=3 etcdctl \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/apiserver-etcd-client.crt \
--key=/etc/kubernetes/pki/apiserver-etcd-client.key \
--endpoints https://127.0.0.1:2379 \
snapshot save /backup/etcd/etcd-$(date +%Y-%m-%d-%H-%M-%S).bak
三、查看快照状态
ETCDCTL_API=3 etcdutl snapshot status --write-out=table \
/backup/etcd/etcd-2026-09-27-11-26-04.bak

四、模拟故障(删除资源)
kubectl delete deployments.apps nginx-server
五、恢复 etcd
1. 停止所有核心组件
cd /etc/kubernetes/manifests/
mv * /mnt/ # 移走静态 Pod 清单,对应容器自动停止
2. 备份原数据目录
mv /var/lib/etcd /mnt/
3. 从快照恢复
ETCDCTL_API=3 etcdutl snapshot restore \
--data-dir /var/lib/etcd \
/backup/etcd/etcd-2026-09-27-11-26-04.bak
4. 重启所有组件
mv /mnt/*.yaml /etc/kubernetes/manifests/ # 移回清单,容器自动启动
六、验证恢复
kubectl get deployments.apps nginx-server
# NAME READY UP-TO-DATE AVAILABLE AGE
# nginx-server 3/3 3 3 4h53m
kubectl get pod -l app=nginx
# 三个 Pod 均 Running,说明资源已恢复
Kubernetes 集群升级
本实验:Kubernetes v1.35.8 → v1.36.5
升级方式:
kubeadm
官方文档:
版本偏差策略:
修改各节点的 Kubernetes 安装源
# vim /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.36/rpm/
enabled=1
gpgcheck=0
# yum makecache fast
升级 Kubernetes Master 节点
升级 kubeadm
# yum install -y kubeadm
# kubeadm version
确认版本为:
v1.36.5
提前下载 K8s 升级镜像
# kubeadm config images pull --image-repository registry.aliyuncs.com/google_containers
查看 v1.36.5 所需镜像:
# kubeadm config images list --kubernetes-version v1.36.5
然后根据实验环境,将镜像上传到 Harbor:
reg.westos.org
修改 containerd 配置
# vim /etc/containerd/config.toml
修改:
sandbox_image = "reg.westos.org/k8s/pause:3.10.2"
重启:
# systemctl restart containerd.service
验证升级计划
# kubeadm upgrade plan
执行升级
# kubeadm upgrade apply v1.36.5
等待升级完成。
升级 kubelet 和 kubectl
# yum install -y kubelet kubectl
重启 kubelet:
# systemctl daemon-reload
# systemctl restart kubelet
解除节点保护
# kubectl uncordon k8s1
验证
# kubectl get node
例如:
NAME STATUS ROLES VERSION
k8s1 Ready control-plane v1.36.5
k8s2 Ready worker v1.35.8
k8s3 Ready worker v1.35.8
升级工作节点
工作节点需要逐个升级。
修改 containerd
# vim /etc/containerd/config.toml
sandbox_image = "reg.westos.org/k8s/pause:3.10.1"
# systemctl restart containerd.service
升级 kubeadm
# yum install -y kubeadm
# kubeadm version
确认:
v1.36.5
执行升级
# kubeadm upgrade node
腾空节点
在 Master 节点执行:
# kubectl drain k8s2 --ignore-daemonsets
如果提示 emptyDir:
# kubectl drain k8s2 --ignore-daemonsets --delete-emptydir-data
升级 kubelet 和 kubectl
在 k8s2 上:
# yum install -y kubelet kubectl
重启:
# systemctl daemon-reload
# systemctl restart kubelet
解除节点保护
在 Master 节点执行:
# kubectl uncordon k8s2
其他工作节点
k8s3 按照相同步骤操作:
# kubectl drain k8s3 --ignore-daemonsets
在 k8s3:
# yum install -y kubeadm
# kubeadm upgrade node
# yum install -y kubelet kubectl
# systemctl daemon-reload
# systemctl restart kubelet
回到 Master:
# kubectl uncordon k8s3
最后验证集群
# kubectl get node
最终:
NAME STATUS ROLES VERSION
k8s1 Ready control-plane v1.36.5
k8s2 Ready worker v1.36.5
k8s3 Ready worker v1.36.5
再检查 Pod:
# kubectl get pod -A
确保没有:
Pending
CrashLoopBackOff
ImagePullBackOff
ErrImagePull