阿里云ASM支持将多个ACK集群整合在一个ASM实例中,为分布广泛的服务提供统一的管理和运维平台。ASM跨集群网格代理提供了更为灵活的多集群网络互联方案,本文将介绍如何在多集群场景下利用跨集群网格代理打通集群通信。
背景信息
ASM支持多集群模式,即用户可以在同一个ASM实例中加入多个ACK集群。 您可以在ASM中加入多个不同网络下的ACK集群,若多集群的网络不具备打通三层网络的条件(设施限制、CIDR冲突、费用等原因),则可以利用ASM网关打通集群网络,使用ASM跨集群网格代理可以灵活使用公、私有网络将集群网络联通,无感解决地址冲突问题,实现多集群统一的流量治理、安全防护以及全链路可观测。本文将以Sleep应用跨集群访问httpbin为例介绍如何在ASM环境下利用跨集群网格代理配置跨网络多集群互通。
能力优势
ASM 1.22及以上版本提供的跨集群网格代理完整实现了七层客户端负载均衡,跨集群调用场景下,所有路由能力与非跨集群负载均衡完全对齐。
前提条件
已创建ASM实例,版本不低于1.22。具体操作,请参见创建ASM实例。
已添加多个集群到ASM实例。具体操作,请参见添加集群到ASM实例。(本文示例为两个)。
已开启ASM自动注入。具体操作,请参见启用自动注入。
服务之间跨集群访问需要满足以下两个条件之一:
开启了ASM的在ASM中使用DNS代理(推荐)。
手动在客户端所在的集群创建一个和服务端集群相同的目标Service。
步骤一:为ASM控制面绑定公网IP
为了使与ASM实例不在同一网络的集群中的数据平面组件可以正确地连接到ASM控制平面,需要为ASM控制平面Pilot使用的SLB实例绑定EIP,以将Pilot暴露于公网。
登录ASM控制台,在左侧导航栏,选择 。
在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择 。
在基本信息页面右侧,找到Istio Pilot 地址并单击绑定EIP。
绑定EIP到Pilot负载均衡后,若删除ASM实例时未解除绑定,EIP将随ASM实例释放。
步骤二:为集群指定网络配置,并启用跨集群网格代理
您可以为每个集群指定一个逻辑网络。同一个逻辑网络之间的服务可以直接互相访问,不同逻辑网络之间的服务需要通过跨集群网格代理才可以访问。
登录ASM控制台,在左侧导航栏,选择 。
在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择 。
单击多集群网络配置按钮,参考如下方式配置多集群网络。
为ACK-1指定所属逻辑网络为network1。
为ACK-2指定所属逻辑网络为network2,并且在ACK-2中启用跨集群网格代理访问。
应用上述配置后,ASM会为您在ACK-2中创建一个默认跨集群网格代理,该网关具有公网IP。ACK-1中的服务将会自动通过这个跨集群网格代理访问到ACK-2中的服务,并且这条链路默认会启用mTLS加密。
您可以通过ASM集群的kubeconfig查看跨集群网格代理的定义,跨集群网格代理有一个特殊的名称:asm-cross-network-${ACK ID}
。您可以根据自己的需求,自行调节网关的资源和副本数等配置。
目前跨集群网格代理是一个TCP Proxy,无法进行L7负载均衡。可能在某些情况下存在负载不均衡的情况。
步骤三:验证跨集群访问
上述步骤中的网络配置需要在业务Pod启动时生效。如果修改网络配置之前已经启动了业务Pod,则需要重启业务Pod。
在ACK-1中创建Sleep应用,示例YAML配置如下:
在ACK-2中创建httpbin应用,示例YAML配置如下:
从Sleep对应的Pod中访问httpbin应用(使用ACK-1的kubeconfig)。
获取Sleep Pod名称。
kubectl get pod | grep sleep
在Sleep中使用curl访问httpbin。
kubectl exec ${sleep pod名称} -- curl httpbin:8000/status/418
此时可以看到访问成功,输出如下所示:
% Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 135 100 135 0 0 16075 0 --:--:-- --:--:-- --:--:-- 16875 -=[ teapot ]=- _...._ .' _ _ `. | ."` ^ `". _, \_;`"---"`|// | ;/ \_ _/ `"""`
验证Sleep通过跨集群网格代理访问了httpbin。
查看Sleep Pod的日志(使用ACK-1的kubeconfig)。
kubectl logs ${sleep pod名称} -c istio-proxy | tail -1
输出如下所示:
{"authority_for":"httpbin:8000","bytes_received":"0","bytes_sent":"135","downstream_local_address":"xxx.xxx.xxx.xx:8000","downstream_remote_address":"xx.x.xxx.xxx:xxxxx","duration":"7","istio_policy_status":"-","method":"GET","path":"/status/418","protocol":"HTTP/1.1","request_id":"08dc43e9-60c8-4f2f-910a-b727172ce311","requested_server_name":"-","response_code":"418","response_flags":"-","route_name":"default","start_time":"2024-05-23T10:06:27.289Z","trace_id":"-","upstream_cluster":"outbound|8000||httpbin.default.svc.cluster.local","upstream_host":"xxx.xx.xxx.xxx:15443","upstream_local_address":"xx.x.xxx.xxx:60248","upstream_response_time":"7","upstream_service_time":"7","upstream_transport_failure_reason":"-","user_agent":"curl/8.1.2","x_forwarded_for":"-"}
其中的
upstream_host
字段标识Sleep Pod直接访问的目标,可以看到访问的端口是15443
,15443
是跨集群网格代理专用的端口。查看跨集群网格代理的日志(使用ACK-2的kubeconfig)。
首先获取跨集群网格代理Pod。
kubectl -n istio-system get pod | grep asm-cross-network istio-asm-cross-network-c0859be51XXX 1/1 Running 0 20h istio-asm-cross-network-c0859be51XXX 1/1 Running 0 20h
可以看到默认有两个跨集群网格代理的Pod。您可以分别查看这两个Pod的日志,可以看到类似的访问日志。
kubectl logs istio-asm-cross-network-c0859be51XXX -n istio-system | tail -1 {"authority_for":"-","bytes_received":"xxxx","bytes_sent":"xxxx","downstream_local_address":"xx.xx.x.xx:15443","downstream_remote_address":"xx.xx.xx.xx:xxxxx","duration":"1568569","istio_policy_status":"-","method":"-","path":"-","protocol":"-","request_id":"-","requested_server_name":"outbound_.8000_._.httpbin.default.svc.cluster.local","response_code":"0","response_flags":"-","route_name":"-","start_time":"2024-05-23T08:41:16.618Z","trace_id":"-","upstream_cluster":"outbound_.8000_._.httpbin.default.svc.cluster.local","upstream_host":"xx.xx.xx.xxx:80","upstream_local_address":"xx.x.xx.xx:xxxxx","upstream_response_time":"-","upstream_service_time":"-","upstream_transport_failure_reason":"-","user_agent":"-","x_forwarded_for":"-"}