IT策士 10余年一线大厂经验,专注 IT 思维、架构、职场进阶。我会在各个平台持续发布最新文章,助你少走弯路。
在前面 46 篇文章中,我们已经从 docker run hello-world 一路走到能用 GitOps 自动部署的 K8s 集群。部署、网络、监控这些"应用开发者"层面的技能已经掌握。但生产环境还要解决三个核心运维难题:
-
控制平面宕机,整个集群是否瘫痪?
-
etcd 数据被误删,还能恢复吗?
-
升级 Kubernetes 版本,如何做到不影响业务?
本文从 高可用、备份与恢复、版本升级 三个维度,搭建 K8s 的生产级运维底座。
一、控制平面高可用
1.1 单点故障的风险
Minikube 默认只运行单个控制平面组件实例,存在严重单点故障:
bash
kubectl get pods -n kube-system | grep -E "etcd|apiserver|scheduler|controller-manager"
输出显示每个关键组件均为 1/1,任意 Pod 失效都会导致集群不可管理或状态丢失。
1.2 生产级 HA 拓扑
生产标配:3 个控制平面节点 + Stacked etcd 拓扑。
-
etcd 集群(3 节点):采用 Raft 共识,容忍 1 个节点宕机,节点数必须为奇数。
-
API Server(3 副本 + 负载均衡):无状态,前方挂载 TCP 负载均衡器(如 HAProxy、云 LB),通过 VIP 分发流量。
-
Scheduler 和 Controller Manager(3 副本):通过 etcd Lease 进行 Leader 选举,同一时刻只有一个 Leader 工作,宕机自动切换。
最小推荐配置(3 节点 HA):
1.3 工作节点高可用
使用 Pod 反亲和性,确保同一服务的副本分散在不同节点:
bash
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: flask-counter
topologyKey: kubernetes.io/hostname
配合 HPA 自动伸缩,即使部分工作节点宕机,剩余节点上的 Pod 也能自动接管流量。
二、etcd 备份与恢复
etcd 是集群的唯一状态存储,丢失 etcd 即丢失整个集群的"认知"。
2.1 备份 etcd(快照)
在 Minikube 节点内手动备份:
bash
minikube ssh
sudo ETCDCTL_API=3 etcdctl \
--endpoints=https://127.0.0.1:2379 \
--cacert=/var/lib/minikube/certs/etcd/ca.crt \
--cert=/var/lib/minikube/certs/etcd/server.crt \
--key=/var/lib/minikube/certs/etcd/server.key \
snapshot save /var/lib/etcd-backup.db
验证快照:
bash
sudo ETCDCTL_API=3 etcdctl --write-out=table snapshot status /var/lib/etcd-backup.db
输出示例:
bash
+----------+----------+------------+------------+
| HASH | REVISION | TOTAL KEYS | TOTAL SIZE |
+----------+----------+------------+------------+
| 5c7d7b3a | 12345 | 1234 | 8.2 MB |
+----------+----------+------------+------------+
备份策略:
-
每日全量备份,保留 7~30 天。
-
备份文件严禁与 etcd 数据同盘存储,防止磁盘故障同时损毁。
-
上传至对象存储(S3 等)或异地节点。
-
建议用 CronJob 自动化备份,并定期验证可恢复性。
2.2 恢复 etcd(灾难重建)
当 etcd 数据完全损坏时:
bash
minikube ssh
# 恢复快照到新目录
sudo ETCDCTL_API=3 etcdctl snapshot restore /var/lib/etcd-backup.db \
--data-dir=/var/lib/etcd-restored \
--name=minikube \
--initial-cluster=minikube=https://127.0.0.1:2380 \
--initial-advertise-peer-urls=https://127.0.0.1:2380
# 替换损坏目录
sudo mv /var/lib/etcd /var/lib/etcd-corrupted
sudo mv /var/lib/etcd-restored /var/lib/etcd
# 重启节点
exit
minikube stop && minikube start
恢复后执行 kubectl get pods -A,若所有资源重现则恢复成功。
2.3 Velero:包含持久卷数据的完整备份
etcd 快照无法恢复 PVC 中的数据(如 Redis AOF 文件)。Velero 可备份整个命名空间,包括 PVC 和其数据。
bash
# 安装 Velero(示例使用 MinIO 作为对象存储)
velero install \
--provider aws \
--bucket velero-backups \
--secret-file ./credentials-velero \
--use-volume-snapshots=false \
--backup-location-config region=minio,s3ForcePathStyle=true,s3Url=http://minio.default:9000
创建备份:
bash
velero backup create flask-app-full \
--include-namespaces default \
--snapshot-volumes \
--storage-location default
模拟灾难恢复:
bash
kubectl delete namespace default
velero restore create --from-backup flask-app-full
稍后 Velero 会自动重建命名空间、所有 K8s 资源及 PVC 数据,弥补了纯 etcd 备份的不足。
三、Kubernetes 版本升级
K8s 每 4 个月发布一个次要版本,维护期约 14 个月,不升级将面临安全漏洞风险。
3.1 版本偏差策略
升级顺序必须为:先升级控制平面(API Server 等),再逐个升级工作节点(kubelet),否则节点可能因版本偏差过大而断开。
3.2 升级演练(Minikube)
bash
# 查看当前版本
kubectl version --short
# Client Version: v1.31.0
# Server Version: v1.31.0
# 停止旧集群并启动新版本
minikube stop
minikube start --kubernetes-version=v1.32.0
# 验证(客户端 1.31,服务器 1.32,偏差在允许范围)
kubectl version --short
3.3 生产集群升级流程
标准采用逐节点滚动升级:
bash
# 1. 升级控制平面
apt-get upgrade kubeadm=1.32.0-1.1
kubeadm upgrade plan
kubeadm upgrade apply v1.32.0
# 2. 对每个工作节点执行:
kubectl drain <节点名> --ignore-daemonsets --delete-emptydir-data
# ... 升级该节点的 kubelet 和 kube-proxy ...
kubectl uncordon <节点名>
-
kubectl drain会将 Pod 迁移到其他节点。 -
--ignore-daemonsets跳过 DaemonSet 控制的 Pod。 -
--delete-emptydir-data清除临时数据。整个过程配合监控面板可观察到短暂波动,但整体服务不中断。
四、总结
-
高可用:控制平面至少 3 节点,etcd 使用 Raft 集群,API Server 多副本 + 负载均衡,工作节点通过反亲和性分散副本。HA 是生产集群的准入门槛,而非加分项。
-
备份恢复:etcd 快照是最后防线,须 CronJob 定期备份并异地存储。Velero 提供包含 PVC 数据的完整命名空间级保护。未经验证的备份等于没有备份。
-
版本升级:严格遵循版本偏差策略,先控制平面后工作节点,逐节点 drain → 升级 → uncordon,实现滚动升级零停机。
下篇预告(第 48 篇):常见问题排查与排错指南------Pod Pending 如何分析?CrashLoopBackOff 怎么定位根因?节点 NotReady 怎么办?掌握这些排错技能,真正从"会用 K8s"跨越到"能修 K8s"。
更多内容可搜索「IT策士」,持续升级你的 IT 思维。