当多个网关配置相同 TLS 证书时发生 404 错误
问题描述
现象
通过 Istio Ingress Gateway 使用 HTTP/2 协议访问时,会出现 404 错误。
这是 Istio Community 中已知的问题。有关更多详情,请参见 404 errors occur when multiple gateways configured with same TLS certificate。
分析
如果配置了多个使用相同 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 配置: