为节点规划原地 OS 升级

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

范围和支持边界

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

范围和限制

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

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

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

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

升级前

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

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

确认目标操作系统版本、kernel 版本、kernel 来源和 CPU 架构都在受支持范围内。有关当前支持矩阵和已知限制,请参见 Supported OS and Kernel Versions。

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

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

步骤 2:检查冲突软件包

在原地操作系统升级期间,操作系统包管理器可能会安装或覆盖 container runtime、Kubernetes 或 container network 二进制文件。升级前,请检查并解决与 组件冲突的软件包。有关软件包列表和命令,请参见 Remove Conflicting Packages。

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

步骤 3:记录当前节点基线

在操作系统升级前记录节点状态,以便升级后进行对比。

现在在节点上运行 步骤 2:验证基础节点配置 中的 Base node configuration check 块,并保留其输出。该输出会记录 SELinux 模式、AppArmor 和主机防火墙状态,以及当前使用的防火墙规则。升级后的检查会与这份输出逐项对比,因此没有这份记录的节点无法进行验证。

同时记录运行时和节点组件版本:

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

还要记录操作系统升级流程可能会更新的关键节点配置文件,例如 /etc/resolv.conf、/etc/fstab、systemd 配置文件以及 container runtime 配置文件。

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

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

你可以使用 控制台从节点驱逐 Pod。有关控制台操作,请参见 Manage Nodes。

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

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

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

控制平面节点的附加检查

控制平面节点运行诸如 kube-apiserver、etcd、kube-scheduler 和 kube-controller-manager 等组件。请一次只升级一个控制平面节点,并在每个节点升级后验证集群健康状态。

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

  • 备份 etcd 数据。有关受支持的备份机制和恢复注意事项,请参见 etcd Backup and Restore。
  • 确认 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

执行操作系统升级

请遵循操作系统供应商针对目标版本提供的支持升级操作步骤。具体的软件包命令、仓库配置以及重启要求,取决于操作系统供应商和你所在组织的操作系统维护策略。

在操作系统升级期间:

  • 不要有意安装与 组件冲突的 container runtime、Kubernetes 或 container network 软件包。
  • 除非供应商的操作步骤要求变更,否则请保留节点网络配置、DNS 配置、时间同步配置和 systemd 服务配置。
  • 如果供应商的操作步骤要求重启节点,则请重启节点。
  • 在所有升级后检查通过之前,保持节点不可调度。

升级后

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

步骤 1:确认操作系统和 kernel

验证节点运行的是预期的操作系统和 kernel 版本。

cat /etc/os-release
uname -r

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

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

验证操作系统升级未回退所需的节点设置。

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

# SELinux must be disabled. Record the value so that you can confirm the
# operating system upgrade did not turn it back on.
if command -v getenforce >/dev/null; then
  echo "SELinux: $(getenforce)"
else
  echo "SELinux: getenforce not available on this system"
fi

# AppArmor must be disabled. A missing unit means the system has no AppArmor at
# all, which is not the same as AppArmor being present but turned off.
if systemctl list-unit-files --no-legend apparmor.service 2>/dev/null | grep -q .; then
  echo "AppArmor: enabled=$(systemctl is-enabled apparmor.service 2>&1) active=$(systemctl is-active apparmor.service 2>&1)"
else
  echo "AppArmor: unit not present on this system"
fi

# firewalld. Same distinction as AppArmor.
if systemctl list-unit-files --no-legend firewalld.service 2>/dev/null | grep -q .; then
  echo "firewalld: enabled=$(systemctl is-enabled firewalld.service 2>&1) active=$(systemctl is-active firewalld.service 2>&1)"
  firewall-cmd --list-all 2>/dev/null || true
else
  echo "firewalld: unit not present on this system"
fi

# ufw. The unit reports active (exited) once it has ever run, so the unit state
# does not show whether the ruleset is enabled. Only ufw status does.
if command -v ufw >/dev/null; then
  ufw status verbose
else
  echo "ufw: not installed"
fi

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

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

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

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

必须禁用 SELinux 和 AppArmor。如果操作系统升级重新启用了它们中的任意一个,请根据你的操作系统策略再次禁用。请参见 Why SELinux and AppArmor Must Be Disabled。

主机防火墙必须恢复到集群安装时的状态。如果集群安装时禁用了主机防火墙,而操作系统升级后重新启用了它,请再次将其禁用。如果集群运行时启用了主机防火墙,请确认升级后它仍然处于启用状态,并且其规则完整。有关所需配置和端口列表,请参见 Hardened Node Security Configuration 和 Communication Matrix。

步骤 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>

你也可以通过 控制台恢复调度。有关控制台操作,请参见 Manage Nodes。

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

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

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

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

已知高风险场景

症状可能原因如何检查推荐操作
containerd 启动失败操作系统升级覆盖了 运行时二进制文件将 containerd --version 与升级前记录进行对比停止维护并联系技术支持
节点一直处于 NotReadykubelet、container runtime、CNI、DNS 或节点网络配置发生了变更检查 systemctl status kubelet、systemctl status containerd 和节点事件恢复已更改的配置,或联系技术支持
集群组件报告 TLS 错误升级期间或升级后节点时间发生漂移检查 timedatectl 并对比各节点的 date在继续之前同步时间
DNS 解析失败/etc/resolv.conf 被覆盖检查 cat /etc/resolv.conf恢复已批准的 DNS 配置
kubelet 因安全策略错误而失败操作系统升级重新启用了 SELinux 或 AppArmor运行 Base node configuration check 块并与升级前记录对比根据你的操作系统策略再次禁用该机制,然后在操作系统要求时重启节点。如果错误持续存在,请联系技术支持
在 uncordon 后无法调度工作负载节点仍不健康、带有污点或资源受限检查 kubectl describe node <node-name>在继续之前先解决节点状况

操作检查清单

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

阶段项目负责人状态
升级前确认目标操作系统和 kernel 在支持矩阵中
升级前确认 kernel 是供应商提供的官方 kernel
升级前检查并解决冲突软件包
升级前记录 containerd、runc、crictl 和 kubelet 版本
升级前记录 DNS、时间同步、/etc/fstab 和运行时配置
升级前记录 SELinux、AppArmor 和主机防火墙是否启用,并记录正在使用的防火墙规则
升级前确认集群有足够容量承载已驱逐的工作负载
升级前驱逐目标节点并确认工作负载影响
仅控制平面备份 etcd 数据
仅控制平面确认 etcd 健康状态和 quorum
升级运行操作系统供应商支持的升级操作步骤
升级如果供应商操作步骤要求,则重启节点
升级后确认操作系统和 kernel 版本
升级后确认 SELinux 和 AppArmor 已禁用
升级后确认 swap 已禁用
升级后确认主机防火墙与集群安装配置一致
升级后确认 /tmp 未以 noexec 方式挂载
升级后确认 DefaultTasksMax 为 infinity
升级后确认运行时和节点组件未被覆盖
升级后确认 containerd 和 kubelet 运行正常
升级后确认节点之间的时间偏差不超过 10 秒
升级后确认 DNS 配置正确
升级后确认节点处于 Ready 状态
升级后恢复节点调度
升级后确认工作负载和业务服务健康