Istio 1.29.8:修复 Ambient iptables 漂移、JWKS HTTP/2 与多集群凭据风险

2026-09-21 23 预计阅读时间: 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.

预计阅读时间:10 分钟

Istio 1.29.8 是一个以稳健性和安全性为重点的补丁版本。与 1.29.7 相比,它没有引入显眼的新功能,但修复了几类会造成重复流量规则、无效配置推送、JWKS 获取失败,以及本地凭据插件被意外执行的问题。对于使用 Ambient 模式、多网络网关、外部身份提供商或多集群管理的团队,这次升级的实际价值很高。

Ambient 模式不再因后端检测变化重复写入规则

在 Ambient 模式下,CNI 节点代理需要判断宿主机使用的是 iptables-legacy 还是 iptables-nft。此前,这个自动检测结果可能在代理重启后发生变化。对于已经加入网格的 Pod,代理可能因此再次写入重定向规则,最终留下重复规则。

这类问题很难通过应用日志直接定位:业务 Pod 仍在运行,但流量路径已经发生异常,排查人员往往会先怀疑 ztunnel、策略配置或节点网络。1.29.8 修复了后端选择在重启间发生翻转的问题,减少对已纳管 Pod 重复编程的风险。

升级后,建议重点观察 CNI 和 ztunnel 的滚动状态,而不是一次性重启所有工作负载:

set -euo pipefail

NAMESPACE=istio-system

kubectl -n "$NAMESPACE" rollout status daemonset/istio-cni-node --timeout=5m
kubectl -n "$NAMESPACE" rollout status daemonset/ztunnel --timeout=5m

kubectl -n "$NAMESPACE" get pods -o wide
kubectl get pods -A -o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,NODE:.spec.nodeName,PHASE:.status.phase' \
  | grep -v Running || true

如果集群没有使用 Ambient 模式,ztunnel 或 Ambient CNI DaemonSet 可能不存在,可以跳过对应命令。不要为了验证修复而手动删除生产 Pod 或清空节点 iptables;更安全的做法是先在测试节点上完成 CNI 滚动升级,再观察新建与存量 Pod 的连通性。

JWKS 获取恢复 HTTP/2,代理环境尤其值得关注

Istio 的 JWKS resolver 会获取用于验证 JWT 的公钥。此前,为实现 TLS 固定和 CIDR 阻断而设置的自定义 TLSClientConfigDialContext,会让 Go 的 net/http 不再自动启用 HTTP/2,导致 ALPN 无法协商出 h2

大多数服务端仍能回退到 HTTP/1.1,因此问题可能长期不暴露。但某些 HTTP CONNECT 代理路径不能正确处理这种回退,最终表现为 JWKS 拉取失败和 JWT 验证异常。1.29.8 重新启用了与 http.DefaultTransport 一致的 HTTP/2 行为。

如果生产环境通过代理访问外部 JWKS,可以先从同一网络区域做一个基础探测。下面的命令只验证代理到 JWKS 端点的 HTTP/2 路径,并不能完全替代 Istio 内部验证:

export HTTPS_PROXY='http://proxy.example.internal:3128'
export JWKS_URL='https://idp.example.com/.well-known/jwks.json'

curl --proxy "$HTTPS_PROXY" \
  --http2 \
  --silent --show-error \
  --output /dev/null \
  --write-out 'status=%{http_code} http_version=%{http_version}\n' \
  "$JWKS_URL"

运行前需要替换代理和 JWKS 地址。期望看到成功状态码以及 http_version=2。如果代理需要认证,应通过受控的凭据注入方式提供,不要把用户名和密码写入共享脚本或终端历史。

WDS 推送更稳定,多网关选择不再随机抖动

本次发布还修复了两项控制面效率问题:

  • istiod 在向 Envoy 代理推送工作负载元数据时,不再重复序列化同一个工作负载。
  • 当一个网络配置了多个网关条目时,工作负载所使用的网络网关不再按随机顺序选取。

此前,网关选择顺序不稳定会让同一个工作负载的网关地址在不同重算周期之间来回变化。即使实际拓扑没有改变,也可能触发额外的 WDS 推送。修复后,控制面重算结果更稳定,减少无意义的推送和序列化开销。

需要注意,这并不意味着 1.29.8 会自动实现网关负载均衡策略,也不代表所有 xDS/WDS 推送都会减少。它解决的是输入相同但结果因随机顺序而变化的问题。升级验证时,可以比较 istiod 的 CPU、推送频率和代理配置收敛情况,但不要把所有性能变化都归因于这一项修复。

istioctl analyze 补上多集群 kubeconfig 清理

安全方面最值得注意的改动发生在 istioctl analyze。此前,该命令可以直接根据 istio-system 中的多集群 Secret 构建 Kubernetes 客户端,却没有先清理其中的 kubeconfig。

如果 Secret 被恶意构造,kubeconfig 中的 exec 凭据插件可能在运行 istioctl 的机器上执行外部命令,其他不安全的认证字段也可能尝试读取本地文件。1.29.8 现在会像 istiod 一样清理这些 kubeconfig,再用于客户端创建。

这项修复保护的是运行 istioctl analyze 的环境,包括工程师工作站和 CI Runner。它不应该替代以下基础控制:

  • 限制谁能在 istio-system 中创建或修改 Secret。
  • 不把不受信任的多集群 Secret 导入管理集群。
  • 使用短期、最小权限的 CI 凭据。
  • 避免在拥有大量本地凭据的管理员工作站上分析未知集群配置。

可以先只盘点 Secret 名称和类型,不读取 Secret 内容:

kubectl -n istio-system get secrets \
  -o custom-columns='NAME:.metadata.name,TYPE:.type,CREATED:.metadata.creationTimestamp' \
  | grep -Ei 'multi|remote|cluster' || true

过滤规则需要根据团队的 Secret 命名方式调整。不要在工单、聊天工具或公共 CI 日志中输出 Secret 的 .data 字段。

一套可复制的升级检查流程

升级时应沿用现有安装方式:Helm 管理的集群继续使用 Helm,istioctl 管理的集群继续使用版本化配置文件,不要在补丁升级中顺便切换安装工具。下面是一套可以改造的检查流程,假设本机已经安装 1.29.8 对应的 istioctl

set -euo pipefail

ISTIO_NAMESPACE=istio-system

printf '%s\n' '== Client and control-plane versions =='
istioctl version

printf '%s\n' '== Upgrade precheck =='
istioctl x precheck

printf '%s\n' '== Configuration analysis =='
istioctl analyze -A

printf '%s\n' '== Current control-plane and node images =='
kubectl -n "$ISTIO_NAMESPACE" get deployment,daemonset \
  -o custom-columns='KIND:.kind,NAME:.metadata.name,IMAGE:.spec.template.spec.containers[*].image'

printf '%s\n' '== Unhealthy Istio namespace pods =='
kubectl -n "$ISTIO_NAMESPACE" get pods \
  -o custom-columns='NAME:.metadata.name,READY:.status.containerStatuses[*].ready,PHASE:.status.phase,NODE:.spec.nodeName'

如果使用 istioctl 和版本控制中的安装配置,升级动作可以这样组织:

# 将路径替换成已审核的 IstioOperator 配置。
# 确保执行命令的是 1.29.8 版本 istioctl。
./istio-1.29.8/bin/istioctl install \
  -f ./deploy/istio-operator.yaml \
  -y

kubectl -n istio-system rollout status deployment/istiod --timeout=5m
./istio-1.29.8/bin/istioctl analyze -A

不要省略原有 values 或 IstioOperator 配置后直接套用默认 profile,否则补丁升级可能意外改变网关、CNI、遥测或资源配置。使用 Helm 的环境应执行等价的 helm upgrade,并继续使用当前已审核的 values 文件。

是否应该立即升级

以下环境应优先安排 1.29.8:使用 Ambient 模式、通过 HTTP CONNECT 代理访问 JWKS、配置多个网络网关,或通过 istioctl analyze 检查多集群资源的集群。

上线前至少确认四件事:安装配置已纳入版本控制;多集群 Secret 的写权限受到限制;测试环境完成 JWT 与跨网络连通性验证;升级后检查 CNI、ztunnel、istiod 和网关的滚动状态。它是补丁版本,但涉及节点流量规则与本地命令执行边界,仍应按正式变更处理,而不是无验证地批量推送。


相关推荐