规划节点的原地 OS 升级

集群管理员可以使用此检查清单,为 自建集群中的节点规划原地操作系统升级。在操作系统变更前后,完成 检查。

范围和支持边界

在维护窗口期间,将此检查清单与操作系统提供商支持的升级操作步骤结合使用。在升级任何节点之前,请先根据 支持矩阵确认目标操作系统和内核。该检查清单不能保证每一条操作系统升级路径都受支持。

范围和限制

仅当满足以下所有条件时,才使用此操作步骤:

  • 集群是由 管理的本地部署集群或自建集群。
  • 你可以登录到目标节点并管理节点操作系统。
  • 你具有平台管理员权限、kubectl 管理员权限,以及对每个目标节点的 SSH 或控制台访问权限。
  • 在操作系统升级之前,你可以从目标节点驱逐工作负载 Pod。

以下类型的集群不要使用此操作步骤:

  • 使用 Immutable Infrastructure 的集群。请通过使用新镜像替换节点来应用操作系统变更。
  • 由云提供商管理节点或控制平面操作系统的托管云 Kubernetes 集群。
  • 你无法登录到节点或控制平面节点的导入集群。

升级前

在对任何节点更改操作系统之前,先完成以下检查。

步骤 1:确认目标操作系统和内核

确认目标操作系统版本、内核版本、内核来源以及 CPU 架构均在受支持范围内。有关当前支持矩阵和已知限制,请参阅 受支持的 OS 和内核版本

在维护窗口之前应用以下规则:

  • 操作系统主版本和次版本必须与支持矩阵一致。
  • 核心内核版本必须与支持矩阵一致。仅允许构建后缀不同。
  • 内核必须是操作系统厂商提供的官方内核。
  • 不支持 Ubuntu HWE 内核以及第三方或自行编译的内核。
  • 如果目标版本不在支持矩阵中,请在升级前联系技术支持确认兼容性。

步骤 2:检查冲突软件包

在原地操作系统升级期间,操作系统包管理器可能会安装或覆盖容器运行时、Kubernetes 或容器网络二进制文件。升级前,请检查并解决与 组件冲突的软件包。有关软件包列表和命令,请参阅 移除冲突软件包

如果发现冲突软件包,请在卸载之前制定应用迁移方案并备份受影响的数据。

步骤 3:记录当前运行时和节点组件版本

在操作系统升级前记录版本信息。升级节点后,使用这些记录进行对比。

containerd --version
runc --version
crictl --version
kubelet --version

同时记录操作系统升级流程可能会更新的关键节点配置文件,例如 /etc/resolv.conf/etc/fstab、systemd 配置文件以及容器运行时配置文件。

步骤 4:验证集群容量并驱逐节点

确认其余节点有足够容量来运行从目标节点驱逐的 Pod。然后在操作系统升级前驱逐该节点。

你可以使用 控制台从节点驱逐 Pod。有关控制台操作,请参阅 管理节点

如果你使用 kubectl,请在运行前与运维团队确认命令选项。例如:

kubectl cordon <node-name>
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data

由 DaemonSet 管理的 Pod 不会被驱逐操作驱逐。使用本地存储的工作负载在驱逐后可能会丢失本地数据。继续之前,请先确认工作负载影响。

控制平面节点的额外检查

控制平面节点运行 kube-apiserveretcdkube-schedulerkube-controller-manager 等组件。请一次升级一个控制平面节点,并在每个节点升级后验证集群健康状态。

在升级控制平面节点之前:

  • 备份 etcd 数据。有关受支持的备份机制和恢复注意事项,请参阅 etcd 备份与恢复
  • 确认 etcd 集群处于健康状态,并且在一个控制平面节点不可用时仍可维持法定人数(quorum)。
  • 在对控制平面节点执行滚动维护时,确认集群至少有三个控制平面节点。
  • 如有可能,先在计算节点上验证该操作步骤,然后再继续处理控制平面节点。

在检查控制平面健康状态时,你可以使用以下命令作为参考:

kubectl get nodes
kubectl get pods -n kube-system | grep -E "etcd|apiserver|scheduler|controller"

如果你在控制平面节点上使用 etcdctl,请使用你环境中的证书路径:

ETCDCTL_API=3 etcdctl member list \
  --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 \
  --write-out=table

执行操作系统升级

请按照操作系统厂商针对目标版本提供的支持升级操作步骤进行操作。具体的软件包命令、仓库配置和重启要求由操作系统厂商以及你所在组织的操作系统维护策略决定。

在操作系统升级期间:

  • 不要有意安装与 组件冲突的容器运行时、Kubernetes 或容器网络软件包。
  • 除非厂商操作步骤要求更改,否则请保留节点网络配置、DNS 配置、时间同步配置以及 systemd 服务配置。
  • 当厂商操作步骤要求时,重启节点。
  • 在所有升级后检查通过之前,保持节点不可调度。

升级后

在每个节点完成操作系统升级和重启后,运行以下检查。

步骤 1:确认操作系统和内核

验证节点正在运行预期的操作系统和内核版本。

cat /etc/os-release
uname -r

将输出结果与支持矩阵及你批准的维护计划进行比较。

步骤 2:验证基础节点配置

验证操作系统升级没有还原所需的节点设置。

echo "=== Base node configuration check ==="

# SELinux must be disabled on systems that use SELinux.
getenforce 2>/dev/null || echo "SELinux command not available"

# AppArmor must be disabled on systems that use AppArmor.
systemctl status apparmor 2>/dev/null || echo "AppArmor service not installed"

# Swap must be disabled.
swapon --show
free -h | grep Swap

# Firewall services must be disabled according to your cluster network plan.
systemctl status firewalld 2>/dev/null || echo "firewalld not installed"
systemctl status ufw 2>/dev/null || echo "ufw not installed"

# /tmp must not be mounted with noexec.
mount | grep " /tmp "

# DefaultTasksMax must be infinity.
systemctl show --property=DefaultTasksMax

如果操作系统升级后启用了 swap,请根据你的操作系统策略将其禁用,并从 /etc/fstab 中移除 swap 条目。

如果操作系统升级后启用了 SELinux 或 AppArmor,请根据你的操作系统策略以及 的节点要求将其禁用。

步骤 3:验证运行时和节点组件版本

将运行时和节点组件版本与升级前记录进行比较。

containerd --version
runc --version
crictl --version
kubelet --version

然后验证 containerd 正在运行:

systemctl status containerd

如果有任何二进制文件被操作系统软件包覆盖,请停止维护,并在继续处理其他节点之前联系技术支持。

步骤 4:验证时间同步和 DNS

验证操作系统升级未更改时间同步和 DNS 配置。

date
timedatectl
cat /etc/resolv.conf

节点之间的时间偏差必须不超过 10 秒。如果偏差大于 10 秒,请先同步时间,再恢复节点上的工作负载调度。

步骤 5:重启 kubelet 并验证节点恢复

在操作系统升级完成且基础节点检查通过后,重启 kubelet

systemctl daemon-reload
systemctl restart kubelet
systemctl status kubelet

等待节点恢复到 Ready 状态。

kubectl get node <node-name> --watch

当节点恢复健康后,恢复调度。

kubectl uncordon <node-name>

你也可以从 控制台恢复调度。有关控制台操作,请参阅 管理节点

步骤 6:验证工作负载恢复

在恢复调度后,验证节点状态和工作负载放置情况。

kubectl get nodes
kubectl get pods -A -o wide | grep <node-name>

然后验证受节点驱逐影响的业务服务。只有在当前节点及相关服务都处于健康状态后,才能继续处理下一个节点。

已知高风险场景

症状可能原因检查方法建议操作
containerd 启动失败操作系统升级覆盖了 运行时二进制文件containerd --version 与升级前记录进行比较停止维护并联系技术支持
节点保持 NotReadykubelet、容器运行时、CNI、DNS 或节点网络配置发生了更改检查 systemctl status kubeletsystemctl status containerd 和节点事件恢复已更改的配置,或联系技术支持
集群组件报告 TLS 错误节点在升级期间或升级后发生了时间漂移检查 timedatectl 并在节点之间比较 date在继续之前先同步时间
DNS 解析失败/etc/resolv.conf 被覆盖检查 cat /etc/resolv.conf恢复已批准的 DNS 配置
kubelet 因安全策略错误而失败SELinux 或 AppArmor 被重新启用检查 getenforcesystemctl status apparmor根据节点要求禁用该服务
执行 uncordon 后工作负载无法调度节点仍然不健康、带有污点,或资源受限检查 kubectl describe node <node-name>在继续之前先解决节点状态问题

操作检查清单

在维护窗口期间使用此检查清单,并在升级后保留已完成记录。

阶段项目负责人状态
升级前确认目标操作系统和内核在支持矩阵中
升级前确认内核是厂商官方内核
升级前检查并解决冲突软件包
升级前记录 containerdrunccrictlkubelet 版本
升级前记录 DNS、时间同步、/etc/fstab 和运行时配置
升级前确认集群有足够容量承载已驱逐的工作负载
升级前驱逐目标节点并确认工作负载影响
仅控制平面节点备份 etcd 数据
仅控制平面节点确认 etcd 健康状态和法定人数
升级执行操作系统厂商支持的升级操作步骤
升级如厂商操作步骤要求,重启节点
升级后确认操作系统和内核版本
升级后确认 SELinux 或 AppArmor 按要求已禁用
升级后确认 swap 已禁用
升级后确认防火墙服务与集群网络规划一致
升级后确认 /tmp 未以 noexec 方式挂载
升级后确认 DefaultTasksMaxinfinity
升级后确认运行时和节点组件版本未被覆盖
升级后确认 containerdkubelet 运行正常
升级后确认节点之间的时间偏差不超过 10 秒
升级后确认 DNS 配置正确
升级后确认节点处于 Ready 状态
升级后恢复节点上的调度
升级后确认工作负载和业务服务健康