Istio 模式采用了被称为HBONE [1] 的方式来连接 ztunnel 和 waypoint proxy。HBONE 是 HTTP-Based Overlay Network Environment 的第一次出现。虽然该创建的名称是第一次看到,但 HBONE 不是 Istio 的一个新协议,而只是利用了 HTTP 协议标准提供的隧道能力。简单地说,环境模式采用了 HTTP 的 CONNECT 方法 [2] 在 ztunnel 和 waypoint proxy 创建了一个隧道,通过该来传输数据分析HBONE的实现机制和原理。
HTTP 隧道原理建立 HTTP 协议隧道的形式通常是采用 HTTP CONNECT 方法。在这种机制下协议,首先向客户端的一个 HTTP 代理服务器发送 HTTP CONNECT 请求,请求中携带需要连接目标服务器。代理服务器根据该请求代表客户端连接之后的目标服务器。和目标服务器建立连接后,代理服务器将客户端的TCP数据流直接透明地传递给目标服务器。在这种方式中,最终的连接请求是HTTP,代理服务器处理的是TCP数据流。
HTTP CONNECT 隧道
通过这种方法,我们可以采用 HTTP CONNECT 创建一个隧道,该隧道中可以传输任何类型的 TCP 数据。
例如一个内部环境中,我们只允许 HTTP 代理来访问外部的网络服务器。但是我们可以通过 HTTP 的隧道来连接到一个外部的 SSH 服务上。。
连接到服务器,发送HTTP CONNECT请求通过客户端和指定端口代理主机的22个隧道建立。
CONNECT for.bar.com:22 HTTP/1.1
如果代理允许连接,并且代理已经连接到指定的主机,则代理将返回 2XX 成功响应。
HTTP/1.1 200正常
现在客户端将通过代理访问远程主机。发送到代理服务器的所有数据都将原封不动地转发到远程主机。
客户端和服务器启动 SSH 通信。
SSH-2 .0-OpenSSH_4 .3 \ r \ n
... ggg
备注:除了 HTTP CONN,除了 HTTP GET 和 POST 也是 HTTP,这种方式创建的 HTTP 隧道的外部 TCP 服务器数据包,采用外部服务器发送的数据包可以发送到客户端并执行的外部服务器收到客户端此请求的响应后,将重新打包为 HTTP 响应,并发送回客户端。在这种方式中,所有流量都封装在 HTTP GET 或 POST 原始请求中。
Envoy 的内部监听器机制我们,socket [3] 就在运行内核接收网络数据,但Envoy还支持一种“用户空间套接字”。Internal Listener [4] 就从“用户空间套接字”接收数据包。用于
Internal Listener 需要和一个 Cluster 一起使用,配置在 Cluster 中作为接收传输的端点。如下所示:
定义一个内部监听器:
名称:demo_internal_listener
Internal_listener:{}
filter_chains:
-过滤器:[
……
]
采用一个 Cluster 来连接 Egress Listener 和 Internal Listener。该 Cluster 配置在 Egress Listener 的 HCM 中,其 endpoint 是 Internal Listener 的名称。
名称:encap_cluster
load_assignment:
cluster_name:encap_cluster
端点:
-磅端点:
-端点:
地址:
envoy_internal_address:
server_listener_name: demo_internal_listener
通过这种方式,可以将 Listener 层叠起来,第一个 Listener 然后从设备配置两个内核网络处理,再经过 interal_listener_demo_internal_listener 的处理,如下面的显示:
名称:入口
地址:
socket_address:
协议:TCP
地址:127.0。0.1
端口值:9999
过滤器链:
-过滤器:
-名称:tcp
typed_config:
“@type”:type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
stat_prefix:入口
集群:encap_cluster
我们可以采用 Envoy 来作为客户端创建一个到 HTTP Proxy 的 HTTP Tunnel,也可以采用 Envoy 来作为 HTTP Proxy 服务器接收客户端的 HTTP CONNECT。
Envoy 作为 HTTP 隧道客户端通过多层监听器中配置的 HTTP 请求,可以将请求的 HTTP 请求内部创建的 HTTP 服务器隧道发送到监听器的外部代理,然后显示监听器(Envoy 的外部代理):来自Github 中的示例文件 [5]
Egress(入口)监听器,从请求端口接收来自客户端的 HTTP 1000
名称:http
地址:
socket_address:
协议:TCP
地址:127.0。0.1
端口值:10000
过滤器链:
-过滤器:
-名称:envoy.filters.network.http_connection_manager
typed_config:
“@type”:type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix:ingress_http
route_config:
名称:local_route
virtual_hosts:
-名称:local_service
域:[ “*” ]
路由:
-匹配:
前缀:“/”
路由:
集群:encap_cluster
http_filters:
-名称:envoy.filters.http.Router
typed_config:
“@type”:type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
Internal Listener,其过滤器链中配置是一个 TcpProxy。该 TcpProxy 中设置了tunneling_config [6] 选项,表示 TcpProxy 将同上游建立一个 HTTP 隧道,将接收到的 TCP 数据通过 HTTP 隧道发送到该上游。 Envoy支持采用HTTP/1.2采用HTTP/1.2的协议方式创建隧道,具体配置中的协议类型和HTTP_extension_options部分。
名称:封装
internal_listener:{}
filter_chains:
-过滤器:
-名称:tcp
typed_config:
“@type”:type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
stat_prefix:tcp_stats
cluster:cluster_0
#表示该TcpProxy将采用HTTP隧道的数据代理方式
隧道配置:
主机名:主机。通讯:443
该 Cluster 配置在 Egress Cluster 的 HCM 中,用于关联 Egress Listener 和 Internal Listener。
集群:
-名称:encap_cluster
load_assignment:
cluster_name:encap_cluster
端点:
-磅端点:
-端点:
地址:
envoy_internal_address:
server_listener_name:encap
该Cluster配置在Internal Cluster中,是HTTP隧道连接的Upstream。
- name: cluster_0
# 该选项表示将采用 HTTP2 CONNECT 来创建隧道
typed_extension_Protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
"@type" : type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicit_http_config:
http2_protocol_options: {}
load_assignment:
# 连接的上游服务器地址
cluster_name: cluster_0
endpoints:
- lb_endpoints:
- endpoint:
address:
套接字地址:
地址: 127.0 .0 .1端口值
: 10001
采用 Internal Listener 创建 HTTP 隧道,代理下游的 HTTP 请求
由于 HTTP 通道是透明传输 TCP 数据的,因此其中可以是任意七层协议的数据,中的 Egress Listener 的过滤链中也可以配置为 HCM。 。
Envoy 作为 HTTP 隧道服务器Envoy 来作为 HTTP Proxy 来接收 HTTP CONNECT 请求,我们和客户端建立 HTTP 隧道。Envoy 不能在同一个 Listener 里面建立隧道,然后从 HTTP 数据隧道中解开出来。要实现这一点,我们负责两层数据流的HCM侦听器,负责创建HTTP隧道并从隧道中的TCP数据流中,然后CO侦听器需要TCP侦听器中的数据流向HCM中的第一个侦听器进行处理。
下面的配置将 Envoy 作为 HTTP CONNECT 隧道服务器端,并采用 Internal Listen 对隧道中的数据进行 HTTP 处理。(该配置文件来自Envoy Github 中的示例文件 [7] )
Egress Listener,从 10001 端口接收来自隧道客户端的 HTTP CONNECT 请求,并将隧道中的数据提交给 Internal Listener 进行下一步处理。注意其中 HCM 的upgrade_type: CONNECT选项表示支持 HTTP COECT,表示采用http2_protocol_optionsHTTP/2。
听众:
-名称:listener_0
地址:
socket_address:
协议:TCP
地址:127.0。0.1
端口值:10001
过滤器链:
-过滤器:
-名称:envoy.filters.network.http_connection_manager
typed_config:
“@type”:type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix:ingress_http
route_config:
名称:local_route
virtual_hosts:
-名称:local_service
域:
- “*”
路线:
-匹配:
connect_matcher:
{}
路线:
# 数据将被发送给 decap_cluster
集群:decap_cluster
upgrade_configs:
-升级类型:连接连接
配置:
{}
http_filters:
-名称:envoy.filters.http.router
typed_config:
“@type”:type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
http2_protocol_options:
allow_connect:true
upgrade_configs:
# 该选项标准支持采用 HTTP CONNECT 请求来创建隧道
-升级类型:连接
Internal Listener,从隧道中获取的 TCP 流解析出 HTTP 请求,并返回一个 HTTP 200 响应。
- 名称:decap
internal_listener:{}
filter_chains:
-过滤器:
-名称:envoy.filters.network.http_connection_manager
typed_config:
“@type”:type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix:ingress_http
route_config:
名称:local_route
virtual_hosts:
-名称:local_service
域:[ “*” ]
路由:
-匹配:
前缀:“/”
direct_response:
状态:200
正文:
inline_string:“你好,世界!\n”
http_filters:
-名称:envoy.filters.http.router
typed_config:
“@type”:type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
采用一个 Cluster 来连接 Egress Listener 和 Internal Listener。该 Cluster 配置在 Egress Listener 的 HCM 中,其 endpoint 是 Internal Listener 的名称。
集群:
-名称:decap_cluster
load_assignment:
cluster_name:decap_cluster
端点:
-磅端点:
-端点:
地址:
envoy_internal_address:
server_listener_name: decap
采用 HTTP Internal Listener 对来自于 CONNECT 隧道的数据进行 HTTP 处理
采用 Envoy 来创建一个隧道的 HTTP CONNECT因此,HTTP CONNECT 隧道服务器可以作为隧道客户端发起一个请求,因此我们可以使用 HTTP CONNECT 隧道创建一个 HTTP CONNECT 隧道作为 HTTP CONN 隧道的端点。图所示:
采用 Envoy 来创建 CONNECT 隧道,建立 HTTP 隧道中的数据进行 HTTP 处理
Istio 的 HBONE 隧道Istio HBONE 采用了自己的方法来创建 HTTP CONNET 隧道,TCP 隧道在进入隧道时会进行 mTLS 加密,在出时 mTLS 释放介绍。一个采用 HBONE 创建的连接方式如下:
HBONE 连接
HBONE 采用了 HTTP CONNECT 创建,还在 HTTP CONNECT 请求中加入隧道头来很方便地在下游和上游之间传递一些时间信息,包括:
- • authority - 请求的原始目的地址,例如 1.2.3.4:80。
- • X-Forwarded-For(任选) - 请求的原始源地址,用于在多次跳转访问之间保留源地址。
- • 行李 (任选) - 客户端/服务器的一些元数据,在遥测中使用。
在这篇文章中,我们介绍了 Istio 环境模式和使用模式中的 HBONE 代理隧道的基本原理的文章,我们通过本书信息演示程序的方式来深入分析环境模式中的 HB 路径。
,