ACK容器网络数据链路(Terway ENI-Trunking)

Terway ENI-Trunking模式架构设计

弹性网卡中继Trunk ENI是一种可以绑定到专有网络VPC类型ECS实例上的虚拟网卡。相比弹性网卡ENI,Trunk ENI的实例资源密度明显提升。启用Terway Trunk ENI功能后,指定的Pod将使用Trunk ENI资源。为Pod开启自定义配置是可选功能,默认情况下创建的Pod,未开启Terway Trunk ENI功能,使用的是共享ENI上的IP地址。只有当您主动声明为指定Pod开启自定义配置后,相应的Pod才能使用Pod自定义配置能力,Terway才可以同时使用共享ENI以及Trunk ENI为Pod分配IP。两种模式共享节点最大Pod数量配额,总部署密度和开启前一致。

金融、电信,政府等行业对数据信息安全有着非常严格的数据安全要求,通常重要的核心数据会放在自建的机房内,并且对访问此数据的客户端有严格的白名单控制。业务架构上云时,往往是通过专线,VPN等打通自建机房和云上资源打通,由于传统容器中Pod IP是不固定的,NetworkPolicy只能在集群内生效,这对客户的白名单设置有了非常大的挑战。ENI在Trunk模式下,可以配置独立的安全组、Vswitch能力,带来更为细化的网络配置能力,提供极具竞争力的容器网络解决方案。

image

在Trunking的命名空间内可以得到相关的Pod信息和节点信息,其中Pod的IP网络稍后会详细说明。

image

image

image

Pod内只有指向eth0的默认路由,说明Pod访问任何地址段都是从eth0为统一的出入口。

image

对于节点和Pod的通信连接,这个类似于ACK容器网络数据链路(Terway ENIIP)。通过OS Linux Routing,所有指向Pod IP的流量都会被转发到Pod对应的calixxx虚拟网卡上。

image

image

Terway增加一种名为PodNetworking的自定义资源来描述网络配置。您可以创建多个PodNetworking,来规划不同网络平面。创建PodNetworking资源后,Terway将同步网络配置信息,只有status成为Ready后,该网络资源才能对Pod生效。如下图所示,类型为Elastic,只要namespace的标签的符合Trunking:zoneb,就给Pod使用指定的安全组和交换机。

image

创建Pod时,Pod将通过标签去匹配PodNetworking。如果Pod没有匹配到任何PodNetworking,则Pod将使用默认的共享ENI上的IP。如果Pod有匹配到PodNetworking,则将使用PodNetworking中定义的配置分配ENI。关于Pod标签的相关内容,请参见标签

Terway会为这类Pod创建相应的名为PodENI的自定义资源,用于跟踪Pod所使用的资源,该资源由Terway管理,您不可修改该资源。如下trunking命名空间下的centos-59cdc5c9c4-l5vf9 Pod匹配了相应的Podnetworking设置,被分配了相应的Member ENI、对应的Trunking ENI、安全组、交换机和被绑定的ECS实例,这样就实现了Pod维度的交换机,安全组的配置和管理。

image

通过ECS的控制台,可以得到Member ENI和Trunking ENI之间的关系,以及相应的安全组、交换机等信息。

image

image

此处已经了解如何去给每个Pod单独配置交换机、安全组等信息,让每个Pod在通过Trunking ENI出ECS后,可以自动走到对应的配置Member ENI上。那么所有的配置其实落到宿主机上都是通过相关的策略实现的,Trunking ENI网卡是通过的vlan来把对应Pod的流量转发到对应的Member ENI上。如下图,在tc层面可以获得相关ENI的VLAN ID,所以在egress或者ingress的阶段会打上或者去除VLAN ID来实现流量正确转发。

image

故Terway ENI-Trunking模式总体可以归纳为:

  • 弹性网卡中继Trunk ENI是一种可以绑定到专有网络VPC类型ECS实例上的虚拟网卡。相比弹性网卡ENI,Trunk ENI的实例资源密度明显提升。

  • Terway Trunk ENI支持为每个Pod配置固定IP、独立的虚拟交换机、安全组,能提供精细化流量管理、流量隔离、网络策略配置和IP管理能力。

  • 使用Terway插件,您需要选择较高规格和较新类型的ECS神龙机型,即5代或者6代的8核以上机型,且机型要支持Trunk ENI。更多信息,请参见实例规格族

  • 单节点所支持的最大Pod数取决于该节点的弹性网卡(ENI)数。共享ENI支持的最大Pod数=(ECS支持的ENI数-1)×单个ENI支持的私有IP数。

  • Pod安全组规则不会应用到同节点Pod间流量及同节点上节点与Pod间流量。如果您需要限制,可以通过NetworkPolicy进行配置。

  • Pod和对应Memeber ENI流量对应是通过VLAN ID 来实现的。

Terway ENI-Trunking模式容器网络数据链路剖析

将Terway ENI-Trunking模式下的网络链路大体分为以Pod IP对外提供服务和以SVC对外提供服务两个大的SOP场景,进一步细分,可以归纳为20个不同的小的SOP场景。

image

这些场景可以归纳为下面10类典型的场景:

  • 通节点访问Pod(相同or不同安全组)。

  • 同节点同安全组Trunk Pod互访(含访问SVC IP,源端和svc后端部署在同一节点)。

  • 同节点不同安全组Trunk Pod互访(含访问SVC IP,源端和svc后端部署在同一节点)。

  • 不同节点同安全组Trunk Pod互访。

  • 不同节点不同安全组Trunk Pod互访。

  • 集群内源端访问SVC IP(源端和SVC后端不同节点,相同安全组,含Local模式访问external IP)。

  • 集群内源端访问SVC IP(源端和SVC后端不同节点,不同安全组,含Local模式访问external IP)。

  • Cluster模式下,集群内源端访问SVC External IP(源端和SVC后端不同节点,不同安全组)。

  • Cluster模式下,集群内源端访问SVC External IP(源端和SVC后端不同节点,相同安全组)。

  • 集群外访问SVC IP。

场景一:通节点访问Pod(相同or不同安全组)

环境

xxx.10.0.4.22节点上存在nginx-6f545cb57c-kt7r8,IP地址为10.0.4.30。

image

内核路由

nginx-6f545cb57c-kt7r8,IP地址10.0.4.30,该容器在宿主机表现的PID是1734171,该容器网络命名空间有指向容器eth0的默认路由。

image

image

该容器eth0在ECS OS内是通过veth pair和ECS的附属ENI eth1建立链路,同时附属ENI eth1还有个虚拟的calxxx网卡。

image

image

在ECS OS内,有指向Pod IP下一跳为calixxx的路由,通过前文可知calixxx网卡是和每个Pod内的veth1组成的veth pair,所以Pod内访问SVC的CIDR会有指向veth1的路由,不会走默认的eth0路由。因此,calixxx网卡在这里的主要作用是:

1.节点访问Pod。

2.当节点或者Pod访问SVC的CIDR时,会走ECS OS内核协议栈转换,走到calixxx和veth1访问Pod。

image

Trunking命名空间下的nginx-6f545cb57c-kt7r8 Pod匹配了相应的Podnetworking设置,被分配了相应的Memeber ENI、对应的Trunking ENI、安全组、交换机和被绑定的ECS实例,这样就实现了Pod维度的交换机,安全组的配置和管理。

image

在tc层面可以得到VLAN ID 1027,所以数据流量在egress或者ingress的阶段会打上或者去除VLAN ID。

image

ENI的网卡所属的安全组可以得到只允许了指定的IP可以访问nginx Pod的80端口。

image

数据面流量在OS层面的流量转发逻辑,请参见ACK容器网络数据链路(Terway ENIIP)

小结

数据链路转发示意图

image

  • 会经过calixxx网卡,每个非host network的Pod会和calixxx网卡形成veth pair,用于和其他Pod或node进行通信。

  • 整个链路不会经过Pod所分配的ENI,直接在OS的ns中命中IP规则被转发。

  • 整个请求链路是ECS1 OS -> calixxx -> ECS1 Pod1。

  • 因为是通过OS内核routing转发,不经过Member ENI,所以安全组不生效,此链路与Pod所属的Member ENI的安全组无关。

场景二:同节点同安全组Trunk Pod互访(含访问SVC IP,源端和svc后端部署在同一节点)

环境

xxx.10.0.4.22节点上存在nginx-6f545cb57c-kt7r8,IP地址10.0.4.30和busybox-87ff8bd74-g8zs7,IP地址10.0.4.24。

image

内核路由

nginx-6f545cb57c-kt7r8,IP地址10.0.4.30,该容器在宿主机表现的PID是1734171,该容器网络命名空间有指向容器eth0的默认路由。

image.png

image.png

该容器eth0在ECS OS内是通过veth pair和ECS的附属ENI eth1建立链路,同时附属ENI eth1还有个虚拟的calxxx网卡。

image

image.png

在ECS OS内,有指向Pod IP下一跳为calixxx的路由,通过前文可以知道calixxx网卡是和每个Pod内的veth1组成的veth pair,所以Pod内访问SVC的CIDR会有指向veth1的路由,不会走默认的eth0路由。因此,calixxx网卡在这里的主要作用是用于:

1.节点访问Pod。

2.当节点或者Pod访问SVC的CIDR时,会走ECS OS内核协议栈转换,走到calixxx和veth1访问Pod。

image.png

Trunking命名空间下的busybox-87ff8bd74-g8zs7和nginx-6f545cb57c-kt7r8 Pod匹配了相应的Podnetworking设置,被分配了相应的Member ENI、对应的Trunking ENI、安全组、交换机和被绑定的ECS实例,这样就实现了Pod维度的交换机,安全组的配置和管理。

image

image

在tc层面可以得到VLAN ID 1027,所以数据流量在egress或者ingress的阶段会打上或者去除VLAN ID。

image.png

ENI的网卡所属的安全组可以得到只允许了指定的IP可以访问nginx Pod的80端口。

image

置于数据面流量在OS层面的流量转发逻辑,详情请见ACK容器网络数据链路(Terway ENIIP)

小结

数据链路转发示意图:

image

  • 会经过calixxx网卡,每个非host network的Pod会和calixxx网卡形成veth pair,用于和其他Pod或node进行通信。

  • 整个链路不会经过Pod所分配的ENI,直接在OS 的ns中命中 IP rule被转发。

  • 整个请求链路是ECS1 Pod1 eth0 -> calixxx-> cali2xxx -> ECS1 Pod2 eth0。

  • Pod属于同or不同 ENI,链路请求是一致的,不经过ENI。

  • 因为是通过OS内核 routing 转发,不经过 Member ENI,所以安全组不生效,此链路与Pod所属的Member ENI的安全组无关。

  • 访问Pod IP和访问SVC IP(External IP或Cluster IP)的区别是:

访问SVC IP, SVC会在源端Pod eth0和calixxx网卡捕捉到,在目的端Pod的eth0和calixxx时捕捉不到。

场景三:同节点不同安全组Trunk Pod互访(含访问SVC IP,源端和svc后端部署在同一节点)

环境

xxx.10.0.4.244节点上存在nginx-96bb9b7bb-wwrdm,IP地址10.0.5.35和centos-648f9999bc-nxb6l,IP地址10.0.5.18。

image.png

内核路由

相关的Pod的容器网络命名空间,详情请见或和SVC。

通过PodENI可以得到centos-648f9999bc-nxb6l所分配的ENI,安全组sg,交换机vsw等。

image

通过安全组sg-j6ccrxxx可以使centos的Pod访问外部所有的地址。

image.png

同理,可以得出服务端Pod的nginx-96bb9b7bb-wwrdm的安全组sg-j6ccrze8utxxx是只允许192.168.0.0/16可以访问。

image

image

小结

数据链路转发示意图:

image

  • 会经过calixxx网卡,每个非host network的Pod会和calixxx网卡形成veth pair,用于和其他Pod或node进行通信。

  • 整个链路不会经过Pod所分配的ENI,直接在OS 的ns中命中IP rule被转发。

  • 整个请求链路是ECS1 Pod1 eth0 -> cali1xxx-> cali2xxx -> ECS1 Pod2 eth0。

  • Pod属于相同或不同ENI,链路请求是一致的,不经过ENI。

  • 因为是通过OS内核routing转发,不经过Member ENI,所以安全组不生效,此链路与Pod所属的Member ENI的安全组无关。

  • 访问Pod IP和访问SVC IP(External IP or Cluster IP)的区别是:访问SVC IP时,SVC会在源端Pod eth0和calixxx网卡捕捉到,在目的端Pod的eth0和calixxx时捕捉不到。

场景四:不同节点同安全组Trunk Pod互访

环境

xxx.10.0.4.20节点上存在客户端centos-59cdc5c9c4-l5vf9和IP 10.0.4.27。

xxx.10.0.4.22节点上存在服务端nginx-6f545cb57c-kt7r8和IP 10.0.4.30。

image

内核路由

相关的Pod的容器网络命名空间,详情请见或和场景二:同节点同安全组Trunk Pod互访(含访问SVC IP,源端和svc后端部署在同一节点)

通过Podeni可以得到centos-59cdc5c9c4-l5vf9所分配的ENI,安全组sg,交换机vsw等.

通过安全组sg-j6cf3sxrlbuwxxx可以得到centos和nginx的Pod属于同一个安全组sg-j6cf3sxrlbuxxx。

image

image

小结

数据链路转发示意图:

image

  • 会经过calixxx网卡,每个非host network的Pod会和calixxx网卡形成veth pair,用于和其他Pod或node进行通信。

  • 整个链路不会经过Pod所分配的ENI,直接在OS的ns中命中IP rule被转发。

  • 出ECS后,根据要访问的Pod和该Pod ENI所属vswitch,命中VPC路由规则;

  • 整个请求链路是ECS1 Pod1 eth0 -> cali1xxx > Trunk eni ( ECS1) -> Pod1 Member ENI -> vpc route rule(如有) -> Pod2 Member ENI -> > Trunk eni ( ECS2) cali2 xxx -> ECS2 Pod1 eth0

  • 通过OS内核routing转发,经过Member ENI,因为Member ENI属于同一个安全组,所以安全组内默认是互通的。

场景五:不同节点不同安全组Trunk Pod互访

环境

xxx.10.0.4.20节点上存在客户端centos-59cdc5c9c4-l5vf9和IP 10.0.4.27。

xxx.10.0.4.244节点上存在服务端nginx-96bb9b7bb-wwrdm和IP 10.0.5.35。

image

内核路由

相关的Pod的容器网络命名空间,详情请见场景一:通节点访问Pod(相同or不同安全组)场景二:同节点同安全组Trunk Pod互访(含访问SVC IP,源端和svc后端部署在同一节点)

通过Podeni可以得到centos-59cdc5c9c4-l5vf9所分配的ENI,安全组sg,交换机vsw等。

通过安全组sg-j6cf3sxrlbuwxxx可以使centos的Pod访问外部所有的地址。

image

image

同理,可以得出服务端Pod的nginx-96bb9b7bb-wwrdm的安全组sg-j6ccrze8utxxx是只允许192.168.0.0/16访问。

image

image

小结

数据链路转发示意图:

image

  • 会经过calixxx网卡,每个非host network的Pod会和calixxx网卡形成veth pair,用于和其他Pod或node进行通信

  • 整个链路不会经过Pod所分配的ENI,直接在OS的ns中命中IP rule被转发

  • 整个请求链路是ECS1 Pod1 eth0 -> cali1xxx > Trunk eni ( ECS1) -> Pod1 Member ENI -> vpc route rule(如有) -> Pod2 Member ENI -> > Trunk eni ( ECS2) cali2 xxx -> ECS2 Pod1 eth0

  • 通过os内核routing转发,流量会经过Member ENI, 是否可以访问成功,安全组配置对此有着决定性的作用。

场景六:集群内源端访问SVC IP(源端和SVC后端不同节点,相同安全组,含Local模式访问external IP)

环境

xxx.10.0.4.20节点上存在客户端centos-59cdc5c9c4-l5vf9和IP 10.0.4.27。

xxx.10.0.4.22节点上存在服务端nginx-6f545cb57c-kt7r8和IP 10.0.4.30。

image

nginx的svc的Cluster IP是192.168.81.92,External IP是8.xxx.xxx.178。

image

内核路由

ENI-Trunking相比较ENIIP来说,只是在VPC侧增加了对应的Trunking和Member ENI,在OS内并无区别,详情请见场景四:群内非SVC后端Pod所在节点访问SVC Cluster IP

小结

数据链路转发示意图:

image

  • 会经过calixxx网卡,每个非host network的Pod会和calixxx网卡形成veth pair,用于和其他Pod或node进行通信。

  • 整个链路不会经过Pod所分配的ENI,直接在OS的ns中命中IP规则被转发。

  • 出ECS后,根据要访问的Pod和该Pod ENI所属vSwitch,命中VPC路由规则。

  • 整个请求链路是:

去方向:ECS1 Pod1 eth0 -> cali1xxx -> ECS eth0 -> Pod1 Member ENI -> VPC route rule(如有) -> Pod2 Member ENI -> Trunk ENI ( ECS2) cali2 xxx -> ECS2 Pod1 eth0。

回方向: ECS2 Pod1 eth0 -> Trunk eni ( ECS2) cali2 xxx -> Pod2 Member ENI -> vpc route rule(如有) -> Pod1 Member ENI -> Trunk eni ( ECS1) -> cali1xxx -> ECS1 Pod1 eth0。

  • 经过ipvs规则dnat转化, 数据包是以源Pod IP从ECS eth0出,请求目的Pod IP(访问SVC clusterIP,以及Local模式下访问External IP)。

  • 整个链路经过环节有ECS1的eth0,Pod1 Member ENI,Pod2 Member ENI。所以这三个网卡的安全组的配置都会影响数据链路的连通性。

场景七:集群内源端访问SVC IP(源端和SVC后端不同节点,不同安全组,含Local模式访问external IP)

环境

xxx.10.0.4.20节点上存在客户端centos-59cdc5c9c4-l5vf9和IP 10.0.4.27。

xxx.10.0.4.244节点上存在服务端nginx-96bb9b7bb-wwrdm和IP 10.0.5.35。

image

nginx的svc的Cluster IP是192.168.31.83,External IP是47.xxx.xxx.204。

image

内核路由

ENI-Trunking相比较ENIIP来说,只是在VPC侧增加了对应的Truning和Member ENI,在OS内并无区别,详情请见场景四:群内非SVC后端Pod所在节点访问SVC Cluster IP

小结

数据链路转发示意图:

image

  • 会经过calixxx网卡,每个非host network的Pod会和calixxx网卡形成veth pair,用于和其他Pod或node进行通信。

  • 整个链路不会经过Pod所分配的ENI,直接在OS 的ns中命中IP rule被转发。

  • 出ECS后,根据要访问的Pod和该Pod ENI所属vswitch,命中VPC路由规则。

  • 整个请求链路是

  1. 去方向:ECS1 Pod1 eth0 -> cali1xxx -> ECS eth0 -> Pod1 Member ENI -> VPC route rule(如有) -> Pod2 Member ENI -> Trunk ENI ( ECS2) cali2 xxx -> ECS2 Pod1 eth0。

  2. 回方向:ECS2 Pod1 eth0 -> Trunk eni ( ECS2) cali2 xxx -> Pod2 Member ENI -> vpc route rule(如有) -> Pod1 Member ENI -> Trunk eni ( ECS1) -> cali1xxx -> ECS1 Pod1 eth0。

  • 经过ipvs规则dnat转化, 数据包是以源Pod IP从ECS eth0出,请求目的Pod IP。(访问SVC clusterIP,以及Local模式下访问External IP)。

  • 整个链路经过环节有ECS1的eth0,Pod1 Member ENI,Pod2 Member ENI。所以这三个网卡的安全组的配置都会影响数据链路的连通性,需要保证安全组互相放通Pod和ECS的IP。

场景八:Cluster模式下,集群内源端访问SVC External IP(源端和SVC后端不同节点,不同安全组)

环境

xxx.10.0.4.20节点上存在客户端centos-59cdc5c9c4-l5vf9和IP 10.0.4.27。

xxx.10.0.4.244节点上存在服务端nginx-96bb9b7bb-wwrdm和IP 10.0.5.35。

image

image

nginx的svc的Cluster IP是192.168.31.83,External IP是47.xxx.xxx.204,ExternalTrafficPolicy是Cluster模式。

image

内核路由

ENI-Trunking相比较ENIIP来说,只是在VPC侧增加了对应的Truning和Member ENI,在OS内并无区别,详情请见场景五:Cluster模式,集群内非SVC后端Pod所在节点访问SVC External IP小节

小结

数据链路转发示意图:

image

  • 会经过calixxx网卡,每个非host network的Pod会和calixxx网卡形成veth pair,用于和其他Pod或node进行通信

  • 整个链路不会经过Pod所分配的ENI,直接在OS 的ns中命中IP rule被转发。

  • 出ECS后,根据要访问的Pod和该Pod ENI所属vswitch,命中VPC路由规则。

  • 整个请求链路是ECS1 Pod1 eth0 -> cali1xxx > ECS eth0 -> vpc route rule(如有) -> Pod2 Member ENI -> Trunk eni ( ECS2) cali2 xxx -> ECS2 Pod1 eth0。

  • 经过IPVS规则fnat转化, 数据包是以源ECS从ECS eth0出,请求目的Pod IP。(访问SVC clusterIP,以及Local模式下访问External IP)。

  • 整个链路经过的环节有ECS1的eth0和Pod2 Member ENI。所以这两个网卡的安全组的配置都会影响数据链路的连通性,需要保证安全组互相放通Pod和ECS的IP。

场景九:Cluster模式下,集群内源端访问SVC External IP(源端和SVC后端不同节点,相同安全组)

环境

xxx.10.0.4.20节点上存在客户端centos-59cdc5c9c4-l5vf9和IP 10.0.4.27。

xxx.10.0.4.22节点上存在服务端nginx-6f545cb57c-kt7r8和IP 10.0.4.30。

image

image

nginx 的svc的Cluster IP是192.168.81.92 External IP是8.xxx.xxx.178,ExternalTrafficPolicy为Cluster。

image

内核路由

ENI-Trunking相比较ENIIP来说,只是在VPC侧增加了对应的Trunking和Member ENI,在OS内并无区别,详情请见场景五:Cluster模式,集群内非SVC后端Pod所在节点访问SVC External IP

小结

数据链路转发示意图:

image

  • 会经过calixxx网卡,每个非host network的Pod会和calixxx网卡形成veth pair,用于和其他Pod或node进行通信。

  • 整个链路不会经过Pod所分配的ENI,直接在OS 的ns中命中IP rule被转发。

  • 出ECS后,根据要访问的Pod和该Pod ENI所属vswitch,命中VPC路由规则。

  • 整个请求链路是ECS1 Pod1 eth0 -> cali1xxx > ECS eth0 -> vpc route rule(如有) -> Pod2 Member ENI -> Trunk eni ( ECS2) cali2 xxx -> ECS2 Pod1 eth0。

  • 经过ipvs规则fnat转化, 数据包是以源ECS从ECS eth0出,请求目的Pod IP。(访问SVC clusterIP,以及Local模式下访问External IP)。

  • 整个链路经过环节有ECS1 的eth0,Pod2 Member ENI。所以这两个网卡的安全组的配置都会影响数据链路的连通性,需要保证安全组互相放通Pod和ECS的IP。

场景十:集群外访问SVC IP

环境

xxx.10.0.4.20节点上存在客户端centos-59cdc5c9c4-l5vf9和IP 10.0.4.27。

xxx.10.0.4.22节点上存在服务端nginx-6f545cb57c-kt7r8和IP 10.0.4.30。

image

image

nginx的svc的Cluster IP是192.168.81.92,External IP是8.xxx.xxx.178,ExternalTrafficPolicy为Cluster。

image

SLB相关配置

在SLB控制台,可以得到lb-j6cmv8xxx虚拟服务器组的后端是三个nginx Pod的ENI eni-j6cgrqqrtvcxxx、eni-j6c54tyfku5xxx和eni-j6cf7e4qnfx2xxx,这几个ENI类型都是Member ENI。

image

image

小结

数据链路转发示意图:

image

  • 会经过calixxx网卡,每个非host network的Pod会和calixxx网卡形成veth pair,用于和其他Pod或node进行通信。

  • 数据链路:client -> SLB -> Pod Member ENI + Pod Port -> Trunking ENI -> ECS1 Pod1 eth0。

  • ExternalTrafficPolicy为Local或Cluster模式下, SLB只会将 Pod分配的Member ENI挂在到SLB的虚拟服务器组。

  • SLB转发请求只会转发到目标Member ENI上,然后通过vlan匹配发送到Trunk ENI,再由Trunk ENI 转发到Pod。