当多个 gateway 配置相同 TLS 证书时发生 404 错误
问题描述
症状
通过 Istio Ingress Gateway 使用 HTTP/2 协议访问时,会出现 404 错误。
这是 Istio 社区中的一个已知问题。更多详情请参考 当多个 gateway 配置相同 TLS 证书时发生 404 错误。
分析
如果配置了多个使用相同 TLS 证书的 gateway,那么利用 HTTP/2 连接复用的浏览器(即大多数浏览器)在已经建立了到某个 host 的连接后,再访问另一个 host 时,就会返回 404 错误。
示例: 如果域名 a.example.com 和 b.example.com 使用相同的 TLS 证书,并且通过同一个 Istio Ingress Gateway 访问,但分别配置在两个不同的 Gateway 资源中,那么 HTTP/2 浏览器客户端在访问过 a.example.com 之后再访问 b.example.com 时会遇到 404 错误。这是由于浏览器的 HTTP/2 连接复用所致。
排查方法
你可以使用以下脚本快速检查你的环境中是否存在与问题描述一致的 Gateway 配置。该脚本需要在 Istio Ingress Gateway 所在的业务集群的主节点上执行。
- 该脚本依赖
jq工具。如果你的集群节点未安装jq工具,请在集群中先安装jq后再执行脚本。工具下载链接:jq download。 jq工具版本必须为 1.7 或更高。
脚本执行输出示例:
如果你在输出中看到类似如下信息:“cred already exist in other gw resource, please must merge hosts in the gw resource drawdb-gateway~drawdb, and delete this gw!” ,则说明你遇到了本文所描述的问题。
解决方案概述
为了解决该问题,我们提供两种方案。你可以参考下面的对比,选择其中一种在你的环境中实施。
方案对比
方案 1:合并 Gateway 资源
方案说明
将使用相同 TLS 证书的多个 Gateway 资源合并为一个。
实施步骤
- 将多个 Gateway 资源合并为一个 Gateway 配置,使用相同的
spec.servers.hosts列表或泛域名配置。 - 修改相关的 VirtualService 资源,确保它们指向合并后的 Gateway。
例如,在原始配置中,两个 Gateway 使用相同的 TLS 证书 testhl:
合并后的正确配置:
也可以使用泛域名格式编写:
步骤总结
- 合并 Gateway 资源的
spec.servers.hosts,将所有使用相同证书的 Gateway 资源合并到一个server配置中。 - 修改 VirtualService 资源,使其指向合并后的 Gateway。
- 确保 VirtualService 中的
destination使用 Kubernetes FQDN 格式。
重要提示: 完成上述步骤后,请重新运行检查脚本,确认问题已经解决。
方案 2:响应码 421
方案说明
在出现问题时返回 421 状态码,可让客户端重新建立连接,从而路由到正确的目标 Host。
实施步骤
应用以下 EnvoyFilter 配置: