基于 ALPN/TLS 握手的 HTTP 元信息交换

基于 ALPN/TLS 握手的 HTTP 元信息交换#

假如你是一家大公司的 HR,每天都要和不同的同事联系沟通。那么你在开始正式的沟通内容前,要做是什么? 自我介绍和让对方自我介绍。各自表明自己的身份。这些信息可以来源于正式对话开始前的打招呼中,也来在开始对话前看看对方在 Outlook 上的个人信息。

同样,Istio 为实现服务网格,Istio Proxy 需要在网点互连握手时作元信息交换。故 Istio 在原生 Envoy 上再定制了传输层的规约,以实现元信息交换。

让我们从一个例子开始:

[serviceA app --h2c--> serviceA istio-proxy] ----(http over mTLS)---> [serviceB istio-proxy --h2c--> serviceB app]

Istio Proxy 的一个基本设计原则是尽早知道新连接的 downstream/upstream 元数据。因为这样就能尽早做出一些决定。

对于 client side(Outbound) Istio proxy :

如果它事先知道 upstream cluster 的元数据:

  • upstream cluster 是同一个 Istio 网格上的另一个 “Istio Proxy”?

  • upstream cluster 支持哪种类型的 TLS?Istio 网格的自动 mTLS 还是手动传统 TLS?

  • upstream cluster 支持哪种应用级协议:http1.1、http2 还是 http3?

client side(Outbound) Istio Proxy 也可以根据 downstream(同一 pod 上的应用程序)连接决定 upstream 的 HTTP 版本,参见 use_downstream_protocol_config

client side(Outbound) Istio Proxy 可以根据 upstream 服务器支持的 HTTP 版本覆盖(overwrite) ALPN 协议列表。

对于 server side(Inbound) Istio proxy :

例如,当 Istio Proxy 接受来自 downstream 的新连接时,它想知道 downstream 的一些元数据:

  • downstream 是同一个 Istio 网格上的另一个 Istio Proxy 吗?

  • downstream 支持哪种类型的 TLS?Istio 网格的自动 mTLS 还是手动传统 TLS?

  • downstream 支持哪种应用级协议:http1.1、http2 还是 http3?

作为服务器的 “Istio Proxy” 将根据上述 downstream 元数据决定 Network Filter ChainsHttp Filter Chains 的选择。

术语#

outbound istio-proxy 与 inbound istio-proxy 的协作#

上面说过,inbound 和 outbound istio-proxy 需要合作协商 HTTP 版本。下图为一个示例的协作流程:

图 - HTTP 协议元数据交换概述

图: HTTP 协议元数据交换概述#

用 Draw.io 打开

  • Outbound istio-proxy

    基于 istio.alpn HTTP FilterUpstream Cluster 元数据。

  • Inbound istio-proxy

    基于 Listener->filter_chains->filter_chain_match->application_protocols 配置和 Outbound istio-proxy 提供的 ALPN 。

ALPN HTTP Meta Exchange 的故障排除示例: 因配置 Envoy 保留 HTTP/1 header 大小写,在混合 HTTP1 和 HTTP2 的 Istio 网格上意外禁用了 HTTP/2

下图深入探究了 Envoy Proxy 和 Istio Proxy 的相关源码。它展示了背后的实现原理:

图 - upstream http 协议选择示例

图: upstream http 协议选择示例#

用 Draw.io 打开

扩展阅读#