集群版本升级
使用 kubeadm 升级 Kubernetes 集群版本的完整流程,包括控制平面升级、节点升级和 etcd 升级注意事项。
概述
集群版本升级是 CKA 考试的重点实操内容。升级需要遵循 Kubernetes 版本偏差策略,按顺序从控制平面到工作节点逐级升级,且每次只能升级一个次要版本。
1. Kubernetes 版本偏差策略
1.1 版本支持规则
kube-apiserver
|
|-- kube-controller-manager / kube-scheduler (必须 ≤ API Server 版本)
|-- kubelet (允许比 API Server 低 2 个次要版本,或高 1 个 minor 版本)
|-- kubectl (允许比 API Server ±1 个次要版本)
|-- kube-proxy (必须与 kubelet 版本一致)
1.2 升级路径示意
# Kubernetes 版本号格式:v<major>.<minor>.<patch>
# v1.29.x -> v1.30.x -> v1.31.x(不能跨次要版本升级)
# 正确升级路径
v1.29.x -> v1.30.x -> v1.31.x
# 错误升级路径(不允许)
v1.29.x -> v1.31.x
2. 升级前准备
2.1 查看当前版本和升级计划
# 查看当前集群版本
kubectl version --short
kubeadm version
kubelet --version
# 查看节点版本详情
kubectl get nodes -o wide
# 检查升级计划(关键命令)
sudo kubeadm upgrade plan
# 示例输出:
# Components that must be upgraded manually:
# kube-apiserver | 1.30.0 -> 1.31.0
# kube-controller-manager | 1.30.0 -> 1.31.0
# kube-scheduler | 1.30.0 -> 1.31.0
# kubelet | 1.30.0 -> 1.31.0 [config]
# etcd | 3.5.12-0 -> 3.5.15-0
# ...
2.2 备份与检查
# 备份 etcd
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-snapshot-$(date +%Y%m%d).db
# 备份重要配置
sudo cp -r /etc/kubernetes /etc/kubernetes-backup-$(date +%Y%m%d)
# 检查集群健康状态
kubectl get nodes
kubectl get pods --all-namespaces
kubectl get cs
# 检查 etcd 健康
kubectl exec -n kube-system etcd-<node> -- etcdctl endpoint health --cluster
# 确认所有节点都是 Ready
kubectl wait --for=condition=Ready node --all --timeout=60s
2.3 升级策略选择
# 策略一:所有节点升级
# 控制平面 -> 工作节点
# 策略二:金丝雀升级
# 先升级一个工作节点验证 -> 再升级全部
# 策略三:蓝绿部署(需要额外资源)
# 部署新版本集群,切换流量
3. 升级控制平面节点
3.1 第一个控制平面节点
# 1. 更新 kubeadm(Ubuntu/Debian)
sudo apt update
sudo apt-cache madison kubeadm # 查看可用版本
sudo apt-mark unhold kubeadm && sudo apt-get install -y kubeadm=1.31.0-1.1 && sudo apt-mark hold kubeadm
# 1. 更新 kubeadm(CentOS/RHEL)
sudo yum update -y kubeadm-1.31.0 --disableexcludes=kubernetes
# 2. 验证更新
kubeadm version
# 3. 升级前检查
sudo kubeadm upgrade plan v1.31.0
# 4. 排空当前节点
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data
# 5. 应用升级(重要!)
sudo kubeadm upgrade apply v1.31.0
# 6. 更新 kubelet 和 kubectl
sudo apt-mark unhold kubelet kubectl
sudo apt-get install -y kubelet=1.31.0-1.1 kubectl=1.31.0-1.1
sudo apt-mark hold kubelet kubectl
# 7. 重启 kubelet
sudo systemctl daemon-reload
sudo systemctl restart kubelet
# 8. 恢复节点调度
kubectl uncordon <node-name>
# 9. 验证
kubectl get nodes
kubeadm version
3.2 后续控制平面节点
# 从第二个控制平面节点开始,使用 upgrade node 而不是 upgrade apply
# 1. 更新 kubeadm
sudo apt-mark unhold kubeadm && sudo apt-get install -y kubeadm=1.31.0-1.1 && sudo apt-mark hold kubeadm
# 2. 排空节点
kubectl drain <cp-node-2> --ignore-daemonsets --delete-emptydir-data
# 3. 升级节点(区别于第一个节点的 upgrade apply)
sudo kubeadm upgrade node
# 4. 更新 kubelet 和 kubectl
sudo apt-mark unhold kubelet kubectl && sudo apt-get install -y kubelet=1.31.0-1.1 kubectl=1.31.0-1.1 && sudo apt-mark hold kubelet kubectl
# 5. 重启 kubelet
sudo systemctl daemon-reload
sudo systemctl restart kubelet
# 6. 恢复节点调度
kubectl uncordon <cp-node-2>
# 7. 验证
kubectl get nodes
4. 升级工作节点
# 在每个工作节点上执行(从控制平面节点执行 drain)
# 1. 在控制平面上排空节点
kubectl drain <worker-node> --ignore-daemonsets --delete-emptydir-data
# 2. 在工作节点上更新 kubeadm
sudo apt-mark unhold kubeadm && sudo apt-get install -y kubeadm=1.31.0-1.1 && sudo apt-mark hold kubeadm
# 3. 在工作节点上升级 kubelet 配置
sudo kubeadm upgrade node
# 4. 在工作节点上更新 kubelet 和 kubectl
sudo apt-mark unhold kubelet kubectl && sudo apt-get install -y kubelet=1.31.0-1.1 kubectl=1.31.0-1.1 && sudo apt-mark hold kubelet kubectl
# 5. 重启 kubelet
sudo systemctl daemon-reload
sudo systemctl restart kubelet
# 6. 在控制平面上恢复节点调度
kubectl uncordon <worker-node>
# 7. 在工作节点验证
kubectl version --short
kubelet --version
5. 升级验证
# 验证所有节点版本
kubectl get nodes
# NAME STATUS ROLES VERSION
# control-plane-1 Ready control-plane v1.31.0
# control-plane-2 Ready control-plane v1.31.0
# worker-1 Ready <none> v1.31.0
# worker-2 Ready <none> v1.31.0
# 验证集群功能
kubectl run nginx --image=nginx —restart=Never
kubectl get pods
kubectl delete pod nginx
# 查看组件版本
kubectl get pods -n kube-system -o yaml | grep "image:" | sort -u
# 验证系统 Pod 运行正常
kubectl get pods -n kube-system
6. etcd 升级注意事项
6.1 etcd 版本兼容性
# 查看当前 etcd 版本
kubectl exec -n kube-system etcd-<node> -- etcdctl version
kubectl get pods -n kube-system etcd-<node> -o yaml | grep image:
# etcd 升级原则:
# - etcd 可以跨多个补丁版本升级
# - 升级 etcd 前检查 Kubernetes 版本兼容性
# - etcd 3.5.x 兼容所有 Kubernetes v1.29+
6.2 etcd 升级步骤
# 如果使用 kubeadm 管理 etcd(stacked etcd):
# 升级 kubeadm 时会自动处理 etcd 升级
# 手动升级 etcd(外部 etcd 集群):
# 1. 备份 etcd 数据
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-pre-upgrade.db
# 2. 逐个升级 etcd 成员
# 停止 etcd 服务
sudo systemctl stop etcd
# 替换 etcd 二进制文件
sudo mv /usr/local/bin/etcd /usr/local/bin/etcd.old
sudo cp /tmp/etcd-v3.5.15-linux-amd64/etcd /usr/local/bin/etcd
# 启动 etcd 服务
sudo systemctl start etcd
# 3. 验证 etcd 集群健康
ETCDCTL_API=3 etcdctl endpoint health --cluster
# 4. 检查成员状态
ETCDCTL_API=3 etcdctl member list
7. 升级回滚
# 如果升级失败,回滚步骤:
# 1. 使用备份恢复 etcd
sudo kubeadm reset -f
ETCDCTL_API=3 etcdctl snapshot restore /backup/etcd-snapshot-<date>.db \
--data-dir=/var/lib/etcd-restored
# 2. 恢复 kubeadm 和 kubelet 到旧版本
sudo apt-mark unhold kubeadm kubelet
sudo apt-get install -y kubeadm=1.30.x-1.1 kubelet=1.30.x-1.1
sudo apt-mark hold kubeadm kubelet
# 3. 重新初始化 kubeadm
sudo kubeadm init --config=/etc/kubernetes/kubeadm-config.yaml --ignore-preflight-errors=all
# 4. 恢复节点
kubectl uncordon <node-name>
8. 升级流程总结
┌─────────────────────────────────────────────┐
│ 升级准备 │
│ 1. 备份 etcd、配置、检查集群健康 │
│ 2. 查看 kubeadm upgrade plan │
└─────────────────┬───────────────────────────┘
│
┌─────────────────▼───────────────────────────┐
│ 升级控制平面 │
│ 1. 第一个控制平面节点: │
│ kubeadm upgrade apply v1.31.0 │
│ 2. 后续控制平面节点: │
│ kubeadm upgrade node │
│ 3. 每个节点 drain → upgrade → uncordon │
└─────────────────┬───────────────────────────┘
│
┌─────────────────▼───────────────────────────┐
│ 升级工作节点 │
│ 1. drain 节点 │
│ 2. kubeadm upgrade node │
│ 3. 升级 kubelet & kubectl │
│ 4. 重启 kubelet │
│ 5. uncordon 节点 │
└─────────────────┬───────────────────────────┘
│
┌─────────────────▼───────────────────────────┐
│ 升级验证 │
│ 1. kubectl get nodes (版本检查) │
│ 2. 运行测试 Pod │
│ 3. 检查系统 Pod 健康 │
└─────────────────────────────────────────────┘
CKA 考试要点
kubeadm upgrade plan先看后做 -- 升级前必须先查看计划- 第一个控制平面用
upgrade apply-- 其余控制平面和工作节点用upgrade node - drain 必须加
--ignore-daemonsets-- 否则 DaemonSet Pod 会导致 drain 失败 - apt-mark unhold/hold -- 考试中可能使用 apt-mark 锁定版本,升级时需要先 unhold
- 逐个节点升级 -- 一次 drain 一个节点,升级完 uncordon 再处理下一个
- 只能升级到下一个小版本 -- 不能跨版本(如 v1.29 -> v1.31)
🧪 完整操作实例:将集群从 v1.29 升级到 v1.30
场景描述
将集群的控制平面节点和工作节点从 Kubernetes v1.29 升级到 v1.30,遵循官方升级路径逐个节点进行。
前置条件
- 集群版本为 v1.29.x
- 已备份 etcd 数据和重要配置
- 所有节点处于 Ready 状态
- 当前节点已配置 Kubernetes apt 仓库(pkgs.k8s.io)
操作步骤
Step 1: 升级前检查与备份
# 查看当前版本
kubectl version --short
# Client Version: v1.29.0
# Server Version: v1.29.0
# 检查升级计划
sudo kubeadm upgrade plan
# ...
# Components that must be upgraded manually:
# kube-apiserver | 1.29.0 -> 1.30.0
# kube-controller-manager | 1.29.0 -> 1.30.0
# ...
# 备份 etcd 和配置
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-snapshot-preupgrade.db \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
sudo cp -r /etc/kubernetes /etc/kubernetes-backup
Step 2: 升级第一个控制平面节点
# 排空控制平面节点
kubectl drain control-plane-1 --ignore-daemonsets --delete-emptydir-data
# 更新 kubeadm
sudo apt-mark unhold kubeadm
sudo apt-get update && sudo apt-get install -y kubeadm=1.30.0-1.1
sudo apt-mark hold kubeadm
# 验证新版本
kubeadm version
# kubeadm version: &version.Info{Major:"1", Minor:"30", GitVersion:"v1.30.0"}
# 应用升级
sudo kubeadm upgrade apply v1.30.0
# [upgrade/successful] SUCCESS! Your cluster was upgraded to v1.30.0. Enjoy!
# 更新 kubelet 和 kubectl
sudo apt-mark unhold kubelet kubectl
sudo apt-get install -y kubelet=1.30.0-1.1 kubectl=1.30.0-1.1
sudo apt-mark hold kubelet kubectl
# 重启 kubelet
sudo systemctl daemon-reload
sudo systemctl restart kubelet
# 恢复节点调度
kubectl uncordon control-plane-1
Step 3: 升级工作节点
# 在控制平面节点上排空工作节点
kubectl drain worker-1 --ignore-daemonsets --delete-emptydir-data
# SSH 到工作节点并升级 kubeadm
ssh worker-1
sudo apt-mark unhold kubeadm
sudo apt-get update && sudo apt-get install -y kubeadm=1.30.0-1.1
sudo apt-mark hold kubeadm
# 升级节点配置
sudo kubeadm upgrade node
# 升级 kubelet 和 kubectl
sudo apt-mark unhold kubelet kubectl
sudo apt-get install -y kubelet=1.30.0-1.1 kubectl=1.30.0-1.1
sudo apt-mark hold kubelet kubectl
sudo systemctl daemon-reload
sudo systemctl restart kubelet
exit
# 在控制平面节点上恢复工作节点调度
kubectl uncordon worker-1
# 重复相同步骤升级 worker-2、worker-3...
验证结果
# 验证所有节点版本
kubectl get nodes
# NAME STATUS ROLES VERSION
# control-plane-1 Ready control-plane v1.30.0
# worker-1 Ready <none> v1.30.0
# worker-2 Ready <none> v1.30.0
# 验证集群功能正常
kubectl get pods --all-namespaces
kubectl run test-nginx --image=nginx --restart=Never
kubectl get pod test-nginx
kubectl delete pod test-nginx
考试提示
- 升级前必须运行
kubeadm upgrade plan-- 没有查看计划直接升级会扣分 - 第一个控制平面用
kubeadm upgrade apply,其余控制平面和所有工作节点用kubeadm upgrade node - 每个节点升级必须遵守
drain -> upgrade -> uncordon的顺序 - 注意
apt-mark unhold释放版本锁定和apt-mark hold重新锁定的操作 - 只能升级到下一个小版本(v1.29 -> v1.30),不能跨版本升级(v1.29 -> v1.31)