2. Kubernetes 集群升级流程:节点升级策略、镜像预拉取、数据面与控制面升级顺序
Kubernetes 集群升级是一项高风险运维操作,尤其在涉及大规模生产环境时,镜像拉取效率与 CNI 网络稳定性直接影响升级窗口与业务连续性。本章聚焦升级流程中的节点策略、镜像预拉取机制以及控制面与数据面的升级顺序,为后续 CNI 网络优化提供操作上下文。
2.1 控制面与数据面升级顺序
Kubernetes 官方推荐的升级顺序为:先升级控制面(Control Plane),再升级数据面(Worker Nodes)。控制面组件(kube-apiserver、kube-controller-manager、kube-scheduler、etcd)的版本决定了集群 API 的兼容性边界,数据面节点上的 kubelet 与 kube-proxy 版本必须 ≤ 控制面版本。
| 升级阶段 | 组件 | 版本约束 | 镜像拉取影响 |
|---|---|---|---|
| 控制面升级 | kube-apiserver, etcd, kube-controller-manager, kube-scheduler | 先升级至目标版本 | API Server 重启期间镜像拉取请求中断,需 CNI 保持连接重试 |
| 数据面升级 | kubelet, kube-proxy, 容器运行时 | ≤ 控制面版本 | 节点排空后镜像缓存清空,预拉取策略决定拉取延迟 |
| CNI 插件升级 | calico-node, cni-plugins, 网络策略控制器 | 与控制面版本兼容 | CNI DaemonSet 滚动更新期间 Pod 网络中断,影响镜像仓库可达性 |
版本偏差策略:kubelet 版本可以比 kube-apiserver 低最多两个次要版本(例如 1.28 控制面可管理 1.26 和 1.27 的 kubelet)。升级数据面时,建议逐节点升级,避免跨度过大导致 CNI 网络策略不兼容。
2.2 节点升级策略:滚动、蓝绿与原地升级
节点升级策略直接影响镜像拉取的并发量与网络带宽消耗。三种主流策略对比如下:
| 策略 | 操作方式 | 镜像拉取特点 | CNI 网络影响 | 适用场景 |
|---|---|---|---|---|
| 滚动升级 | 逐节点排空 → 升级 → 恢复调度 | 每节点独立拉取,镜像仓库压力平稳 | 单节点网络中断,CNI 需快速重建路由 | 中小规模集群(≤100 节点) |
| 蓝绿升级 | 创建新节点池 → 迁移负载 → 销毁旧池 | 新池节点同时拉取,瞬时带宽峰值高 | 双网络平面共存,CNI 需处理跨池通信 | 大规模集群或合规要求高的环境 |
| 原地升级 | 节点 OS 或 kubelet 原地替换,不重建节点 | 镜像缓存可能保留,拉取量最小 | CNI 插件需热更新,网络中断时间最短 | 虚拟化节点或不可变基础设施 |
2.3 镜像预拉取策略与实现
镜像预拉取(Image Pre-pulling)是减少节点升级期间 Pod 启动延迟的关键手段。在节点排空或重启前,提前将目标工作负载的镜像拉取到节点本地缓存,避免升级后因镜像拉取慢导致 Pod 长时间处于 ContainerCreating 状态。
2.3.1 预拉取触发时机
- 节点排空前预拉取:在
kubectl drain之前,通过 DaemonSet 或 init 容器将镜像拉取到节点。 - 节点重启后预拉取:节点启动后、kubelet 恢复调度前,由启动脚本或 systemd 单元执行预拉取。
- 集群级预拉取:通过自定义控制器或 CI/CD 流水线,在升级窗口前批量向所有目标节点分发镜像。
2.3.2 预拉取工具与实现方式
| 工具/方式 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| DaemonSet + init 容器 | 通过 DaemonSet 在每个节点运行预拉取容器,镜像列表挂载为 ConfigMap | 原生 Kubernetes 资源,无需额外组件 | DaemonSet 滚动更新可能影响预拉取并发 |
| kubelet 镜像垃圾回收(ImageGC) | 调整 --image-gc-high-threshold 保留更多缓存镜像 |
零额外运维,kubelet 原生能力 | 无法精确控制预拉取列表,依赖 LRU 策略 |
| 外部工具(kraken、dragonfly) | P2P 镜像分发,节点间共享镜像层 | 大规模集群拉取效率高,减少仓库压力 | 需要额外部署和 CNI 网络适配 |
| 节点启动脚本 | 在 cloud-init 或 ignition 中嵌入 crictl pull 命令 |
适合不可变基础设施,启动即缓存 | 镜像列表变更需更新节点模板 |
# 示例:使用 DaemonSet 进行镜像预拉取(关键片段)
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: image-prepuller
namespace: kube-system
spec:
selector:
matchLabels:
app: image-prepuller
template:
metadata:
labels:
app: image-prepuller
spec:
initContainers:
- name: prepull
image: alpine:3.18
command:
- sh
- -c
- |
for img in $(cat /etc/prepull-images.txt); do
ctr image pull $img || true
done
volumeMounts:
- name: prepull-config
mountPath: /etc/prepull-images.txt
subPath: images.txt
containers:
- name: pause
image: gcr.io/google_containers/pause:3.9
volumes:
- name: prepull-config
configMap:
name: prepull-images
预拉取避坑:预拉取 DaemonSet 本身会占用节点资源,建议设置
resources.requests 和 resources.limits,并在预拉取完成后通过 postStart 或 lifecycle 钩子清理临时容器。同时注意镜像仓库的认证配置,避免预拉取因认证失败而无效。
2.4 升级流程中的 CNI 网络优化切入点
在控制面与数据面升级的各个阶段,CNI 网络优化可以显著提升镜像拉取效率与集群稳定性。以下为关键优化点:
- 控制面升级期间:确保 CNI 控制平面(如 calico-kube-controllers)与 API Server 版本兼容,避免网络策略同步中断导致镜像仓库 DNS 解析失败。
- 节点排空阶段:CNI 需快速清理 Pod 网络命名空间,释放 IP 地址池,避免因 IP 耗尽导致新 Pod 无法启动。
- 镜像预拉取阶段:CNI 网络策略需允许预拉取 DaemonSet 访问外部镜像仓库,同时避免预拉取流量被误限速。
- 节点恢复调度阶段:CNI 需快速重建节点路由与 ARP 表项,减少 Pod 启动后网络不可用时间。
- 跨节点镜像分发:利用 CNI 的 Pod 网络直连能力,部署 P2P 镜像分发工具(如 Dragonfly),将镜像拉取流量从集中式仓库分散到节点间。
2.5 升级流程清单与检查点
以下为生产环境集群升级的标准操作清单,每个步骤均标注镜像拉取与 CNI 网络相关的检查点:
| 步骤 | 操作内容 | 镜像拉取检查点 | CNI 网络检查点 |
|---|---|---|---|
| 1 | 备份 etcd 与控制面组件配置 | 确认镜像仓库可达性 | 记录当前 CNI 配置与网络策略 |
| 2 | 升级控制面组件(kube-apiserver 优先) | API Server 镜像拉取成功 | CNI 控制器版本兼容性验证 |
| 3 | 升级 CNI 插件(如 calico) | CNI DaemonSet 镜像拉取 | Pod 网络连通性测试 |
| 4 | 节点排空前执行镜像预拉取 | 预拉取成功率 ≥ 95% | 预拉取流量未被网络策略阻断 |
| 5 | 逐节点排空并升级 kubelet/kube-proxy | 节点重启后镜像缓存保留情况 | 节点路由重建延迟 |
| 6 | 节点恢复调度,验证 Pod 启动时间 | Pod 启动时间 ≤ 基线值 + 20% | Pod 网络就绪时间 ≤ 5s |
| 7 | 全集群功能回归测试 | 镜像拉取总耗时对比 | 网络策略与 Service 连通性 |
关键指标:升级过程中,镜像拉取成功率应 ≥ 98%,Pod 启动时间中位数不应超过升级前的 1.5 倍。若预拉取后 Pod 仍出现
ErrImagePull,需优先排查 CNI 网络策略是否限制了镜像仓库的出口流量。