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

Terway ENI模式架构设计

Terway ENI模式下,ENI的网络与VPC的网络是相同的网段,ENI网络就是从阿里云的VPC网络中创建和绑定一个弹性网卡到ECS节点上,然后Pod利用这个弹性网卡和其他网络完成互通。但弹性网卡的数量存在限制,详细信息,请参见实例规格族

image

Pod所使用的CIDR网段和节点的CIDR是同一个网段。

image

Pod内部可以得到两张网卡,eth0和veth1。其中,eth0的IP为Pod的IP,此网卡的MAC地址和控制台上ENI的MAC地址可以匹配,表明此网卡为附属ENI网卡,被直接挂载到了Pod的网络命名空间内。

image

控制台信息如下所示:

image

Pod内有指向eth0的默认路由,同时还有指向目的网段为192.168.0.0/16、下一跳为veth1网卡的路由。其中,192.168.0.0/16网段为集群的Service网段,表明集群内Pod访问SVC的Cluster IP网段。数据链路会经过veth1网卡到宿主机ECS的OS内进行下一步判断。其他情况下,数据链路会经由eth0直接进入VPC。

image

容器的网络命名空间中通过ip addr可以查看veth1@if19的标志位,通过'19'可以在ECS的OS内得到和容器网络命名空间中的veth pair相匹配的另一张网卡。在ECS OS内通过ip addr | grep 19:可以得到cali38ef34581a9这个虚拟网卡,这个就是在ECS OS侧相对应的veth pair。

image

到目前为止,容器访问SVC的Cluster IP时,容器和OS数据链路之间的连接已经建立。通过OS Linux Routing,所有目的是Pod CIDR网段的流量都会被转发到Pod对应的calixxx虚拟网卡。因此,ECS OS和Pod的网络命名空间之间已经建立起完整的出入链路配置。

image

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

针对容器网络特点,可以将Terway ENI模式下的网络链路大致分为以Pod IP对外提供服务和以SVC对外提供服务两个主要场景,进一步细分可以拆分为8个不同的小的SOP场景。

image

对这8个场景的数据链路进行梳理合并后,可以归纳出以下8类典型场景。

TerwayENI架构下,不同的数据链路访问情况可以总结归纳为8类:

•访问Pod IP,同节点访问Pod。

•访问Pod IP,同节点Pod之间互访。

•访问Pod IP,异节点Pod间互访。

•集群内访问SVC IP(Cluster IP),源端和SVC后端Pod为同一节点。

•集群内访问SVC IP(Cluster IP),源端和SVC后端Pod为不同节点。

•集群内访问SVC IP(External IP),源端和SVC后端Pod为同一节点。

•集群内访问SVC IP(External IP),源端和SVC后端Pod为不同节点。

•集群外访问SVC External IP。

场景一:访问Pod IP,同节点访问Pod

环境

xxx.10.0.0.196节点上存在nginx1-5969d8fc89-9t99h和10.0.0.203。

image

内核路由

nginx1-5969d8fc89-9t99h IP地址10.0.0.203,该容器在宿主机表现的PID是1094736,该容器网络命名空间有指向容器eth0的默认路由和下一跳为veth1,目的网段为Service的两条路由。

image

image

image

该容器veth1在ECS OS内对应veth pair是cali5068e632525

image

image

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

1.节点访问Pod。

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

image

小结

nginx1-5969d8fc89-9t99h netns veth1可以抓到数据包。

image

nginx1-5969d8fc89-9t99h cali5068e632525可以抓到数据包。

image

数据链路转发示意图:

image

  • 数据链路是ECS -> Linux routing -> calicxxx -> Pod net ns veth1,数据链路完成宿主机ns切换至Pod ns。

  • 通过宿主机上的路由切换至Pod所属的veth pair。

  • 该网卡为被分配的Pod独占,无法和其他Pod进行共享。

场景二:访问Pod IP,同节点Pod访问Pod

环境

xxx.10.0.0.196节点上存在两个Pod:centos-59cdc5c9c4-89f8x,IP地址为10.0.0.202,以及nginx1-5969d8fc89-9t99h,IP地址为10.0.0.203。

image

内核路由

centos-59cdc5c9c4-89f8x IP地址10.0.0.202,该容器在宿主机表现的PID是2314075,该容器网络命名空间有指向容器eth0的默认路由和下一跳为veth1,目的网段为Service的两条路由。

image

image

image

通过上述类似的方法,可以得到nginx1-5969d8fc89-9t99h IP地址为10.0.0.203,该容器在宿主机表现的PID是1094736。

image

小结

centos-59cdc5c9c4-89f8x netns eth1可以抓到数据包。

image

nginx1-5969d8fc89-9t99h netns eth1可以抓到数据包。

image

数据链路转发示意图:

image

  • 数据链路是Pod1 netns eth1 -> VPC -> Pod2 netns eth2。数据链路不经过宿主机Host Namespace,数据链路会先出ECS,再到VPC,再回到原来的ECS。

  • 在Pod内的net Namespace中,直接命中默认路由规则,从eth0网卡出Pod直接到VPC。这里的eth0则为附属网卡ENI,直接被挂载在了Pod的net ns,走了PCI网卡。

  • 该网卡为被分配的Pod独占,无法和其他Pod进行共享。

场景三:访问Pod IP,异节点Pod访问Pod

环境

xxx.10.0.0.196节点上存在Pod:centos-59cdc5c9c4-89f8x,IP地址为10.0.0.202。

xxx.10.0.2.80节点上存在Pod:nginx-6f545cb57c-jmbrq,IP地址为10.0.2.86。

image

内核路由

centos-59cdc5c9c4-89f8x IP地址10.0.0.202,该容器在宿主机表现的PID是2314075,该容器网络命名空间有指向容器eth0的默认路由和下一跳为veth1,目的网段为Service的两条路由。

image

image

image

通过上述类似的方法,可以得到nginx-6f545cb57c-jmbrq,IP地址10.0.2.86,该容器在宿主机表现的PID是1083623。

image

image

小结

centos-59cdc5c9c4-89f8x netns eth0可以抓到数据包。

image

nginx-6f545cb57c-jmbrq netns eth0可以抓到数据包。

image

数据链路转发示意图:

image

  • 数据链路是ECS1 Pod1 netns eth0 -> VPC -> ECS2 Pod2 netns eth0。数据链路不经过宿主机Host Namespace,数据链路会先出ECS1,到VPC再回到ECS2。

  • 在Pod内的net Namespace中,直接命中默认路由规则,从eth0网卡出Pod直接到VPC。这里的eth0则为附属网卡ENI直接被挂载在了Pod的net ns,走了PCI设备。

  • 该网卡为被分配的Pod独占,无法和其他Pod共享。

场景四:集群内访问SVC IP(Cluster IP),源端和SVC后端Pod为同一节点

环境

xxx.10.0.0.196节点上存在两个Pod:centos-59cdc5c9c4-89f8x,IP地址为10.0.0.202,以及nginx1-5969d8fc89-9t99h,IP地址为10.0.0.203。

image

Service是nginx1集群内Cluster IP是192.168.41.244,External IP是8.xxx.xxx.179。

image

内核路由

centos-59cdc5c9c4-89f8x,IP地址10.0.0.202,该容器在宿主机表现的PID是2314075,该容器网络命名空间有指向容器eth0的默认路由和下一跳为veth1,目的网段为Service的两条路由。

image

image

该容器eth0在ECS OS内对应的veth pair是cali38ef34581a9。

image

image

通过上述类似的方法,可以得到nginx1-5969d8fc89-9t99h,IP地址10.0.0.203,该容器在宿主机表现的PID是1094736,该容器eth0在ECS OS内veth pair是cali5068e632525。

image

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

1.节点访问Pod。

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

image

小结

centos-59cdc5c9c4-89f8x netns veth1可以抓到数据包。

image

centos-59cdc5c9c4-89f8x netns cali38ef34581a9可以抓到数据包。

image

nginx1-5969d8fc89-9t99h netns veth1可以抓到数据包。

image

nginx1-5969d8fc89-9t99h netns cali5068e632525可以抓到数据包。

image

数据链路转发示意图:

image

  • 数据链路是ECS1 Pod1 netns veth1 -> calixxx1 -> calixxx2 -> ECS1 Pod2 netns veth1。

  • 在Pod内的net Namespace中,命中SVC的路由,从veth1网卡出Pod到ECS的Namespace,然后通过Linux Routing转到另一个Pod的calixx网卡。这里的veth1和calixxx是veth pair。

  • 源端Pod所分配的veth,calixxxxx网卡可以捕获到SVC IP和源端Pod IP。SVC IP会在源端ECS Host内命中ipvs/iptables规则,做Nat转换。

  • 目的端Pod所分配的veth,calixxxxx网卡可以捕获calixxxxx网卡默认IP和目的Pod IP。

  • 该网卡为被分配的Pod独占,无法和其他Pod进行共享。

场景五:集群内访问SVC IP(Cluster IP),源端和SVC后端Pod为不同节点

环境

xxx.10.0.0.196节点上存在Pod:centos-59cdc5c9c4-89f8x,IP地址10.0.0.202。

xxx.10.0.2.80节点上存在Pod:nginx-6f545cb57c-jmbrq,IP地址10.0.2.86。

image

Service是Nginx的Cluster IP,地址为192.168.204.233,External IP是8.xxx.xxx.33。

image

内核路由

centos-59cdc5c9c4-89f8x,IP地址10.0.0.202,该容器在宿主机表现的PID是2314075,该容器网络命名空间有指向容器eth0的默认路由和下一跳为veth1,目的网段为Service。

image

image

该容器eth0在ECS OS内对应的veth pair是cali38ef34581a9。

image

image

通过上述类似的方法,可以得到nginx-6f545cb57c-jmbrq,IP地址10.0.2.86,该容器在宿主机上表现的PID是1083623,该Pod网卡ENI被直接挂载到了Pod的网络命名空间内。

image

image

小结

数据链路转发示意图:

image

  • 数据链路是ECS1 Pod1 netns veth1 -> calixxx -> ECS1 eth0 -> VPC -> ECS2 Pod2 netns veth1。

  • 在客户端Pod内的net Namespace中,命中SVC的路由,从veth1网卡出Pod到ECS的Namespace,然后通过Linux Routing转发到客户端ECS eth0网卡,然后进入到VPC转发到目的Pod所属的eth网卡。

  • 源端Pod所分配的veth,calixxxxx网卡可以捕获到SVC IP和源端Pod IP。

  • SVC IP会在源端ECS Host内命中ipvs/iptables规则,进行Fnat转化。在源端ECS所属的eth0只能捕获到ipvs/iptables规则所分配的目的Pod IP和源ECS IP。

  • 目的Pod内eth0所捕获的IP是源端ECS IP和目的Pod IP(源Pod IP和SVC IP不会体现)。

  • 该网卡为被分配的Pod独占,不和其他Pod进行共享。

场景六:集群内访问SVC IP(External IP),源端和SVC后端Pod为同一节点

环境

xxx.10.0.0.196节点上存在两个Pod:centos-59cdc5c9c4-89f8x,IP地址10.0.0.202,以及nginx1-5969d8fc89-9t99h,IP地址10.0.0.203。

image

Service是nginx1集群内Cluster IP是192.168.221.163,External IP是10.0.2.89。

image

内核路由

centos-59cdc5c9c4-89f8x,IP地址10.0.0.202,该容器在宿主机表现的PID是2314075,该容器网络命名空间有指向容器eth0的默认路由和下一跳为veth1,目的网段为Service的Cluster IP的两条路由。

image

image

image

SLB相关配置

虚拟服务器组的后端只有nginx1-5969d8fc89-9t99h的ENI eni-t4n6qvabpxxx。

image

综上,可以判断如果访问的是SVC的External IP,是走默认路由到eth0,直接出ECS进入到VPC,访问到SLB的实例,再由SLB实例转发到后端ENI上。

小结

数据链路转发示意图:

image

  • 数据链路是ECS1 Pod1 netns eth0 -> VPC -> SLB -> VPC -> ECS1 Pod2 netns eth0。数据链路不经过宿主机Host Namespace,数据链路会先出ECS1,再到VPC,再回到ECS1。

  • 在Pod内的net Namespace中,直接命中默认路由规则,从eth0网卡出Pod直接到VPC。这里的eth0其实就是附属网卡ENI,直接被挂载在了Pod的net ns,走了PCI设备。

  • 该网卡为被分配的Pod独占,无法和其他Pod共享。

  • 场景四:集群内访问SVC IP(Cluster IP),源端和SVC后端Pod为同一节点场景可以得到非常大的不同,虽然都是前后端Pod都是部署在同一个ECS访问SVC的IP,但是可以得到如果访问的是SVC的Cluster IP,则数据链路会进入到ECS OS层面;如果访问的是External IP,则不会经过ECS的操作系统,直接出ECS,经过SLB转发到目的Pod上。

场景七:集群内访问SVC IP(External IP),源端和SVC后端Pod为不同节点

环境

xxx.10.0.0.196节点上存在Pod:centos-59cdc5c9c4-89f8x,IP地址10.0.0.202。

xxx.10.0.2.80节点上存在Pod:nginx-6f545cb57c-jmbrq,IP地址10.0.2.86。

image

Service是Nginx的Cluster IP,地址为192.168.254.141,External IP是10.0.2.90。

image

内核路由

centos-59cdc5c9c4-89f8x IP地址10.0.0.202,该容器在宿主机表现的PID是2314075,该容器网络命名空间有指向容器eth0的默认路由和下一跳为veth1,目的网段为Service的Cluster IP的两条路由。

image

image

image

SLB相关配置

在SLB控制台,可以得到lb-t4nih6p8w8b1dc7xxx虚拟服务器组的后端只有nginx-6f545cb57c-jmbrq的ENI eni-t4n5kzo553dfaxxx。

image

综上,可以判断如果访问的是SVC的External IP,经过默认路由到eth0,直接出ECS进入到VPC,访问到SLB的实例,再由SLB实例转发到后端ENI上。

小结

数据链路转发示意图:

image

  • 数据链路是ECS1 Pod1 netns eth0 -> VPC -> SLB -> VPC -> ECS2 Pod2 netns eth0。数据链路不经过宿主机Host Namespace,数据链路会先出ECS1,到SLB再回到ECS2。

  • 在Pod内的net Namespace中,直接命中默认路由规则,从eth0网卡出Pod直接到VPC。这里的eth0则为附属网卡ENI,直接被挂载在了Pod的net ns,走了PCI设备。

  • 该网卡为被分配的Pod独占,无法和其他Pod进行共享。

  • 场景五:集群内访问SVC IP(Cluster IP),源端和SVC后端Pod为不同节点场景可以得到非常大的不同,虽然都是前后端Pod都是部署在不同ECS访问SVC的IP,但是可以得到如果访问的是SVC的Cluster IP,则数据链路会进入到ECS OS层面,通过ECS的eth0出ECS,进入到VPC;如果访问的是External IP,则不会经过ECS OS,直接通过Pod所属的附属ENI出ECS,经过SLB转发到目的Pod上。

场景八:集群外访问SVC External IP

环境

xxx.10.0.2.80节点上存在Pod:nginx-6f545cb57c-jmbrq,IP地址10.0.2.86。

xxx.10.0.1.233节点上存在Pod:nginx-6f545cb57c-25k9z,IP地址10.0.1.239。

image

Service是Nginx的Cluster IP,地址为192.168.254.141,External IP是10.0.2.90。

image

SLB相关配置

在SLB控制台,可以得到lb-xxx拟服务器组的后端服务器组是两个后端Nginx Pod的ENI eni-t4n5kzo5xxx和eni-t4naaozjxxx。

image

从集群外部角度看,SLB的后端虚拟服务器组是SVC的后端Pod所属的两个ENI网卡,内网的IP地址就是Pod的地址,没有经过后端Pod所在的ECS的OS层面,直接进入到了OS的协议栈。

小结

数据链路转发示意图:

image

数据链路:client -> SLB -> Pod ENI + Pod Port。