3. 集群升级基础:Kubernetes版本升级策略与CRI层影响

Kubernetes 集群升级是 SRE 日常工作中风险最高的操作之一。不同的升级策略在业务连续性、资源消耗和CRI 层影响上存在显著差异。本节将系统梳理三种主流升级策略的核心原理,并重点分析它们对容器运行时接口(CRI)产生的具体影响。

3.1 三种升级策略对比

策略 核心原理 业务中断 资源开销 回滚速度 CRI 影响范围
原地升级 直接替换节点上的 kubelet、kube-proxy 等组件二进制文件 短时(秒级) 低(无需额外节点) 快(二进制回退) 节点级(CRI 需重启)
蓝绿部署 构建全新版本集群,流量一次性切换 几乎为零 高(双倍集群资源) 极快(流量切回) 集群级(CRI 全量迁移)
滚动升级 逐节点或逐批节点升级,保持集群容量 可控(逐节点排空) 中(需少量缓冲节点) 慢(逐节点回滚) 节点级(分批影响 CRI)
选型建议:生产环境优先选择滚动升级,兼顾安全性与资源效率;蓝绿部署适用于对停机零容忍的核心业务;原地升级仅推荐用于测试环境或紧急热修复场景。

3.2 原地升级(In-Place Upgrade)

原地升级直接操作节点操作系统层,替换 Kubernetes 组件二进制文件并重启相关服务。其流程可概括为:

  1. 节点封锁:kubectl cordon <node> 标记节点为不可调度。
  2. Pod 排空:kubectl drain <node> --ignore-daemonsets 驱逐已有 Pod。
  3. 组件替换:停止 kubelet 服务,替换 kubelet/kube-proxy 二进制,更新配置。
  4. CRI 重启:重启容器运行时(如 containerd 或 CRI-O),加载新版本接口。
  5. 节点恢复:启动 kubelet,kubectl uncordon <node> 恢复调度。
CRI 层风险:原地升级时,CRI 守护进程(containerd/cri-o)必须重启以加载新版本 gRPC 接口。若新 kubelet 与旧 CRI 版本不兼容,将导致 Pod 创建失败或 Sandbox 无法初始化。建议升级前确认 kubelet --version 与 crictl version 的兼容性矩阵。

3.3 蓝绿部署(Blue-Green Deployment)

蓝绿部署维护两套独立集群:蓝色(当前生产)和绿色(新版本)。升级时并行运行,验证通过后切换流量。

蓝绿部署架构与 CRI 迁移路径 蓝色集群(当前生产) kubelet v1.27 + containerd v1.6 CRI gRPC 接口 v1alpha2 Pod 运行中(业务流量) 绿色集群(新版本) kubelet v1.28 + containerd v1.7 CRI gRPC 接口 v2 Pod 待命(无流量) 流量切换 CRI 影响:所有节点同时升级容器运行时,需确保新旧 CRI 版本与 kubelet 双向兼容
CRI 层关键考量:蓝绿部署中,CRI 升级是全量一次性完成的。这意味着:
  • 必须提前验证新版本 CRI 的 gRPC 接口变更(如 v1alpha2 → v2)。
  • 容器镜像缓存需要预热,避免切换后镜像拉取风暴。
  • CNI 插件版本需与 CRI 新版本兼容,否则 Pod 网络初始化失败。

3.4 滚动升级(Rolling Upgrade)

滚动升级是生产环境最常用的策略,通过逐节点或逐批次升级,始终保持集群容量冗余。其核心流程如下:

  1. 设置最大不可用节点数:maxUnavailable=1 或百分比。
  2. 节点排空:驱逐 Pod 到其他可用节点。
  3. 升级节点:更新 kubelet、kube-proxy 及 CRI 组件。
  4. 验证就绪:节点加入集群,运行 node-ready 检查。
  5. 重复:处理下一个节点,直至全部升级完成。
滚动升级逐节点 CRI 影响时序 节点 1(升级中) kubelet 停止 CRI 重启中 Pod 已排空 节点 2(已升级) kubelet v1.28 containerd v1.7 Pod 已恢复 节点 3(待升级) kubelet v1.27 containerd v1.6 Pod 正常运行 滚动升级 CRI 影响特点 • 每个节点 CRI 独立重启,集群整体 CRI 服务不中断 • 新旧 CRI 版本在集群内共存,需保证 gRPC 接口双向兼容 • 排空阶段需确保目标节点 CRI 版本能运行被迁移的 Pod

3.5 升级对 CRI 层的具体影响

无论采用哪种升级策略,CRI 层都会受到以下四个维度的直接影响:

影响维度 具体表现 应对措施
gRPC 接口版本 kubelet 与 CRI 运行时通过 gRPC 通信,版本不匹配导致 ErrRuntimeNotReady 升级前检查 kubelet --version 与 crictl version 兼容性
Sandbox 配置 新版本 CRI 可能修改 PodSandbox 配置结构,导致旧 Sandbox 无法复用 升级后执行 crictl rmp -a 清理旧 Sandbox,让 kubelet 重建
镜像缓存 CRI 重启后镜像缓存丢失,Pod 启动需重新拉取镜像,增加延迟 使用 crictl images 预热缓存,或配置镜像仓库镜像加速
CNI 插件兼容性 CRI 升级可能改变 CNI 调用路径,导致 Pod 网络初始化失败 验证 CNI 插件版本与 CRI 版本的兼容性矩阵
最佳实践:在滚动升级前,建议执行以下 CRI 预检脚本:
#!/bin/bash
# CRI 兼容性预检
echo "=== Kubelet 版本 ==="
kubelet --version
echo "=== CRI 运行时版本 ==="
crictl version
echo "=== 运行时状态 ==="
crictl info
echo "=== 镜像缓存数量 ==="
crictl images -q | wc -l
echo "=== 运行中 Sandbox 数量 ==="
crictl pods | wc -l

3.6 策略选择决策树

根据集群规模、业务容忍度和资源预算,可参考以下决策逻辑:

  • 单节点集群 / 测试环境 → 原地升级(快速验证,接受短暂中断)
  • 多节点生产集群 / 允许分钟级中断 → 滚动升级(推荐,maxUnavailable=1)
  • 核心生产集群 / 零中断要求 → 蓝绿部署(需双倍资源预算)
  • 跨大版本升级(如 v1.27 → v1.29) → 蓝绿部署或分阶段滚动升级(避免 CRI 接口不兼容)
CRI 版本跳跃警告:Kubernetes v1.24 移除了 Dockershim,v1.26 废弃了 CRI v1alpha2。如果从 v1.23 直接升级到 v1.28,CRI 接口将经历两次不兼容变更。此时必须采用蓝绿部署或分阶段滚动升级,中间版本验证 CRI 兼容性。