Terway IPVLAN+EBPF模式架构设计
弹性网卡(ENI)支持配置多个辅助IP的功能,单个弹性网卡(ENI)根据实例规格可以分配6-20个辅助IP,ENI多IP模式就是利用了这个辅助IP分配给容器,从而大幅提高了Pod部署的规模和密度。在网络联通的方式上,Terway支持选择veth pair策略路由和IPVLAN两种方案,Linux在4.2以上的内核中支持了IPVLAN的虚拟网络,可以实现单个网卡虚拟出来多个子网卡用不同的IP地址,而Terway便利用了这种虚拟网络类型,将弹性网卡的辅助IP绑定到IPVLAN的子网卡上来实现网络连通,使用这种模式使ENI多IP的网络结构足够简单,性能也相对veth策略路由较好。
Pod所使用的CIDR网段和节点的CIDR是同一个网段。
Pod内部可以得到是有一张网卡的,一个是eth0,其中eth0的IP就是Pod的IP,此网卡的MAC地址和控制台上的ENI的MAC地址不一致,同时ECS上有多张ethx的网卡,说明ENI附属网卡并不是直接挂载到了Pod的网络命名空间。
Pod内只有指向eth0的默认路由,说明Pod访问任何地址段都是从eth0为统一的出入口。
OS层面会给每个附属网卡创建一个ipvl_x的网卡,用于建立OS和Pod内的连接隧道。
通过OS Linux Routing,所有目的是Pod IP的流量都会被转发到Pod对应的ipvl_x虚拟往卡上。到这里为止,ECS OS和Pod的网络命名空间已经建立好完整的链路配置。
对于ENI多IP的实现,这个类似于ACK容器网络数据链路(Terway ENIIP)原理,Terway Pod是通过daemonset的方式部署在每个节点上的。通过terway-cli show factory
命令可以得到节点上的附属ENI数量、MAC地址以及每个ENI上的IP
对于Pod访问SVC,容器是利用各种办法将请求转发到Pod所在的ECS层面,由ECS内的netfilter模块来实现SVC IP的解析。但是由于数据链路需要从Pod的网络命名空间切换到ECS的OS的网络命名空间,中间经过了对此内核协议栈,必然会产生性能损失,如果对高并发和高性能有机制追求,可能并不完全满足客户的需求。在4.19版本内核中,利用eBPF特性,可以实现在tc层面对访问SVC IP的数据包进行调整。
例如集群内有一个名为nginx的svc,Cluster P是192.168.27.242,后端Pod IP是10.0.3.38。
通过cilium bpf lb list
可以得到在eBPF程序中对于Cluster P 192.168.27.242的访问会被转到10.0.3.38这个IP上,而Pod内只有一个默认路由。此处说明,IPVLAN+EBPF模式下,如果Pod访问SVC IP,SVC IP在Pod的网络命名空间内就会被eBPF转为某个SVC后端Pod的IP,之后数据链路被发出Pod。也就是说SVC IP只会在Pod内被捕获,在源端ECS,目的端Pod和目的端的Pod所在ECS都无法被捕获到。
假如一个SVC后段有100多个Pod,因为eBPF存在,Pod外无法捕获到SVC IP,所在一旦出现网络抖动,对于抓包该抓那个后端IP或该在哪个后端Pod抓包是个消耗极大的动作,建议使用ACK Net Exporter定位网络问题,可以针对此场景进行持续化的观测和问题诊断。
故Terway IPVLAN+EBPF模式总体可以归纳为:
4.2以上内核中支持了IPVLAN的虚拟网络,可以实现单个网卡虚拟出多个子网卡用不同的IP地址,而Terway便利用了这种虚拟网络类型,将弹性网卡的辅助IP绑定到IPVlAN的子网卡上来打通网络,使用这种模式使ENI多IP的网络结构足够简单,性能也相对veth策略路由较好。
节点访问Pod需要经过host的协议栈,Pod和Pod间访问不经过host的协议栈。
IPVLAN+EBPF模式下,如果Pod访问SVC IP,SVC IP在Pod的网络命名空间内就会被eBPF转为某个SVC后端Pod的IP,之后数据链路被发出Pod。也就是说SVC IP只会在Pod内被捕获,在源端ECS,目的端Pod和目的端的Pod所在ECS都无法被捕获到。
Terway IPVLAN+EBPF模式容器网络数据链路剖析
针对容器网络特点,可以将Terway IPVLAN+EBPF模式下的网络链路大体分为以Pod IP对外提供服务和以SVC对外提供服务两个大的SOP场景,进一步细分,可以归纳为15个不同的小的SOP场景。
对这15个场景的数据链路梳理合并,这些场景可以总结为下面11类典型的场景:
访问Pod IP,同节点访问Pod。
访问Pod IP,同节点Pod间互访(Pod属于同ENI)。
访问Pod IP,同节点Pod间互访(Pod属于不同ENI)。
不同节点间Pod之间互访。
集群内Pod访问的SVC Cluster IP(含Terway版本≥1.2.0,访问External IP),SVC后端Pod和客户端Pod配属同一个ENI。
集群内Pod访问的SVC Cluster IP(含Terway版本≥1.2.0,访问External IP),SVC后端Pod和客户端Pod配属不同ENI(同ECS)。
集群内Pod访问的SVC Cluster IP(含Terway版本≥1.2.0,访问External IP),SVC后端Pod和客户端Pod不属于不同ECS。
集群内Pod访问的SVC External IP(Terway版本≤1.2.0),SVC后端Pod和客户端Pod配属同一个ENI。
集群内Pod访问的SVC External IP(Terway版本≤1.2.0),SVC后端Pod和客户端Pod配属不同ENI(同ECS) 。
集群内Pod访问的SVC External IP(Terway版本≤1.2.0),SVC后端Pod和客户端Pod部署于不同ECS。
集群外访问SVC External IP。
场景一:访问Pod IP,同节点访问Pod
环境
xxx.10.0.3.15节点上存在nginx-7d6877d777-j7dqzI,P地址10.0.3.38。
内核路由
nginx-7d6877d777-j7dqz,IP地址10.0.3.38,该容器在宿主机中的PID是329470,容器网络命名空间有指向容器eth0的默认路由。
该容器eth0在ECS OS内是通过IPVLAN隧道的方式和ECS的附属ENI eth1建立的隧道,同时附属ENI eth1还有个虚拟的ipvl_8@eth1网卡。
通过OS Linux Routing可得到所有目的是Pod IP的流量都会被转发到Pod对应的ipvl_x虚拟网卡上,这样就建立完ECS和Pod之间的连接隧道。
小结
nginx-7d6877d777-zp5jg netns eth0可以抓到数据包。
ECS的ipvl_8可以抓到数据包。
数据链路转发示意图:
不会经过分配给Pod的附属网卡。
整个链路是通过查找路由表进入ipvl_xxx不需要经过ENI。
整个请求链路是node -> ipvl_xxx -> ECS1 Pod1。
场景二:访问Pod IP,同节点Pod间互访(Pod属于同ENI)
环境
xxx.10.0.3.15节点上存在nginx-7d6877d777-j7dqz和centos-6c48766848-znkl8两个Pod,IP地址分别为10.0.3.38和10.0.3.5。
通过此节点的terway Pod,利用terway-cli show factory
的命令得到这两个IP(10.0.3.5和10.0.3.38)都属于同一个MAC地址00:xx:xx:xx:xx:3,说明这两个IP属于同一个ENI,进而可以推断出nginx-7d6877d777-j7dqz和centos-6c48766848-znkl8都属于同一个ENI网卡。
内核路由
centos-6c48766848-znkl8,IP地址10.0.3.5,该容器在宿主机表现的PID是2747933,该容器网络命名空间有指向容器eth0的默认路由,有且只有一条,说明Pod访问所有地址都需要通过该默认路由。
nginx-7d6877d777-j7dqz,IP地址10.0.3.38,该容器在宿主机表现的PID是329470,该容器网络命名空间有指向容器eth0的默认路由。
该容器eth0在ECS OS内是通过IPVLAN隧道的方式和ECS的附属ENI eth1建立的隧道,同时附属ENI eth1还有个虚拟的ipvl_8@eth1网卡。
小结
centos-6c48766848-znkl8 netns eth0可以抓到数据包。
nginx-7d6877d777-zp5jg netns eth0可以抓到数据包。
ipvl_8网卡并没有捕获到相关的数据流量包。
数据链路转发示意图:
不会经过分配给Pod的附属网卡。
不会经过任何宿主机ECS的网络空间的中间节点。
整个链路不会经过Pod所分配的ENI,直接在OS的ns中命中IP rule被转发到对端Pod。
整个请求链路是ECS1 Pod1 -> ECS1 Pod2(发生在ECS内部),和IPVS相比,避免了calixx网卡设备的两次转发,性能更好。
场景三:访问Pod IP,同节点Pod间互访(Pod属于不同ENI)
环境
xxx.10.0.3.15节点上存在nginx-7d6877d777-j7dqz和busybox-d55494495-8t677两个Pod,IP地址分别为10.0.3.38和10.0.3.22。
此节点的terway Pod,利用terway-cli show factory
的命令得到这两个IP(10.0.3.22和10.0.3.38)都属于不同的MAC地址00:xx:xx:xx:xx:bd和00:xx:xx:xx:xx08:3a,说明这两个IP属于不同ENI,进而可以推断出nginx-7d6877d777-j7dqz和busybox-d55494495-8t677属于不同ENI网卡。
内核路由
busybox-d55494495-8t677,IP地址10.0.3.22,该容器在宿主机表现的PID是2956974,该容器网络命名空间有指向容器eth0的默认路由,有且只有一条,说明Pod访问所有地址都需要通过该默认路由。
nginx-7d6877d777-j7dqz,IP地址10.0.3.38,该容器在宿主机表现的PID是329470,该容器网络命名空间有指向容器eth0的默认路由。
该容器eth0在ECS OS内是通过IPVLAN隧道的方式和ECS的附属ENI eth1建立的隧道,通过MAC地址一样可以得到nginx-7d6877d777-j7dqz和busybox-d55494495-8t677分别被分配eth1和eth2。
小结
busybox-d55494495-8t677 netns eth0可以抓到数据包。
nginx-7d6877d777-zp5jg netns eth0可以抓到数据包。
数据链路转发示意图:
不会经过分配给Pod的附属网卡。
不会经过任何宿主机ECS的网络空间的中间节点。
整个链路是需要从客户端Pod所属的ENI网卡出ECS再从目的POD所属的ENI网卡进入ECS。
整个请求链路是ECS1 POD1 -> ECS1 eth1 -> VPC -> ECS1 eth2 -> ECS1 POD2。
场景四:不同节点间Pod之间互访
环境
xxx.10.0.3.15节点上存在nginx-7d6877d777-j7dqz,IP地址为10.0.3.38。
xxx.10.0.3.93节点上存在centos-6c48766848-dz8hz,IP地址为10.0.3.127。
通过此节点的terway Pod,可以利用terway-cli show factory
的命令得到nginx-7d6877d777-j7dqz的IP 10.0.3.5属于xxx.10.0.3.15上的MAC地址为00:xx:xx:xx:xx:3a的ENI网卡。
可以利用terway-cli show factory的命令得到centos-6c48766848-dz8hz的IP 10.0.3.127属于xxx.10.0.3.93上的MAC地址为00:xx:xx:xx:xx:f5的ENI网卡。
内核路由
centos-6c48766848-dz8hz,IP地址10.0.3.127,该容器在宿主机表现的PID是1720370,该容器网络命名空间有指向容器eth0的默认路由,有且只有一条,说明Pod访问所有地址都需要通过该默认路由。
nginx-7d6877d777-j7dqz,IP地址10.0.3.38,该容器在宿主机表现的PID是329470,该容器网络命名空间有指向容器eth0的默认路由。
ECS OS内是通过IPVLAN隧道的方式和ECS的附属ENI eth1建立的隧道,通过MAC地址一样可以得到两个Pod分配的ENI地址。
centos-6c48766848-dz8hz信息:
nginx-7d6877d777-j7dqz信息:
小结
此处不再对抓包进行展示,从客户端角度,数据流可以在centos-6c48766848-dz8hz的网络命名空间eth0,以及此Pod所部署的ECS对应的ENI eth1上可以被捕获到;从服务端角度,数据流可以在nginx-7d6877d777-j7dqz的网络命名空间eth0,以及此Pod所部署的ECS对应的ENI eth1上可以被捕获到。
数据链路转发示意图:
不会经过任何宿主机ECS的网络空间的中间节点。
整个链路是需要从客户端Pod所属的ENI网卡出ECS再从目的POD所属的ENI网卡进入ECS。
整个请求链路是ECS1 POD1 -> ECS1 ethx -> VPC -> ECS2 ethy -> ECS2 POD2。
场景五:集群内Pod访问的SVC Cluster IP(含Terway版本≥1.2.0,访问External IP),SVC后端Pod和客户端Pod配属同一个ENI
环境
xxx.10.0.3.15节点上存在nginx-7d6877d777-j7dqz和centos-6c48766848-znkl8两个Pod,IP地址为10.0.3.38和10.0.3.5。
通过此节点的terway Pod,可以利用terway-cli show factory
的命令得到这两个IP(10.0.3.5和10.0.3.38)都属于同一个MAC地址00:xx:xx:xx:xx:3a,说明这两个IP属于同一个ENI,进而可以推断出nginx-7d6877d777-j7dqz和centos-6c48766848-znkl8属于同一个ENI网卡。
通过describe svc
可以得到nginx Pod被加入到了svc nginx的后端。SVC的Cluster IP是192.168.27.242。如果是集群内访问External IP,对于Terway版本≥ 1.20,集群内访问SVC的Cluster IP或External IP,整个链路架构是一致的,此小节不再针对External IP单独说明,统一用Cluster IP作为示例。
内核路由
centos-6c48766848-znkl8,IP地址10.0.3.5,该容器在宿主机表现的PID是2747933,该容器网络命名空间有指向容器eth0的默认路由,有且只有一条,说明Pod访问所有地址都需要通过该默认路由。
nginx-7d6877d777-j7dqz,IP地址10.0.3.38,该容器在宿主机表现的PID是329470,该容器网络命名空间有指向容器eth0的默认路由。
在ACK中,是利用cilium去调用eBPF的能力,可以通过图示命令可以得到nginx-7d6877d777-j7dqz和centos-6c48766848-znkl8 identity ID分别是634和1592。
通过centos-6c48766848-znkl8 Pod,可以找到此Pod所在的ECS的Terway Pod为terway-eniip-6cfv9,在Terway Pod中运行cilium bpf lb list | grep -A5 192.168.27.242
命令可以得到eBPF中对于Cluster IP 192.168.27.242:80记录的后端是10.0.3.38:80。
如果集群内的Pod访问SVC的Cluster IP or External IP地址(Terway≥1.20),数据流会在Pod的网络命名空间内就被转化为相应的SVC的后端Pod IP后,再被从Pod网络命名空间的eth0发出Pod,进入到Pod所在的ECS,然后通过IPVLAN隧道,转发到同ECS或相应的ENI出ECS。也就是说,如果抓包或观测,不管在Pod内抓包还是在ECS抓包,都无法捕获到SVC的IP,只能捕获到Pod IP。
小结
从客户端Pod centos-6c48766848-znkl8访问SVC。
客户端的centos-6c48766848-znkl8网络命名空间内eth0抓包,抓包地址是目的SVC的IP和SVC的后端POD IP。可以得到只能抓到SVC后端Pod IP,无法捕获到SVC IP。
目的端SVC的后端POD nginx-7d6877d777-zp5jg网络命名空间eth抓包,抓包地址是目的SVC的IP和客户端POD IP。可以得到只能抓到客户端Pod IP。
cilium提供了一个monitor的功能,使用cilium monitor --related-to <endpoint ID>
,可以得到:源端POD IP访问SVC IP 192.168.27.242,之后被解析到SVC的后端POD IP 10.0.3.38,说明SVC IP直接在tc层做了转发。
后续小节如果涉及SVC IP的访问,如有类似,不再做详细的说明。
数据链路转发示意图:
不会经过任何宿主机ECS的网络空间的中间节点。
整个链路不会和请求不会经过Pod所分配的ENI,直接在OS的ns中命中IP rule被转发到对端Pod。
整个请求链路是ECS1 Pod1 -> ECS1 Pod2(发生在ECS内部),和IPVS相比,避免了calixx网卡设备的两次转发,性能是更好的。
ECS1 Pod1的eth0网卡无法捕捉到SVC IP,SVC IP在Pod网络命名空间内已经通过eBPF转换成了SVC后端Pod的IP。
场景六:集群内Pod访问的SVC Cluster IP(含Terway版本≥1.2.0,访问External IP),SVC后端Pod和客户端Pod配属不同ENI(同ECS)
环境
xxx.10.0.3.15节点上存在nginx-7d6877d777-j7dqz和busybox-d55494495-8t677两个Pod,IP地址分别为10.0.3.38和10.0.3.22。
通过此节点的terway Pod,可以用terway-cli show factory
的命令得到这两个IP(10.0.3.22和10.0.3.38)分别属于不同的MAC地址00:xx:xx:xx:xx:bd和00:xx:xx:xx:xx8:3a。说明这两个IP属于不同ENI,进而可以推断出nginx-7d6877d777-j7dqz和busybox-d55494495-8t677属于不同ENI网卡。
通过describe svc
可以得到nginx Pod被加入到了svc nginx的后端,SVC的Cluster IP是192.168.27.242。如果是集群内访问External IP,对于Terway版本≥1.20,集群内访问SVC的Cluster IP或External IP,整个链路架构是一致的,此小节不在针对External IP单独说明,统一用Cluster IP作为示例。
内核路由
busybox-d55494495-8t677,IP地址为10.0.3.22,该容器在宿主机表现的PID是2956974,该容器网络命名空间有指向容器eth0的默认路由,有且只有一条,说明Pod访问所有地址都需要通过该默认路由。
nginx-7d6877d777-j7dqz,IP地址10.0.3.38,该容器在宿主机表现的PID是329470,该容器网络命名空间有指向容器eth0的默认路由。
在ACK中,是利用cilium去调用eBPF的能力,可以通过下面的命令可以得到nginx-7d6877d777-j7dqz和busybox-d55494495-8t677的identity ID分别是634和3681。
通过busybox-d55494495-8t677 Pod,可以得到此Pod所在的ECS的Terway Pod为terway-eniip-6cfv9,在Terway Pod 中运行cilium bpf lb list | grep -A5 192.168.27.242
命令可以得到eBPF中对于Cluster IP 192.168.27.242:80记录的后端是10.0.3.38:80。
关于svc Cluster IP的eBPF转发详情,详情请见场景五:不同节点不同安全组Trunk Pod互访。从上述描述情况,可以得知被访问的SVC的IP 在客户端busybox的网络命名空间中已经被eBPF转为svc后端Pod的IP,在任何dev上都无法捕获到客户端访问的SVC的IP,故此场景和场景三:同节点不同安全组Trunk Pod互访(含访问SVC IP,源端和svc后端部署在同一节点)小节的网络架构非常类似。
小结
数据链路转发示意图:
不会经过任何宿主机ECS的网络空间的中间节点。
整个链路是需要从客户端Pod所属的ENI网卡出ECS再从目的POD所属的ENI网卡进入ECS。
整个请求链路是ECS1 POD1 -> ECS1 eth1 -> VPC -> ECS1 eth2 -> ECS1 POD2。
在客户端/服务端Pod内或者ECS的ENI网卡都无法捕捉到 SVC IP,SVC IP 在客户端 Pod 网络命名空间内已经通过eBPF转换成了SVC后端Pod的IP。
场景七:集群内Pod访问的SVC Cluster IP,SVC后端Pod和客户端Pod不属于不同ECS
环境
xxx.10.0.3.15节点上存在nginx-7d6877d777-j7dqz,IP地址为10.0.3.38。
xxx.10.0.3.93节点上存在centos-6c48766848-dz8hz,IP地址为10.0.3.127。
通过此节点的terway Pod,可以用terway-cli show factory
的命令得到nginx-7d6877d777-j7dqz的IP 10.0.3.5属于xxx.10.0.3.15上的MAC地址为00:xx:xx:xx:xx:3a的ENI网卡。
通过此节点的terway Pod,可以用terway-cli show factory
的命令得到centos-6c48766848-dz8hz的IP10.0.3.127属于xxx.10.0.3.93上的MAC地址为00:xx:xx:xx:xx:f5的ENI网卡。
通过describe svc
可以得到nginx Pod被加入到了svc nginx的后端,SVC的Cluster IP是192.168.27.242。如果是集群内访问External IP,对于Terway版本≥1.20,集群内访问SVC的Cluster IP或External IP,整个链路架构是一致的,此小节不在针对External IP单独说明,统一用Cluster IP作为示例。
内核路由
Pod访问SVC的Cluster IP,而SVC的后端Pod和客户端Pod部署在不同ECS上,此架构和场景四:不同节点同安全组Trunk Pod互访小节相似,只不过此场景是Pod访问SVC的Cluster IP。要注意此处是访问Cluster IP,如果是访问External IP,那么场景会更加复杂。本文的后面几个小节会详细说明。对于Cluster IP的eBPF转发进行描述,详情请见场景五:不同节点不同安全组Trunk Pod互访。
小结
数据链路转发示意图:
不会经过任何宿主机ECS的网络空间的中间节点。
整个链路是需要从客户端Pod所属的ENI网卡出ECS再从目的POD所属的ENI网卡进入ECS。
整个请求链路是ECS1 POD1 -> ECS1 eth1 -> VPC -> ECS2 eth1 -> ECS2 POD2。
在客户端/服务端Pod内或者ECS的ENI网卡都无法捕捉到SVC IP,SVC IP 在客户端Pod网络命名空间内已经通过eBPF转换成了SVC后端Pod的IP。
场景八:集群内Pod访问的SVC External IP(Terway版本≤1.2.0),SVC后端Pod和客户端Pod配属同一个ENI
环境
此场景和场景五:不同节点不同安全组Trunk Pod互访小节类似,只是此小节是在terway版本小于1.2.0情况下,访问External IP 47.xxx.xxx.183。
内核路由
由于客户端Pod和被访问的SVC的后端Pod同属于同一个ENI,那么在terway版本小于1.2.0的情况下,访问External IP,实际上数据链路会通过ENI出ECS到External IP的SLB,在被转发到同一个ENI上。四层SLB目前是不支持同一个ENI同时作为客户端和服务端,所以会形成回环,详细信息可以参考Terway IPVLAN模式和为什么无法访问负载均衡。
小结
数据链路转发示意图:
整个请求链路是ECS1 POD1 -> ECS1 eth1 -> VPC -> SLB -> 中断。
Terway版本小于1.2.0时,集群内访问External IP,会出ECS ENI到SLB,再由SLB转发到ECS ENI上,如果源Pod所属的ENI和被转发的ENI为同一个,将访问不成功,原因是四层SLB会形成回环。
解决方案(任何一个):
通过SVC annotation将SLB配置为7层监听
将Terway版本升级之1.2.0以及上,并开启集群内负载均衡。Kube-Proxy会短路集群内访问External IP、LoadBalancer的流量,即集群内访问这些外部地址,实际流量不会到外部,而会被转为对应后端的Endpoint直接访问。在Terway IPVLAN模式下,Pod访问这些地址流量由Cilium而不是kube-proxy进行处理,在Terway 1.2.0之前版本并不支持这种链路的短路。在Terway v1.2.0版本发布后,新建集群将默认开启该功能,已创建的集群不会开启(此处就是场景五:不同节点不同安全组Trunk Pod互访小节场景,请参考Terway和容器网络FAQ)。
场景九:集群内Pod访问的SVC External IP(Terway版本≤1.2.0),SVC后端Pod和客户端Pod配属不同ENI(同ECS)
环境
此场景类似场景六:集群内源端访问SVC IP(源端和SVC后端不同节点,相同安全组,含Local模式访问External IP,只是此小节是在terway版本小于1.2.0情况下,访问External IP 47.xx.xx.183。
内核路由
请参考场景六:集群内源端访问SVC IP(源端和SVC后端不同节点,相同安全组,含Local模式访问external IP)和场景八:Cluster模式下,集群内源端访问SVC External IP(源端和SVC后端不同节点,不同安全组)小节。
由于客户端Pod和被访问的SVC的后端Pod虽然同属于同一个ECS,但是不属于同一个ENI,那么在terway版本小于1.2.0的情况下,访问External IP,实际上数据链路会通过客户端Pod ENI出ECS到External IP的SLB,在被转发到另一个ENI上。虽然从外部感知上看两个客户端Pod和SVC的后端Pod都是在同一个ECS,但是由于属于不同ENI,所以不会形成回环,可以访问成功,此处的结果和场景八:Cluster模式下,集群内源端访问SVC External IP(源端和SVC后端不同节点,不同安全组)小节完全不同,需要注意。
小结
数据链路转发示意图:
整个请求链路是ECS1 POD1 -> ECS1 eth1 -> VPC -> SLB -> ECS1 eth2 -> ECS1 POD2。
Terway版本小于1.2.0时,集群内访问External IP,会出ECS ENI到SLB,再由SLB转发到ECS ENI上,如果源Pod所属的ENI和被转发的ENI为同一个,将访问不成功,原因是四层SLB会形成回环。
如果源Pod所属的ENI和被转发的ENI为是同一个节点上的不同ENI,可以访问成功。
场景十:集群内Pod访问的SVC External IP(Terway版本≤1.2.0),SVC后端Pod和客户端Pod部署于不同ECS
环境
此场景类似场景六:集群内源端访问SVC IP(源端和SVC后端不同节点,相同安全组,含Local模式访问External IP,只是此小节是在terway版本小于1.2.0情况下,访问External IP 47.xx.xx.183。
内核路由
请参考场景七:集群内源端访问SVC IP(源端和SVC后端不同节点,不同安全组,含Local模式访问External IP和场景九:Cluster模式下,集群内源端访问SVC External IP(源端和SVC后端不同节点,相同安全组)小节。
此处和场景七的架构场景相似,都是客户端Pod和SVC的后端Pod不属于不同的ECS节点,客户端去访问SVC的External IP。只有Terway的版本不同,场景七Terway版本是≥1.2.0,此小节是<1.2.0,仅仅是Terway版本和eni-config的不同,Terway版本<1.2.0会经过SLB,Terway版本>1.2.0则不会经过SLB。链路不同的原因是Terway 1.2.0版本之后开启集群内负载均衡,对于访问External IP会被负载到Service网段,详情请见场景八:Cluster模式下,集群内源端访问SVC External IP(源端和SVC后端不同节点,不同安全组)。
小结
数据链路转发示意图:
整个请求链路是ECS1 POD1 -> ECS1 eth1 -> VPC -> SLB -> ECS2 eth1 -> ECS2 POD2。
Terway版本小于1.2.0时,集群内访问External IP,会出ECS ENI到SLB,再由SLB转发到ECS ENI上,如果源Pod所属的ENI和被转发的ENI为同一个,将访问不成功,原因是四层SLB会形成回环。
场景十一:集群外访问SVC External IP
环境
xxx.10.0.3.15节点上存在nginx-7d6877d777-j7dqz,IP地址为10.0.3.34。
通过describe svc
可以得到nginx Pod被加入到了svc nginx的后端。SVC的Cluster IP是192.168.27.242。
内核路由
在SLB控制台,可以得到lb-j6cj07oi6uc705nxxx虚拟服务器组的后端服务器组是两个后端nginx Pod的ENI eni-j6cgs979ky3evxxx。
从集群外部角度看,SLB的后端虚拟服务器组是SVC的后端Pod所属的ENI网卡,内网的IP地址就是Pod的地址。
小结
数据链路转发示意图:
ExternalTrafficPolicy为Local或Cluster模式下,SLB只会将Pod分配的ENI挂在到SLB的虚拟服务器组。
数据链路:client -> SLB -> Pod ENI + Pod Port -> ECS1 Pod1 eth0。