Qingular

集群版本升级

·CKAk8s练习

使用 kubeadm 升级 Kubernetes 集群版本的完整流程,包括控制平面升级、节点升级和 etcd 升级注意事项。

← 返回 CKA 练习目录

概述

集群版本升级是 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 考试要点

  1. kubeadm upgrade plan 先看后做 -- 升级前必须先查看计划
  2. 第一个控制平面用 upgrade apply -- 其余控制平面和工作节点用 upgrade node
  3. drain 必须加 --ignore-daemonsets -- 否则 DaemonSet Pod 会导致 drain 失败
  4. apt-mark unhold/hold -- 考试中可能使用 apt-mark 锁定版本,升级时需要先 unhold
  5. 逐个节点升级 -- 一次 drain 一个节点,升级完 uncordon 再处理下一个
  6. 只能升级到下一个小版本 -- 不能跨版本(如 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)

官方文档