Istio 1.28.10:修掉 krt 控制器里的内存泄漏

2026-07-01 31 预计阅读时间: 1 分钟
来源: istio.io AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:9 分钟

Istio 1.28.10 是一个偏“稳态维护”的补丁版本,重点不是新功能,而是修复一个会影响长期运行稳定性的 bug:krt controller framework 在某些 Fetch 过滤条件变化后,可能留下过期的反向索引条目,导致内存持续增长,并触发不必要的重新计算。

如果你的集群已经在 Istio 1.28.9 上运行,尤其是使用 waypoint、ambient mesh,或者存在频繁 Pod relabel 的场景,这个补丁值得纳入近期升级窗口。

这次修复的问题具体在哪里

本次变更修复的是 krt 控制器框架中的一个内存泄漏。

问题触发点可以理解为:某个对象被 Fetch 过滤器按 key 建立索引后,这个 key 发生了变化,但旧 key 对应的反向索引没有被正确清理。

发布说明中给出的典型例子是:

  • 一个 Pod 原本通过 label 指向某个 waypoint;
  • 后来这个 Pod 被重新打标,改为指向另一个 waypoint;
  • krt 内部用于追踪依赖关系的旧反向索引残留;
  • 随着这类变化累计,控制面内存使用可能增长;
  • 同时,旧索引还可能带来多余的 recomputation。

这类 bug 的麻烦之处在于,它不一定马上变成错误日志或明显故障。更常见的表现是:istiod 内存曲线缓慢上扬、CPU 偶发波动、控制面在高变更集群里越来越“吃力”。

哪些集群更应该关注

不是所有 Istio 集群都会明显感知这个问题。更需要关注的是下面几类环境:

  • 使用 Istio 1.28.9,并且准备继续停留在 1.28 系列;
  • 使用 ambient mesh 或 waypoint 相关能力;
  • 工作负载 label 经常变化,例如发布系统会动态改 label;
  • 集群里 Pod churn 较高,服务实例频繁创建、销毁、迁移;
  • 曾观察到 istiod 内存缓慢增长,但没有清晰业务流量原因。

这次发布说明没有提到安全修复或 API 行为变化,因此它更像是一个低风险的稳定性补丁。不过,Istio 控制面升级仍然应该走灰度和回滚预案,尤其是在生产网格里。

可以这样做升级前检查

下面是一组可以直接改造使用的检查命令。假设你的 Istio 安装在 istio-system 命名空间,控制面 Deployment 名为 istiod

# 1. 查看当前 Istio 控制面镜像版本
kubectl -n istio-system get deploy istiod \
  -o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'

# 2. 观察 istiod Pod 的资源使用
kubectl -n istio-system top pod -l app=istiod

# 3. 查看最近是否有异常重启
kubectl -n istio-system get pod -l app=istiod \
  -o custom-columns=NAME:.metadata.name,READY:.status.containerStatuses[0].ready,RESTARTS:.status.containerStatuses[0].restartCount,AGE:.metadata.creationTimestamp

# 4. 如果使用 waypoint,可查看相关资源
kubectl get gateway -A
kubectl get pod -A --show-labels | grep -E 'waypoint|istio.io/use-waypoint' || true

如果你已经接入 Prometheus,也可以重点观察 istiod 的内存趋势。不同安装方式指标名可能不同,下面给出一个常见方向,实际以你的监控标签为准:

container_memory_working_set_bytes{namespace="istio-system", pod=~"istiod-.*"}

升级前建议至少保留一段基线数据。这样升级后才能判断内存曲线是否稳定,而不是只凭“感觉好多了”。

一个保守的升级流程

如果你使用 istioctl 管理控制面,可以按类似流程操作。请把 profile、revision、values 文件替换成你自己的生产配置。

# 下载或切换到 Istio 1.28.10 对应的 istioctl 后,先确认客户端版本
istioctl version --remote=false

# 生成升级后的 manifests,便于审查差异
istioctl manifest generate \
  --set profile=default \
  --set tag=1.28.10 \
  > istio-1.28.10-rendered.yaml

# 如果你有现成配置文件,建议这样生成
# istioctl manifest generate -f ./istio-values.yaml > istio-1.28.10-rendered.yaml

# 执行升级前检查
istioctl x precheck

# 执行升级
istioctl upgrade \
  --set profile=default \
  --set tag=1.28.10

# 确认控制面状态
kubectl -n istio-system rollout status deploy/istiod
istioctl version

如果你的集群使用 revision-based upgrade,可以先安装新 revision,再逐步切换 namespace 或 workload label。下面是一个可改造的示例:

# 安装 1.28.10 的新 revision,revision 名称仅作示例
istioctl install \
  --set profile=default \
  --set revision=1-28-10 \
  --set tag=1.28.10

# 将测试命名空间切到新 revision
kubectl label namespace demo istio.io/rev=1-28-10 --overwrite
kubectl rollout restart deployment -n demo

# 验证测试命名空间业务正常后,再逐步扩大范围
kubectl get pod -n demo -L istio.io/rev

这类方式的好处是回滚路径更清楚:如果新 revision 有问题,可以把命名空间标签切回旧 revision,并重启工作负载。

验证重点:别只看 Pod Ready

升级完成后,istiod Ready 只是第一层检查。针对这次修复,更有价值的是观察一段时间内的控制面资源趋势。

可以把下面几项放进升级后的观察清单:

  • istiod 内存是否继续线性增长;
  • waypoint 相关 workload relabel 后,控制面是否出现异常 CPU 峰值;
  • istiod 是否有新的 panic、watch 错误或频繁重启;
  • sidecar 或 ztunnel 相关配置下发是否正常;
  • 业务命名空间重新发布后,路由和策略是否符合预期。

一个简单的持续观察命令如下:

# 每 30 秒观察一次 istiod 资源使用
watch -n 30 'kubectl -n istio-system top pod -l app=istiod && kubectl -n istio-system get pod -l app=istiod'

如果你的生产集群规模较大,建议至少观察一个完整发布周期,因为这次 bug 和“对象 key 变化、索引清理”有关,只有在足够多变更发生后,趋势才更明显。

采用建议

Istio 1.28.10 的价值在于降低控制面长期运行中的隐性成本。它不像新特性那样显眼,但对高变更、高密度集群很实际。

建议的处理方式是:

  • 仍在 1.28.9 的集群,优先安排升级到 1.28.10;
  • 使用 waypoint 或频繁 Pod relabel 的环境,缩短评估周期;
  • 升级前后保留 istiod 内存与 CPU 曲线,避免盲目判断;
  • 生产环境优先使用 revision-based 或分批升级;
  • 不要把补丁升级当作“无风险操作”,仍需保留回滚路径。

一句话总结:这不是一次让你改 YAML 的大版本变化,而是一次应该让控制面更安静、更稳的补丁升级。


相关推荐