在上一篇博客中我介绍了 Ambient 模式中的透明流量劫持和四层流量路由,在这一篇博客中,我将向你介绍在 Istio 的 Ambient 模式中,七层流量是如何路由的。
下图展示了 Ambient 模式中七层网络流量路径。
注意:Waypoint Proxy 可以位于应用程序所在节点,甚至图中的服务 A、服务 B 和 Waypoint Proxy 都可以位于同一个节点,之所以将它们画在三个节点上是为了方便展示,但是对于实际的流量路径没有大的影响,只不过是不再通过 eth0 发送到另外一个节点。
下文我们将从手操作探究图中过程。
环境说明
我们继续使用上一篇博客中部署的 Ambient 模式的 Istio,查看环境说明。为了说明七层网路路由,我们需要在此基础上再创建一个 Gateway:
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: Gateway
metadata:
name: productpage
annotations:
istio.io/service-account: bookinfo-productpage
spec:
gatewayClassName: istio-mesh
EOF
执行完该命令后,default
命名空间下会创建了一个 Waypoint proxy,在我的环境中这个 pod 的名字是 bookinfo-productpage-waypoint-proxy-6f88c55d59-4dzdx
,专门用于处理发往 productpage 服务(服务 B)的 L7 流量,我将它称之为 Waypoint Proxy B。
Waypoint 代理可以位于与工作负载相同或者不同的节点上,它也可以部署在独立的命名空间中,不论它位于哪个节点,对于 L7 流量路径没有影响。
Ambient mesh 中透明流量的方式在 L4 和 L7 网络中没有什么不同,因此在这篇博客中我们将略过 Inbound 和 Outbound 流量劫持部分,你可以查看上一篇博客了解详情。
下面我们将直接从流量被劫持到 Ztunnel A 后,被转发到 Envoy 的 15006 端口开始。
Ztunnel A 上的出站流量路由
使用下面的命令导出 Ztunnel A 上的 Envoy 代理配置:
kubectl exec -n istio-system ztunnel-hptxk -c istio-proxy -- curl "127.0.0.1:15000/config_dump?include_eds">ztunnel-a-all-include-eds.json
查看 ztunnel-a-all-include-eds.json
文件中的 Listener 配置部分,根据目的端口和来源 IP 的匹配关系,你将看到 ztunnel_outbound
监听器中有如下配置:
|
|
10.8.14.226
是目标服务的 Cluster IP,服务端口是 9080。流量将被路由到 spiffe://cluster.local/ns/default/sa/sleep_to_server_waypoint_proxy_spiffe://cluster.local/ns/default/sa/bookinfo-productpage
集群,查看该集群的配置:
|
|
该集群使用 EDS 服务发现。查看该集群的 EDS 信息:
|
|
注意:这里还是缺少输出 cluster_name
字段。
在这里直接将流量转发给 Waypoint Proxy 的端点 10.4.3.14:15006
。
Waypoint Proxy B 上的流量转发
我们再导出 Waypoint Proxy B 中的 Envoy 配置:
kubectl exec -n default bookinfo-productpage-waypoint-proxy-6f88c55d59-4dzdx -c istio-proxy -- curl "127.0.0.1:15000/config_dump?include_eds">waypoint-a-all-include-eds.json
查看 inbound_CONNECT_terminate
监听器的配置:
|
|
目的地为 10.8.14.226:9080
的 TCP 流量将被转发到 inbound-vip|9080|internal|productpage.default.svc.cluster.local
,并将 HTTP 类型修改为 CONNECT
,查看该集群的配置:
|
|
该集群的端点是一个内部监听器 inbound-vip|9080||productpage.default.svc.cluster.local
:
|
|
数据包被转发到 inbound-vip|9080|http|productpage.default.svc.cluster.local
集群:
|
|
该集群是 EDS 类型,查看 Endpoint 配置:
|
|
数据包被转发到 inbound-pod|9080||10.4.0.5
监听器:
|
|
数据包被转发到 inbound-pod|9080||10.4.0.5
集群:
|
|
该集群是 STATIC
类型,其中包含了 HBONE 隧道配置(HTTP/2 CONNECT 地址是 10.4.0.15008
),端点是 Envoy 内部监听器 inbound_CONNECT_originate
:
|
|
说明:
listener_filters
中的set_dst_address
将目的地地址设置为10.4.0.5.15008
;- 在隧道中新增了一个 Header:
x-envoy-original-dst-host
,它的值是10.4.0.5:9080
; - 该集群的端点是
inbound_CONNECT_originate
集群;
查看 inbound_CONNECT_originate
集群:
|
|
该集群的类型是 ORIGINAL_DST
,直接与上游建立 HBONE 隧道,将数据包发送到 Pod B 的 15008 端口。在节点 B 的 Ztunnel 的流量劫持和路由方式就跟 L4 是一样的了,在这里不再赘述。
总结
L7 流量路由是在 L4 的基础上增加了 Waypoint 代理,该代理中 Envoy 处理比较复杂。Waypoint 代理使用 Gateway API 生成基于 Deployment 部署的,我们可以根据个别服务的负载情况,单独扩缩容其 Waypoint 代理,也可以创建 HPA 来动态扩容。