跳到主要内容

K8s 集群升级实战

问题

Kubernetes 集群需要从 1.28 升级到 1.29,如何安全地执行升级?

答案

升级原则

K8s 版本兼容规则
  • 只能逐个小版本升级:1.28 → 1.29 → 1.30,不能跳版本
  • 先升 Control Plane,再升 Worker Node
  • kubelet 不能比 API Server 新,可以旧最多 2 个小版本

升级流程

Step 1:准备工作

# 1. 查看当前版本
kubectl version --short
kubectl get nodes -o wide

# 2. 阅读变更日志,关注:
# - Deprecated API(旧版 API 会被移除)
# - 破坏性变更

# 3. 检查应用使用的 API 版本
kubectl api-versions
# 使用 pluto 检查已废弃 API
# pluto detect-all-in-cluster

# 4. 备份 etcd(最重要!)
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-$(date +%Y%m%d).db \
--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

# 验证备份
ETCDCTL_API=3 etcdctl snapshot status /backup/etcd-$(date +%Y%m%d).db --write-out=table

Step 2:升级 Control Plane(kubeadm 方式)

# 在第一个 Master 节点上操作

# 1. 升级 kubeadm
apt-get update && apt-get install -y kubeadm=1.29.0-00
# 或 yum install -y kubeadm-1.29.0

# 2. 查看升级计划
kubeadm upgrade plan

# 3. 执行升级
kubeadm upgrade apply v1.29.0

# 4. 升级 kubelet 和 kubectl
apt-get install -y kubelet=1.29.0-00 kubectl=1.29.0-00
systemctl daemon-reload
systemctl restart kubelet

# 其他 Master 节点:
kubeadm upgrade node
# + 升级 kubelet

Step 3:升级 Worker Node(逐台滚动)

# 对每个 Worker 节点执行以下流程:

NODE="worker-01"

# 1. 驱逐 Pod(将 Pod 调度到其他节点)
kubectl drain $NODE --ignore-daemonsets --delete-emptydir-data

# 2. SSH 到节点,升级组件
ssh $NODE
apt-get update && apt-get install -y kubeadm=1.29.0-00
kubeadm upgrade node
apt-get install -y kubelet=1.29.0-00
systemctl daemon-reload
systemctl restart kubelet
exit

# 3. 恢复调度
kubectl uncordon $NODE

# 4. 确认节点就绪
kubectl get node $NODE
# STATUS: Ready, VERSION: v1.29.0

# 5. 等待该节点 Pod 恢复后再升级下一台
PDB(Pod Disruption Budget)

drain 时 K8s 会尊重 PDB 配置。如果存在 PDB 且剩余可用 Pod 数不足,drain 会阻塞。确保应用 replicas 足够或临时调整 PDB。

Step 4:验证

# 1. 所有节点版本一致
kubectl get nodes

# 2. 核心组件正常
kubectl get pods -n kube-system

# 3. 核心功能测试
# - 创建 Deployment 能正常调度
# - Service 网络正常
# - Ingress 正常
# - PVC 创建绑定正常
# - DNS 解析正常
kubectl run test --image=busybox --rm -it -- nslookup kubernetes

常见面试问题

Q1: K8s 升级失败如何回滚?

答案

  1. Control Plane 回滚

    • 如果 kubeadm upgrade apply 失败,kubeadm 会自动回滚
    • 极端情况下从 etcd 备份恢复
  2. Worker Node 回滚

    • 降级 kubelet 和 kubeadm 包版本
    • systemctl restart kubelet
  3. 最坏情况

    # 从 etcd 备份恢复整个集群
    ETCDCTL_API=3 etcdctl snapshot restore /backup/etcd-backup.db \
    --data-dir=/var/lib/etcd-restore
  4. 预防:先在测试集群升级验证,再操作生产环境

相关链接