ACK容器网络Terway DataPath V2数据链路全景剖析

Terway DataPath V2模式架构设计

弹性网卡(ENI)支持配置多个辅助IP的功能,单个弹性网卡(ENI)根据实例规格可以分配6~20个辅助IP,ENIIP模式就是利用了这个辅助IP分配给容器,从而大幅提高了Pod部署的规模和密度。在网络联通的方式上,Terway目前支持veth pair策略路由和IPVLAN两种方案,但是社区在cilium v1.12版本后废弃了IPVLAN的支持,为了统一数据面一致性,将ACK的数据面演进和社区保持一致,便于云原生的能力集成,减少差异化。从v1.8.0开始,Terway不再支持IPvlan隧道加速,而采用DataPath V2的方式进行数据面的统一。

image

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

Pod内部有一张网卡eth0,其中eth0IP就是PodIP,此网卡的MAC地址和控制台上的ENIMAC地址不一致,同时ECS上有多张ethx的网卡,说明ENI附属网卡并不是直接挂载到了Pod的网络命名空间。image.pngimage.png

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

同时ECS上有多张ethx的网卡,说明ENI附属网卡并不是直接挂载到了Pod的网络命名空间。

image.png

通过OS Linux Routing可以得到,所有目的是Pod IP的流量都会被转发到Pod对应的calixx虚拟往卡上。因此,ECS OSPod的网络命名空间已经建立好完整的出入链路配置了。

image.png

对于ENIIP的实现,这个类似于ACK容器网络数据链路(Terway ENIIP)原理,Terway Pod是通过Daemonset的方式部署在每个节点上的。通过terway-cli mapping命令可以得到节点上的附属ENI数量、MAC地址以及每个ENI上的IP。

image.png

对于Pod访问SVC,容器是利用各种办法将请求转发到Pod所在的ECS层面,由ECS内的netfilter模块来实现SVC IP的解析。但是由于数据链路需要从Pod的网络命名空间切换到ECSOS的网络命名空间,中间经过了对此内核协议栈,必然会产生性能损失,如果对高并发和高性能有机制追求,可能并不完全满足客户的需求。相比较IPVLAN模式将eBPF部署在Pod内部用于SVC地址转换, DataPath V2模式的eBPF监听在每个Podcalixxx网卡上,用于实现PodPod访问的加速,以及Pod访问SVC IP的地址转后的链路加速,模式比较可以参考使用Terway网络插件

BPF Routing

5.10 内核以后,Cilium 新增了 eBPF Host-Routing 功能,新增了bpf_redirect_peerbpf_redirect_neigh两个redirect方式。

  • bpf_redirect_peer

数据包不经过宿主机的lxc接口,直接被送到veth pair Pod里面接口eth0上,实现数据包少进入一次cpu backlog queue队列,获得更好的转发性能。

  • bpf_redirect_neigh

用来填充pod egress流量的srcdst mac地址,流量无需经过kernelroute协议栈处理过程。

Terway DataPath V2模式总体可以归纳为:

  • 目前低版本内核(低于4.2)不支持eBPF加速,Aliyun2可获得部分加速能力,Aliyun3可获得完整的加速能力。

  • 节点访问Pod需要经过Host的协议栈,PodPod间访问以及Pod访问SVC不经过Host的协议栈。

  • DataPath V2模式下,如果Pod访问SVC IP,SVC IPPodveth pair calixxx网卡上被eBPF转为某个SVC后端PodIP,之后数据链路绕过Host协议栈。也就是说SVC IP只会在源端Podveth pair被捕获,目的端Pod和目的端的Pod所在ECS都无法被捕获到。

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

针对容器网络特点,可以将Terway DataPath V2模式下的网络链路大体分为以Pod IP对外提供服务和以SVC对外提供服务两个大的SOP场景,进一步细分,可以归纳为11个不同的小的SOP场景。

image.png

对这15个场景的数据链路进行梳理合并,这些场景可以总结为下面8类典型的场景:

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

  • 访问Pod IP,同节点Pod间互访(Pod属于同ENI)

  • 访问Pod IP,同节点Pod间互访(Pod属于不同ENI)

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

  • 集群内Pod访问的SVC Cluster IP/External IP,SVC后端Pod和客户端Pod属同ECSENI

  • 集群内Pod访问的SVC Cluster IP/External IP,SVC后端Pod和客户端Pod属同ECS不同ENI

  • 集群内Pod访问的SVC Cluster IP/External IP,SVC后端Pod和客户端Pod属于不同ECS

  • 集群外访问SVC External IP

场景一:访问Pod IP,同节点访问Pod(含节点访问后端为同一节点的SVC ClusterIP)

环境

xxx.10.0.1.219节点上存在nginx2-7ff4679659-xkpmm,IP地址10.0.0.2。image.png

内核路由

nginx2-7ff4679659-xkpmm,IP地址10.0.0.2,该容器在宿主机中的PID5630,容器网络命名空间有指向容器eth0的默认路由。image.pngimage.png

该容器eth0ECS OS 内对应veth paircali10e985649a0,在ECS OS内,有指向Pod IP,下一跳为calixxx的路由,通过前文可以知道calixxx网卡是和每个Pod内的veth1组成的pair。

image.png

image.png

通过下面的命令我们可以获取到nginx2-7ff4679659-xkpmm,IP地址10.0.0.2terway分配到了eth2附属网卡。

kubectl --kubeconfig kubeconfig -n kube-system exec -it terway-eniip-v5v2p -c terway -- terway-cli mapping

image.png

image.png

小结

ECSeth0捕获了从nginx2-7ff4679659-xkpmm返回的数据,但是没有捕获发送的数据。image.png

ECSeth1同样也捕获了从nginx2-7ff4679659-xkpmm返回的数据,但是没有捕获发送数据。

image.png

cali10e985649a0可以捕获发和收的数据包。

image.png

后续小结不再展示数据报文观测。

数据链路转发示意图(Aliyun2&Aliyun3):image

  • 整个链路是经过了ECSPod的网络协议栈。

  • 整个请求链路是:ECS OS -> calixxx -> ECS Pod eth0

场景二:访问Pod IP,同节点Pod间互访(Pod属于同ENI)

环境

xxx.10.0.1.219节点上存在nginx2-7ff4679659-xkpmm,IP地址10.0.0.2centos-5bf8644bcf-jqxpk,IP地址10.0.0.13。image.png

内核路由

centos-5bf8644bcf-jqxpk,IP地址10.0.0.13,该容器在宿主机中的PID126938,容器网络命名空间有指向容器eth0的默认路由。image.pngimage.png

该容器eth0ECS OS 内对应veth paircalia7003b8c36c,在ECS OS内,有指向Pod IP,下一跳为calixxx的路由,通过前文可以知道calixxx网卡是和每个Pod内的veth1组成的pair。

image.png

image.png

nginx2-7ff4679659-xkpmm,IP地址10.0.0.2,该容器在宿主机中的PID5630,容器网络命名空间有指向容器eth0的默认路由。image.pngimage.png

该容器eth0ECS OS 内对应veth paircali10e985649a0,在ECS OS内,有指向Pod IP,下一跳为calixxx的路由,通过前文可以知道calixxx网卡是和每个Pod内的veth1组成的pair。

image.png

通过下面的命令我们可以获取到nginx2-7ff4679659-xkpmmcentos-5bf8644bcf-jqxpk都被terway分配到了eth2同一张附属网卡。

kubectl --kubeconfig kubeconfig -n kube-system exec -it terway-eniip-v5v2p -c terway -- terway-cli mapping

image.png

image.png

小结

Aliyun2

image

  • 不会经过分配给Pod的附属网卡。

  • 整个链路是经过了Pod的网络协议栈,链路由Pod的网络命名空间转发到对端时候,会经过eBPF加速绕过OS协议栈。

  • 整个请求链路是:ECS Pod1 -> Pod1 calixxx -> Pod2 calixxx -> ECS Pod2。

Aliyun3

image

  • 不会经过分配给Pod的附属网卡。

  • 整个链路会在eBPFingress被直接加速到目的Pod内,不会经过目的Podcalixxx网卡。

  • 整个请求链路是:

    • 去方向:ECS Pod1 -> Pod1 calixxx -> ECS Pod2。

    • 回方向:ECS Pod2 -> Pod2 calixxx -> ECS Pod1。

场景三:访问Pod IP,同节点Pod间互访(Pod属于不同ENI)

环境

xxx.10.0.1.219节点上存在nginx3-55f5c67988-p4qnbcentos-5bf8644bcf-jqxpk两个Pod,IP地址分别为10.0.0.25110.0.0.13。

image.png

此节点的terway Pod,利用terway-cli mapping的命令得到这两个IP(10.0.0.25110.0.0.13)都属于不同的ENI网卡,在OS层面被认为是eth1eth2。

image.png

image.png

内核路由

centos-5bf8644bcf-jqxpk,IP地址10.0.0.13,该容器在宿主机中的PID126938,容器网络命名空间有指向容器eth0的默认路由。image.pngimage.png

该容器eth0ECS OS 内对应veth paircalia7003b8c36c,在ECS OS内,有指向Pod IP,下一跳为calixxx的路由,通过前文可以知道calixxx网卡是和每个Pod内的veth1组成的pair。

image.png

image.png

nginx3-55f5c67988-p4qnb,IP地址10.0.0.251,该容器在宿主机中的PID5630,容器网络命名空间有指向容器eth0的默认路由。image.pngimage.png

该容器eth0ECS OS 内对应veth paircali08203025d22,在ECS OS内,有指向Pod IP,下一跳为calixxx的路由,通过前文可以知道calixxx网卡是和每个Pod内的veth1组成的pair。

image.png

小结

Aliyun2

image

  • 不会经过分配给Pod的附属网卡。

  • 整个链路是经过了Pod的网络协议栈,链路由Pod的网络命名空间转发到对端时候,会经过eBPF加速绕过OS协议栈

  • 整个请求链路是:ECS Pod1 -> Pod1 calixxx -> Pod2 calixxx -> ECS Pod2。

Aliyun3

image

  • 不会经过分配给Pod的附属网卡。

  • 整个链路会在eBPFingress被直接加速到目的Pod内,不会经过目的Podcalixxx网卡。

  • 整个请求链路是:

    • 去方向:ECS Pod1 -> Pod1 calixxx -> ECS Pod2。

    • 回方向:ECS Pod2 -> Pod2 calixxx -> ECS Pod1。

场景四:访问Pod IP,不同节点间Pod之间互访

环境

xxx.10.0.1.219节点上存在centos-5bf8644bcf-jqxpk,IP地址为10.0.0.13。

xxx.10.0.5.27节点上存在nginx1-7bcf4ffdb4-6rsqz,IP地址为10.0.4.121。

image.png

可以利用terway-cli show factory的命令得到centos-5bf8644bcf-jqxpkIP 10.0.0.13属于xxx.10.0.1.219上的MAC地址为00:16:3e:0d:74:23ENI网卡。

image.png

同理可得nginx1-7bcf4ffdb4-6rsqzIP 10.0.4.121属于xxx.10.0.5.27上的MAC地址为00:16:3e:0c:ef:6cENI网卡。

内核路由

centos-5bf8644bcf-jqxpk,IP地址10.0.0.13,该容器在宿主机中的PID126938,容器网络命名空间有指向容器eth0的默认路由。image.pngimage.png

该容器eth0ECS OS内对应veth paircalia7003b8c36c,在ECS OS内有指向Pod IP,下一跳为calixxx的路由,通过前文可知calixxx网卡是和每个Pod内的veth1组成的pair。

image.png

image.png

nginx1-7bcf4ffdb4-6rsqz,IP地址10.0.4.121,该容器在宿主机中的PID7745,容器网络命名空间有指向容器eth0的默认路由。image.pngimage.png

该容器eth0ECS OS 内对应veth paircali06cd16bb25f,在ECS OS内,有指向Pod IP,下一跳为calixxx的路由,通过前文可以知道calixxx网卡是和每个Pod内的veth1组成的pair。

image.png

小结

Aliyun2

image

  • 会经过宿主机OS的网络命名空间,但协议栈链路会被eBPF加速。

  • 整个链路是需要从客户端Pod所属的ENI网卡出ECS再从目的Pod所属的ENI网卡进入ECS。

  • 整个请求链路是ECS1 Pod1 -> ECS1 Pod1 calixxx -> ECS1 ENI ethx -> VPC -> ECS2 ENI ethx -> ECS2 Pod2 calixxx -> ECS2 Pod2。

Aliyun3

image

  • 整个链路是需要从客户端Pod所属的ENI网卡出发,再经过ECS再从目的Pod所属的ENI网卡进入ECS。

  • 整个请求链路是:

    • 去方向:ECS1 Pod1 -> ECS1 Pod1 calixxx -> ECS1 ENI ethx -> VPC -> ECS2 ENI ethx -> ECS2 Pod2。

    • 回方向:ECS2 Pod2 -> ECS2 Pod2 calixxx -> ECS2 ENI ethx -> VPC -> ECS1 ENI ethx -> ECS1 Pod1。

场景五:集群内Pod访问的SVC Cluster IP/External IP,SVC后端Pod和客户端Pod属同ECSENI

环境

xxx.10.0.1.219节点上存在nginx2-7ff4679659-xkpmm,IP地址10.0.0.2centos-5bf8644bcf-jqxpk,IP地址10.0.0.13image.png

其中nginx2-7ff4679659-xkpmm PodSVC nginx2endpoint。

image.png

内核路由

内核路由类似场景二:访问Pod IP,同节点Pod间互访(Pod属于同ENI)

关于eBPF,在DataPath V2中,eBPF监听在OS层面的calixxx网卡上,而非Pod内部。利用cilium去调用eBPF的能力,可以通过图示命令可以得到centos-5bf8644bcf-jqxpknginx2-7ff4679659-xkpmm identity ID分别是6932702。image.png

找到Pod所在的ECSTerway Podterway-eniip-v5v2p,在Terway Pod中运行cilium bpf lb list | grep -A5 192.168.152.119命令可以得到eBPF中对于Cluster IP 192.168.152.119:80记录的后端是10.0.0.2:80。image.png

小结

从客户端Pod centos-5bf8644bcf-jqxpk访问SVC。image.png

客户端的centos-6c48766848-znkl8calia7003b8c36c网卡观测,可以捕获SVCIP和客户端的Pod IP。image.png

在这个Pod centos-6c48766848-znkl8所属的附属网卡ENI上观测,未能捕获任何相关流量报文,说明流量从客户端的所属的calixx网卡到ENI之间经过了eBPF转换。

Pod nginx2-7ff4679659-xkpmmIcali10e985649a0观测,只能捕获centosnginxPod IP。image.png

cilium提供了一个monitor的功能,使用cilium monitor --related-to <endpoint ID>,可以得到:源端Pod IP访问SVC IP 192.168.152.119,之后被解析到SVC的后端Pod IP 10.0.0.2,说明SVC IP直接在tc层做了转发。image.png

Aliyun2image

  • 整个链路是经过了Pod的网络协议栈,链路由Pod的网络命名空间转发到对端时候,会经过eBPF加速绕过OS协议栈。

  • 整个链路请求未经过Pod所分配的ENI。

  • SVC IP在客户端Podcalixxx网卡通过eBPF转换成了SVC后端PodIP,后续节点无法捕获SVC IP。

  • 整个请求链路是:ECS Pod1 -> Pod1 calixxx -> Pod2 calixxx -> ECS Pod2。

Aliyun3

image

  • 整个链路是经过了Pod的网络协议栈,链路由Pod的网络命名空间转发到对端时候,会经过eBPF加速绕过OS协议栈。

  • 整个链路请求未经过Pod所分配的ENI。

  • SVC IP在客户端Podcalixxx网卡通过eBPF转换成了SVC后端PodIP,后续节点无法捕获SVC IP。

  • 整个链路会在eBPFingress被直接加速到目的Pod内,不会经过目的Podcalixxx网卡。

  • 整个请求链路是:

    • 去方向:ECS Pod1 -> Pod1 calixxx -> ECS Pod2。

    • 回方向:ECS Pod2 -> Pod2 calixxx -> ECS Pod1。

场景六:集群内Pod访问的SVC Cluster IP/External IP,SVC后端Pod和客户端Pod属同ECS不同ENI

环境

xxx.10.0.1.219节点上存在nginx3-55f5c67988-p4qnb,IP地址10.0.0.251centos-5bf8644bcf-jqxpk,IP地址10.0.0.13。

image.png

其中nginx3-55f5c67988-p4qnb PodSVC nginx3endpoint。image.png

内核路由

内核路由类似场景三:访问Pod IP,同节点Pod间互访(Pod属于不同ENI),此处不再叙述。

关于eBPF,在DataPath V2中,eBPF监听在OS层面的calixxx网卡上,而非Pod内部。利用cilium去调用eBPF的能力,可以通过图示命令可以得到centos-5bf8644bcf-jqxpknginx3-55f5c67988-p4qnb identity ID分别是69394。image.png

找到Pod所在的ECSTerway Podterway-eniip-v5v2p,在Terway Pod中运行cilium bpf lb list | grep -A5 192.168.239.183命令可以得到eBPF中对于Cluster IP 192.168.239.183:80记录的后端是10.0.0.2:80。image.png

小结

从客户端Pod centos-5bf8644bcf-jqxpk访问SVC。image.png

客户端的centos-6c48766848-znkl8calia7003b8c36c网卡观测,可以捕获SVCIP和客户端的Pod IP。

image.png

Pod centos-6c48766848-znkl8所属的附属网卡ENInginx3-55f5c67988-p4qnb所属的附属网卡ENI上观测,未能捕获到相关流量,说明流量从客户端的所属的calixx网卡上被eBPF转换成SVC相关的endpoint后直接被短路到目的calixxx网卡。

Pod nginx3-55f5c67988-p4qnb所属的cali08203025d22观测,只能捕获centosnginxPod IP。

image.png

cilium提供了一个monitor的功能,使用cilium monitor --related-to <endpoint ID>,可得源端Pod IP访问SVC IP 192.168.239.183,之后被解析到SVC的后端Pod IP 10.0.0.251,说明SVC IP直接在tc层做了转发。

image.png

后续小节如涉及SVC IP的访问,有类似场景不再详细说明。

Aliyun2image

  • 会经过宿主机OS的网络命名空间,但协议栈链路会被eBPF加速。

  • 整个链路请求未经过Pod所分配的ENI。

  • SVC IP在客户端Podcalixxx网卡通过eBPF转换成了SVC后端PodIP,后续节点无法捕获SVC IP。

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

Aliyun3

image

  • 不会经过分配给Pod的附属网卡。

  • 整个链路会在eBPFingress被直接加速到目的Pod内,不会经过目的Podcalixxx网卡。

  • SVC IP在客户端Podcalixxx网卡通过eBPF转换成了SVC后端PodIP,后续节点无法捕获SVC IP。

  • 整个请求链路是:

    • 去方向:ECS Pod1 -> Pod1 calixxx -> ECS Pod2。

    • 回方向:ECS Pod2 -> Pod2 calixxx -> ECS Pod1。

场景七:集群内Pod访问的SVC Cluster IP/External IP,SVC后端Pod和客户端Pod属于不同ECS

环境

xxx.10.0.1.219节点上存在centos-5bf8644bcf-jqxpk,IP地址为10.0.0.13。

xxx.10.0.5.27节点上存在nginx1-7bcf4ffdb4-6rsqz,IP地址为10.0.4.121。

image.png

其中nginx1-7bcf4ffdb4-6rsqz PodSVC nginx1endpoint。

image.png

内核路由

Pod访问SVCCluster IP,而SVC的后端Pod和客户端Pod部署在不同ECS上,此架构和场景四:访问Pod IP,不同节点间Pod之间互访小节相似,只不过此场景是Pod访问SVCCluster IPExternal IP。对于SVCeBPF转发请参考场景五:集群内Pod访问的SVC Cluster IP/External IP,SVC后端Pod和客户端Pod属同ECSENI

小结

Aliyun2

image

  • 会经过宿主机OS的网络命名空间,但协议栈链路会被eBPF加速。

  • 整个链路是需要从客户端Pod所属的ENI网卡出ECS再从目的Pod所属的ENI网卡进入ECS。

  • 整个请求链路是ECS1 Pod1 -> ECS1 Pod1 calixxx -> ECS1 ENI ethx -> VPC -> ECS2 ENI ethx -> ECS2 Pod2 calixxx -> ECS2 Pod2。

Aliyun3

image

  • 整个链路是需要从客户端Pod所属的ENI网卡出发,再经过ECS再从目的Pod所属的ENI网卡进入ECS。

  • 整个请求链路是:

    • 去方向:ECS1 Pod1 -> ECS1 Pod1 calixxx -> ECS1 ENI ethx -> VPC -> ECS2 ENI ethx -> ECS2 Pod2。

    • 回方向:ECS2 Pod2 -> ECS2 Pod2 calixxx -> ECS2 ENI ethx -> VPC -> ECS1 ENI ethx -> ECS1 Pod1。

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

环境

xxx.10.0.5.27 节点上存在nginx1-7bcf4ffdb4-6rsqz,IP地址为10.0.4.121。image.png

通过describe svc可以得到nginx Pod被加入到了svc nginx的后端。SVCCluster IP192.168.190.78。image.png

内核路由

SLB控制台,可以得到lb-3nsj50u4gyz623nitxxx虚拟服务器组的后端服务器组是两个后端nginx PodENI eni-j6cgs979ky3evxxx。

image

从集群外部角度看,SLB的后端虚拟服务器组是SVC的后端Pod所属的ENI网卡,内网的IP地址就是Pod的地址。

小结

Aliyun2image

  • ExternalTrafficPolicyLocalCluster模式下,SLB只会将Pod分配的ENI挂载到SLB的虚拟服务器组。

  • 数据链路会经过PodVethcalixxx网卡

  • 数据链路:Client -> SLB -> Pod ENI + Pod Port -> ECS1 Pod1 calixxx -> ECS1 Pod1 eth0。

Aliyun3

image

  • ExternalTrafficPolicyLocalCluster模式下,SLB只会将Pod分配的ENI挂载到SLB的虚拟服务器组。

  • 数据链路会被ECS的附属网卡上eBPF加速绕过PodVethcalixxx网卡,直接进到Pod的网络命名空间。

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