4. Istio 升级流程概览:升级前检查、控制平面升级、数据平面升级、Sidecar 重启策略
Istio 升级并非单一操作,而是一个需要严格遵循阶段顺序的工程流程。根据官方推荐及生产环境最佳实践,升级过程可划分为四个核心阶段:升级前检查、控制平面升级、数据平面升级以及Sidecar 重启策略。每个阶段都有其特定的目标、风险点和验证手段。
核心原则: 始终遵循“先控制面,后数据面”的升级顺序。控制平面升级完成后,数据平面(Envoy Sidecar)的注入策略可能会因 API 版本变更或配置模型调整而自动重置,这是本课程后续章节重点解决的实践问题。
4.1 升级流程全景图
下图展示了 Istio 升级的完整生命周期,从环境准备到 Sidecar 最终就绪,每个阶段都包含关键的检查点与决策点。
4.2 升级前检查(Pre-Upgrade Checklist)
升级前检查是避免升级失败或中断业务的第一道防线。此阶段的核心目标是确认当前环境是否满足新版本 Istio 的要求,并记录关键状态以便回滚。
| 检查类别 | 具体检查项 | 检查命令 / 方法 | 预期结果 |
|---|---|---|---|
| 版本兼容性 | 当前 Istio 版本与目标版本之间的升级路径 | istioctl x precheck |
无阻断性错误 |
| Kubernetes 版本 | 集群 K8s 版本是否在目标 Istio 支持范围内 | kubectl version --short |
版本 ≥ 1.25(以 Istio 1.20+ 为例) |
| 资源配额 | 控制平面 Pod(istiod)的 CPU/内存余量 | kubectl top pods -n istio-system |
CPU 使用率 < 70%,内存余量 > 512Mi |
| CRD 备份 | 备份所有 Istio CRD 及自定义资源 | kubectl get crd | grep istio + kubectl get ... -o yaml > backup.yaml |
备份文件完整可读 |
| Sidecar 注入状态 | 记录当前命名空间的注入标签(revision) | kubectl get ns -L istio-injection,istio.io/rev |
明确每个命名空间的注入策略 |
| 健康状态快照 | 记录当前所有 Pod 的运行状态 | kubectl get pods --all-namespaces |
所有 Pod 均为 Running/Ready |
常见陷阱: 跳过 CRD 备份是升级回滚失败的首要原因。Istio 升级会更新 CRD 的 schema,如果新版本不兼容旧 CRD 实例,回滚后将无法解析已有资源。务必在升级前执行
kubectl get crd -o yaml > crd-backup-$(date +%Y%m%d).yaml。
4.3 控制平面升级(Control Plane Upgrade)
控制平面升级的核心是替换 istiod 组件并更新相关的 CRD 与 Webhook 配置。此阶段通常使用 istioctl upgrade 命令完成,但也可以采用金丝雀发布(Canary Upgrade)方式。
4.3.1 标准升级流程
- 下载新版本 istioctl: 确保客户端版本与目标版本一致。
- 执行升级预检:
istioctl x precheck确认无阻塞项。 - 应用新 CRD:
kubectl apply -f manifests/charts/base/crds - 升级控制平面:
istioctl upgrade -f your-iop.yaml - 验证控制平面: 检查 istiod Pod 状态、Webhook 配置及注入端点。
4.3.2 金丝雀升级(Canary Upgrade)
对于生产环境,推荐使用金丝雀升级策略,即同时运行新旧两个版本的控制平面,逐步将流量切换到新版本。
# 安装新版本控制平面(使用新 revision)
istioctl install --set revision=canary -f new-profile.yaml
# 验证新控制平面就绪
kubectl get pods -n istio-system -l istio.io/rev=canary
# 将测试命名空间切换到新 revision
kubectl label ns test-ns istio-injection- istio.io/rev=canary
# 验证测试命名空间 Pod 注入正常后,再逐步切换生产命名空间
关键影响: 控制平面升级完成后,
MutatingWebhookConfiguration 会被更新。如果新版本的默认注入策略与旧版本不同(例如从 istio-injection: enabled 切换到 istio.io/rev: default),则所有未显式指定 revision 标签的命名空间将自动使用新版本的注入配置,导致 Sidecar 注入策略“静默重置”。
4.4 数据平面升级(Data Plane Upgrade)
数据平面升级即更新所有 Envoy Sidecar 代理。由于 Sidecar 是作为 init 容器和 sidecar 容器注入到业务 Pod 中的,因此升级数据平面本质上是重新创建所有注入过 Sidecar 的 Pod。
4.4.1 数据平面升级方式对比
| 升级方式 | 操作手段 | 对业务的影响 | 适用场景 |
|---|---|---|---|
| 滚动更新 Deployment | 修改 Pod 模板(如更新镜像版本)触发滚动更新 | 零停机(需配置 PDB) | 所有 Deployment 管理的无状态服务 |
| 原地重启 Sidecar | 使用 istioctl proxy-reset 或直接删除 Sidecar 容器 |
短时连接中断(毫秒级) | StatefulSet 或有状态服务 |
| Pod 原地重建 | 使用 kubectl delete pod 触发重建 |
短暂中断(秒级) | 测试环境或允许停服的场景 |
| 分批灰度升级 | 通过标签选择器分批重建 Pod | 可控影响 | 大规模生产集群 |
4.4.2 验证数据平面升级成功
升级完成后,必须验证所有 Sidecar 的版本是否已更新,并且流量转发正常。
# 查看所有 Sidecar 的 Envoy 版本
kubectl exec <pod-name> -c istio-proxy -- pilot-agent request GET /server_info | grep "version"
# 批量检查命名空间内所有 Pod 的 Sidecar 版本
kubectl get pods -n <namespace> -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[?(@.name=="istio-proxy")].image}{"\n"}{end}'
4.5 Sidecar 重启策略(Sidecar Restart Strategy)
Sidecar 重启策略是数据平面升级的具体执行方案,也是本课程的核心关注点。选择正确的重启策略,可以在最小化业务影响的前提下,确保所有 Sidecar 都更新到新版本。
4.5.1 三种主流重启策略
- 策略一:滚动重启(Rolling Restart)
- 原理:通过更新 Deployment 的 Pod 模板(如添加一个无关紧要的 annotation)触发滚动更新。
- 优点:零停机,K8s 原生支持。
- 缺点:需要修改 Deployment 对象,可能触发不必要的配置同步。
- 策略二:优雅排空重启(Graceful Drain Restart)
- 原理:先通过
istioctl proxy-config排空连接,再重启 Sidecar。 - 优点:连接中断最小化,适合长连接服务。
- 缺点:操作步骤较多,需要脚本化。
- 原理:先通过
- 策略三:原地重启(In-Place Restart)
- 原理:直接删除 Sidecar 容器,K8s 会自动重建。
- 优点:快速,不修改 Pod 模板。
- 缺点:可能导致短暂连接中断,不适合有状态服务。
4.5.2 重启策略选择矩阵
| 业务类型 | 推荐策略 | 理由 |
|---|---|---|
| 无状态 HTTP 服务 | 滚动重启 | 零停机,K8s 自动处理 |
| 有状态服务(如数据库) | 优雅排空重启 | 避免连接中断导致数据不一致 |
| 批处理任务 / Job | 原地重启 | 任务完成后自动退出,重启影响小 |
| 大规模集群(>1000 Pod) | 分批灰度 + 滚动重启 | 控制爆炸半径,便于回滚 |
4.5.3 注入策略重置的触发时机
Sidecar 注入策略重置通常发生在以下两个关键节点:
- 控制平面升级完成时: MutatingWebhookConfiguration 被更新,导致新创建的 Pod 使用新的注入策略。
- Pod 重启时: 如果命名空间的注入标签被修改(例如从
istio-injection: enabled变为istio.io/rev: canary),重启后的 Pod 将使用新的 revision 进行注入。
最佳实践: 在升级前,使用
kubectl get ns -L istio-injection,istio.io/rev 记录所有命名空间的注入标签。升级后,对比这些标签是否发生变化。如果发现标签被重置,需要手动恢复或使用自动化脚本重新应用正确的注入策略。