多个 Gateway 配置相同 TLS 证书时出现 404 错误
问题描述
现象
通过 Istio Ingress Gateway 使用 HTTP/2 协议访问时,会出现 404 错误。
这是 Istio Community 中的一个已知问题。更多详情请参见 多个 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 配置: