基于 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 Chains 和 Http Filter Chains 的选择。
术语#
h2c -
基于 TCP 的 HTTP/2或HTTP/2 明文(Cleartext)h2 -
基于 TLS 的 HTTP/2(使用 ALPN 作协议协商)ALPN - 基于 TLS 的
ALPN(Application-Layer Protocol Negotiation 应用层协议协商)
outbound istio-proxy 与 inbound istio-proxy 的协作#
上面说过,inbound 和 outbound istio-proxy 需要合作协商 HTTP 版本。下图为一个示例的协作流程:
图: HTTP 协议元数据交换概述#
Outbound istio-proxy
基于
istio.alpn HTTP Filter和Upstream 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 协议选择示例#