全景剖析阿里云容器网络数据链路(三):Terway ENIIP
本系列文章由余凯执笔创作,联合作者:阿里云容器服务 谢石 对本文亦有贡献
前言
近几年,企业基础设施云原生化的趋势越来越强烈,从最开始的 IaaS 化到现在的微服务化,客户的颗粒度精细化和可观测性的需求更加强烈。容器网络为了满足客户更高性能和更高的密度,也一直在高速的发展和演进中,这必然对客户对云原生网络的可观测性带来了极高的门槛和挑战。为了提高云原生网络的可观测性,同时便于客户和前后线同学增加对业务链路的可读性,ACK 产研和 AES 联合共建,合作开发 ack net-exporter 和云原生网络数据面可观测性系列,帮助客户和前后线同学了解云原生网络架构体系,简化对云原生网络的可观测性的门槛,优化客户运维和售后同学处理疑难问题的体验 ,提高云原生网络的链路的稳定性。
鸟瞰容器网络,整个容器网络可以分为三个部分:Pod 网段,Service 网段和 Node 网段。这三个网络要实现互联互通和访问控制,那么实现的技术原理是什么?整个链路又是什么,限制又是什么呢?Flannel, Terway 有啥区别?不同模式下网络性能如何?这些,需要客户在下搭建容器之前,就要依据自己的业务场景进行选择,而搭建完毕后,相关的架构又是无法转变,所以客户需要对每种架构特点要有充分了解。比如下图是个简图,Pod 网络既要实现同一个 ECS 的 Pod 间的网络互通和控制,又要实现不同 ECS Pod 间的访问, Pod 访问 SVC 的后端可能在同一个 ECS 也可能是其他 ECS,这些在不同模式下,数据链转发模式是不同的,从业务侧表现结果也是不一样的。
本文是[全景剖析容器网络数据链路]第三部分,主要介绍 Kubernetes Terway ENIIP 模式下,数据面链路的转转发链路,一是通过了解不同场景下的数据面转发链路,从而探知客户在不同的场景下访问结果表现的原因,帮助客户进一步优化业务架构;另一方面,通过深入了解转发链路,从而在遇到容器网络抖动时候,客户运维以及阿里云同学可以知道在哪些链路点进行部署观测手动,从而进一步定界问题方向和原因。
系列一:
系列二:
全景剖析阿里云容器网络数据链路(二)—— Terway ENI
系列四:
全景剖析阿里云容器网络数据链路(四)—— Terway IPVLAN+EBPF
系列五:
全景剖析阿里云容器网络数据链路(五)—— Terway ENI-Trunking
系列六:
全景剖析阿里云容器网络数据链路(六)—— ASM Istio
Terway ENIIP 模式架构设计
弹性网卡 (ENI) 支持配置多个辅助 IP 的功能,单个弹性网卡 (ENI) 根据实例规格可以分配 6-20 个辅助 IP,ENI 多 IP 模式就是利用了这个辅助 IP 分配给容器,从而大幅提高了 Pod 部署的规模和密度。
在网络联通的方式上,Terway 支持选择 Veth pair 策略路由和 ipvlan l 两种方案,Terway 主要考虑了这些:
在节点上如何把弹性网卡 (ENI) 的辅助 IP 的流量都走对应的弹性网卡出去,并使用弹性网卡本身的 mac 地址而不被丢包
2.如何兼容容器服务目前广泛的 Centos 7.x 的 3.10 的版本的内核
Pod 所使用的的 CIDR 网段和节点的 CIDR 是同一个网段
Pod 内部可以看到是有一张网卡的,一个是 eth0,其中 eth0 的 IP 就是 Pod 的 IP,此网卡的 MAC 地址和控制台上的 ENI 的 MAC 地址不一致,同时 ECS 上有多张 ethx 的网卡,说明 ENI 附属网卡并不是直接挂在到了 Pod 的网络命名空间
Pod 内有只有指向 eth0 的默认路由,说明 Pod 访问任何地址段都是从 eth0 为统一的出入口
如上图所示,我们可以容器的网络命名空间中通过 ip addr 看到一个 eth0@if63 的标志位,其中 ‘63' 这个将会协助我们在 ECS 的 OS 内找到找到和容器网络命名空间中的 veth pair 相对一个。在 ECS OS 内我们通过 ip addr | grep 63: 可以找到 cali44ae9fbceeb 这个虚拟网卡,这个就是 veth pair 在 ECS OS 侧相对的那一个。
ECS OS 内对于数据流量是怎么判断去哪个容器呢?通过 OS Linux Routing 我们可以看到,所有目的是 Pod IP 的流量都会被转发到 Pod 对应的 calico 虚拟往卡上,到这里为止,ECS OS 和 Pod 的网络命名空间已经建立好完整的出入链路配置了。
在 veth pair 中实现了多个 Pod 共享一个 ENI 的方式来提升了 ECS 的 Pod 部署密度,那么如何知道 Pod 是被分配到哪个 ENI 呢?Terway Pod 是通过 daemonset 的方式部署在每个节点上的,通过下面命令可以看到每个节点上的 Terway Pod。通过 terway-cli show factory 命令可以看到节点上的附属 ENI 数量、MAC 地址以及每个 ENI 上的 IP
故 Terway ENIIP 模式总体可以归纳为:
在网络联通的方式上,采用选择 Veth pair 策略路由
一对 veth pair 来联通宿主机和 pod 的网络空间,pod 的地址是来源于弹性网卡的辅助 IP 地址,并且节点上需要配置策略路由来保证辅助 IP 的流量经过它所属的弹性网卡。
同主机上的容器通信直接通过主机上的路由到同一个主机上别的容器对应的 veth 上
不同主机的容器通信经过 VPC 的网络进行转发到对应的机器上,再通过机器上的路由转发到容器中
容器和其所在的宿主机之间的通信直接通过连接到宿主机 namespace 的 veth pair 和路由打通
容器到其他主机通过 VPC 的网络转发到对应的机器,其他主机到容器通过 VPC 网络转发到对应的弹性网卡,然后通过路由转发到容器的 Veth 上
容器到专线和共享服务也都是通过 VPC 的网络转发
容器到公网的访问经过 VSwitch 配置的 SNAT 网关直接将源 IP 转换成 EIP 的地址到外部网络
弹性网卡 (ENI) 支持配置多个辅助 IP 的功能,单个弹性网卡 (ENI) 根据实例规格可以分配 6-20 个辅助 IP,ENI 多 IP 模式就是利用了这个辅助 IP 分配给容器,从而大幅提高了 Pod 部署的规模和密度。
Terway ENIIP 模式容器网络数据链路剖析
针对容器网络特点,我们可以将 Terway ENI 模式下的网络链路大体分为以 Pod IP 对外提供服务和以 SVC 对外提供服务两个大的 SOP 场景,进一步细分,可以归纳为 7 个不同的小的 SOP 场景。
对这 8 个场景的数据链路梳理合并,这些场景可以归纳为下面 8 类典型的场景:
TerwayENI 架构下,不同的数据链路访问情况下,可以总结归纳为为 8 类:
访问 Pod IP, 同节点访问 Pod
访问 Pod IP/SVC IP(Cluster or Local),同节点 pod 间互访(pod 属于同 or 不同 ENI)
访问 PodIP ,异节点 pod 间互访
集群内非 SVC 后端 pod 所在节点访问 SVC ClusterIP
Cluster 模式,集群内非 SVC 后端 pod 所在节点访问 SVC External IP
Local 模式,集群内非 SVC 后端 pod 所在节点访问 SVC External IP
集群外访问 SVC External IP
场景一:访问 Pod IP,同节点访问 pod
环境
cn-hongkong.10.0.1.82 节点上存在 nginx-7d6877d777-zp5jg 和 10.0.1.104
内核路由
nginx-7d6877d777-zp5jg IP 地址 10.0.1.104 ,该容器在宿主机表现的 PID 是 1094736,该容器网络命名空间有指向容器 eth0 的默认路由
该容器 eth0 在 ECS OS 内对应 veth pair 是 calif03b26f9a43
在 ECS OS 内,有指向 Pod IP,下一跳为 calixxxx 的路由,通过前文可以知道 calixxx 网卡是和每个 pod 内的 veth1 组成的 pair,所以,pod 内访问 SVC 的 CIDR 会有指向 veth1 的路由,不会走默认的 eth0 路由。
故:calixx 网卡在这里的主要作用是用于:
节点访问 Pod
当节点或者 Pod 访问 SVC 的 CIDR 时,会走 ECS OS 内核协议栈转换,走到 calixxx 和 veth1 访问 pod。
小结:可以访问到目的端
nginx-7d6877d777-zp5jg netns eth0 可以抓到数据包
nginx-7d6877d777-zp5jg calif03b26f9a43 可以抓到数据包
数据链路转发示意图
会经过 calicao 网卡,每个非 hostnetwork 的 pod 会和 calicao 网卡形成 veth pair,用于和其他 pod 或 node 进行通信
整个链路不会和请求不会经过 pod 所分配的 ENI,直接在 OS 的 ns 中命中 Ip rule 被转发
整个请求链路是 OS -> calixxxxx -> ECS Pod net eth0
整个链路会经过两次内核协议栈:ECS OS 和 Pod
数据链路要经过两次内核协议栈,是 Pod1 协议栈、ECS1 协议栈
场景二:访问 Pod IP/SVC IP(Cluster or Local),同节点 pod 访问 pod(pod 属于同 or 不同 ENI)
环境
cn-hongkong.10.0.1.82 节点上存在 nginx-7d6877d777-zp5jg 和 10.0.1.104
cn-hongkong.10.0.1.82 节点上存在 centos-67756b6dc8-h5wnp 和 10.0.1.91
Service 是 nginx , ClusterIP 是 192.168.2.115 ExternalIP 是 10.0.3.62
内核路由
nginx-7d6877d777-zp5jg IP 地址 10.0.1.104 ,该容器在宿主机表现的 PID 是 1094736,该容器网络命名空间有指向容器 eth0 的默认路由
该容器 eth0 在 ECS OS 内对应 veth pair 是 calif03b26f9a43
用上述类似办法可以发现 centos-67756b6dc8-h5wnp 的 veth pair 的 cali44ae9fbceeb,Pod 网络空间只有默认路由。
在 ECS OS 内,有指向 Pod IP,下一跳为 calixxxx 的路由,通过前文可以知道 calixxx 网卡是和每个 pod 内的 veth1 组成的 pair,所以,pod 内访问 SVC 的 CIDR 会有指向 veth1 的路由,不会走默认的 eth0 路由。
故:calixx 网卡在这里的主要作用是用于:
节点访问 Pod
当节点或者 Pod 访问 SVC 的 CIDR 时,会走 ECS OS 内核协议栈转换,走到 calixxx 和 eth0 访问 pod。
说明相关的路由转发是在 ECS OS 层面进行的,Pod 的 calixx 网卡起到了一个桥梁和连通的作用。
源端 ECS 上的 IPVS 规则(如果访问的是 SVC IP)
如果同节点上访问的是 SVC 的 IP(ClusterIP or ExternalIP),在节点上我们查看 SVC 的相关 IPVS 转发规则:
Service 的 ExternalTrafficPolicy 是 Local
SVC nginx CLusterIP 是 192.168.2.115, ExternalIP 是 10.0.3.62, 后端是 10.0.1.104 和 10.0.3.58
cn-hongkong.10.0.1.82
对于 SVC 的 ClusterIP,可以看到 SVC 的后端两个 Pod 都会被加到 IPVS 的转发规则
对于 SVC 的 ExternalIP,可以看到 SVC 的后端,只有该节点的后端 Pod 10.0.1.104 才会被加到 IPVS 的转发规则
在 LoadBalancer 的 SVC 模式下,如果 ExternalTrafficPolicy 为 Local,对于 ClusterIP 来说,会把所有 SVC 后端 Pod 都会加到该节点的 IPVS 转发规则;对于 ExternalIP,只会把该节点上的 SVC 后端 Pod 才会加到 IPVS 规则中。如果该节点没有 SVC 后端 Pod,则该节点上的 Pod 访问 SVC 的 ExternalIP 将会是失败。
Service 的 ExternalTrafficPolicy 是 Cluster
SVC nginx1 CLusterIP 是 192.168.2.253, ExternalIP 是 10.0.3.63, 后端是 10.0.1.104 和 10.0.3.58
cn-hongkong.10.0.1.82
对于 SVC 的 ClusterIP,可以看到 SVC 的后端两个 Pod 都会被加到 IPVS 的转发规则
对于 SVC 的 ExternalIP,可以看到 SVC 的后端两个 Pod 都会被加到 IPVS 的转发规则
在 LoadBalancer 的 SVC 模式下,如果 ExternalTrafficPolicy 为 Cluster,对于 ClusterIP 或 ExternalIP 来说,会把所有 SVC 后端 Pod 都会加到该节点的 IPVS 转发规则。
小结:可以访问到目的端
Conntrack 表信息
Service nginx 的 ExternalTrafficPolicy 是 Local
SVC nginx CLusterIP 是 192.168.2.115, ExternalIP 是 10.0.3.62, 后端是 10.0.1.104 和 10.0.3.58
1.如果访问的是 SVC 的 ClusterIP,通过 conntrack 信息,可以看到 src 是源端 Pod 10.0.1.91 ,dst 是 SVC ClusterIP 192.168.2.115,dport 是 SVC 中的 port。并且期望是 10.0.1.104 来回包给 10.0.1.91 。
2.如果访问的是 SVC 的 ExternalIP,通过 conntrack 信息,可以看到 src 是源端 Pod 10.0.1.91 ,dst 是 SVC ExternalIP 10.0.3.62 ,dport 是 SVC 中的 port。并且期望是 10.0.1.104 来回包给 10.0.1.91 。
Service nginx1 的 ExternalTrafficPolicy 是 Cluster
SVC nginx1 CLusterIP 是 192.168.2.253, ExternalIP 是 10.0.3.63, 后端是 10.0.1.104 和 10.0.3.58
1.如果访问的是 SVC 的 ClusterIP,通过 conntrack 信息,可以看到 src 是源端 Pod 10.0.1.91 ,dst 是 SVC ClusterIP 192.168.2.253 ,dport 是 SVC 中的 port。并且期望是 10.0.1.104 来回包给 10.0.1.91 。
2.如果访问的是 SVC 的 ExternalIP,通过 conntrack 信息,可以看到 src 是源端 Pod 10.0.1.91 ,dst 是 SVC ExternalIP 10.0.3.63 ,dport 是 SVC 中的 port。并且期望是节点 ECS 的 IP 10.0.1.82 来回包给 10.0.1.91 。
综上可以看到 src 变换了多次,故在 Cluster 模式下,会存在丢失真实客户端 IP 的情况
数据链路转发示意图
会经过 calicao 网卡,每个非 hostnetwork 的 pod 会和 calicao 网卡形成 veth pair,用于和其他 pod 或 node 进行通信
整个链路不会和请求不会经过 pod 所分配的 ENI,直接在 OS 的 ns 中命中 Ip rule 被转发
整个请求链路是 ECS1 Pod1 eth0 -> Pod1 calixxxx -> Pod2 calixxxx -> ECS1 Pod2 eth0
访问 SVC IP, SVC 会在源端 pod eth0 和 calixxx 网卡捕捉到,在目的端 pod 的 eth0 和 calixxx 时捕捉不到
在 LoadBalancer 的 SVC 模式下,如果 ExternalTrafficPolicy 为 Local,对于 ClusterIP 来说,会把所有 SVC 后端 Pod 都会加到该节点的 IPVS 转发规则;对于 ExternalIP,只会把该节点上的 SVC 后端 Pod 才会加到 IPVS 规则中。
在 LoadBalancer 的 SVC 模式下,如果 ExternalTrafficPolicy 为 Cluster,对于 ClusterIP 或 ExternalIP 来说,会把所有 SVC 后端 Pod 都会加到该节点的 IPVS 转发规则,同时无法保留 src 地址。
数据链路要经过三次内核协议栈,是 Pod1 协议栈、ECS1 协议栈、Pod2 协议栈
场景三:访问 PodIP ,异节点 pod 间互访
环境
cn-hongkong.10.0.1.82 节点上存在 centos-67756b6dc8-h5wnp 和 10.0.1.91
cn-hongkong.10.0.3.49 节点上存在 nginx-7d6877d777-lwrfc 和 10.0.3.58
内核路由
centos-67756b6dc8-h5wnp IP 地址 10.0.1.104 ,该容器在宿主机表现的 PID 是 2211426,该容器网络命名空间有指向容器 eth0 的默认路由
用上述类似办法可以发现 centos-67756b6dc8-h5wnp 的 veth pair 的 cali44ae9fbceeb,Pod 网络空间只有默认路由。
在 ECS OS 内,有指向 Pod IP,下一跳为 calixxxx 的路由,通过前文可以知道 calixxx 网卡是和每个 pod 内的 veth1 组成的 pair,所以,pod 内访问 SVC 的 CIDR 会有指向 veth1 的路由,不会走默认的 eth0 路由。
故:calixx 网卡在这里的主要作用是用于:
节点访问 Pod
当节点或者 Pod 访问 SVC 的 CIDR 时,会走 ECS OS 内核协议栈转换,走到 calixxx 和 eth0 访问 pod,对于目的为外部地址,则走 Pod 所属的 ENI 出 ECS 进入到了 VPC。
小结:可以访问到目的端
数据链路转发示意图
会经过 calicao 网卡,每个非 hostnetwork 的 pod 会和 calicao 网卡形成 veth pair,用于和其他 pod 或 node 进行通信
整个链路请求会经过 pod 所分配的 ENI,直接在 OS 的 ns 中命中 Ip rule 被转发;
出 ECS 后,根据要访问的 pod 和该 pod ENI 所属 vswitch,命中 VPC 路由规则或者直接 VSW 上的二层转发;
整个请求链路是 ECS1 Pod1 eth0-> ECS1 Pod1 calixxxxx-> ECS1 ethx -> vpc route rule(如有) -> ECS2 ethx -> ECS2 Pod2 calixxxxx -> ECS2 Pod2 eth0
数据链路要经过四次内核协议栈,Pod1 协议栈、ECS1 协议栈、Pod2 协议栈、ECS2 协议栈
场景四:群内非 SVC 后端 pod 所在节点访问 SVC ClusterIP
环境
cn-hongkong.10.0.3.49 节点上存在 nginx-7d6877d777-h4jtf 和 10.0.3.58cn-hongkong.10.0.1.82 节点上存在 centos-67756b6dc8-h5wnp 和 10.0.1.91Service1 是 nginx , ClusterIP 是 192.168.2.115 ExternalIP 是 10.0.3.62
Service2 是 ngin1 , ClusterIP 是 192.168.2.253 ExternalIP 是 10.0.3.63
内核路由
内核路由部分已经在场景二和场景三小结中详细说明,这里不再进行过多阐述
源端 ECS 上的的 IPVS 规则
根据场景二小结中的源端 ECS 上的 IPVS 规则, 我们可以得到:无论在哪种 SVC 模式下,对于 ClusterIP 来说,会把所有 SVC 后端 Pod 都会加到该节点的 IPVS 转发规则
小结:可以访问到目的端
Conntrack 表信息
Service nginx 的 ExternalTrafficPolicy 是 Local
SVC nginx CLusterIP 是 192.168.2.115, ExternalIP 是 10.0.3.62, 后端是 10.0.1.104 和 10.0.3.58
cn-hongkong.10.0.1.82
源端 ECS 上 src 是源端 Pod 10.0.1.91 ,dst 是 SVC ClusterIP 192.168.2.115,dport 是 SVC 中的 port。并且期望是 10.0.3.58 来回包给 10.0.1.91 。
cn-hongkong.10.0.3.49
目的端 ECS 上 src 是源端 Pod 10.0.1.91 ,dst 是 pod 的 IP 10.0.3.58,dport 是 pod 的 port。并且期望此 pod 来回包给 10.0.1.91 。
Service nginx1 的 ExternalTrafficPolicy 是 Cluster
SVC nginx1 CLusterIP 是 192.168.2.253, ExternalIP 是 10.0.3.63, 后端是 10.0.1.104 和 10.0.3.58
cn-hongkong.10.0.1.82
源端 ECS 上 src 是源端 Pod 10.0.1.91 ,dst 是 SVC ClusterIP 192.168.2.115,dport 是 SVC 中的 port。并且期望是 10.0.3.58 来回包给 10.0.1.91 。
cn-hongkong.10.0.3.49
目的端 ECS 上 src 是源端 Pod 10.0.1.91 ,dst 是 pod 的 IP 10.0.3.58,dport 是 pod 的 port。并且期望此 pod 来回包给 10.0.1.91 。
对于 ClusterIP 来说,源端 ECS 会把所有 SVC 后端 Pod 都会加到该节点的 IPVS 转发规则,目的端 ECS 是捕获不到任何 SVC ClusterIP 信息的,只能捕获到源端 Pod 的 IP,所以回包的时候会回到源端 Pod 的附属网卡上。
数据链路转发示意图
会经过 calicao 网卡,每个非 hostnetwork 的 pod 会和 calicao 网卡形成 veth pair,用于和其他 pod 或 node 进行通信
整个链路请求会经过 pod 所分配的 ENI,直接在 OS 的 ns 中命中 Ip rule 被转发;
出 ECS 后,根据要访问的 pod 和该 pod ENI 所属 vswitch,命中 VPC 路由规则或者直接 VSW 上的二层转发;
整个请求链路是
去方向:
ECS1 Pod1 eth0 -> ECS1 Pod1 calixxxxxx -> ECS1 主网卡 eth0 -> vpc route rule(如有) -> ECS2 附属网卡 ethx -> ECS2 Pod2 calixxxxx -> ECS2 Pod2 eth0
回方向:
ECS2 Pod2 eth0 -> ECS2 Pod2 calixxxxx -> ECS2 附属网卡 ethx -> vpc route rule(如有) -> ECS1 附属网卡 eth1 -> ECS1 Pod1 calixxxxxx -> ECS1 Pod1 eth0
对于 ClusterIP 来说,源端 ECS 会把所有 SVC 后端 Pod 都会加到该节点的 IPVS 转发规则,目的端 ECS 是捕获不到任何 SVC ClusterIP 信息的,只能捕获到源端 Pod 的 IP,所以回包的时候会回到源端 Pod 的附属网卡上。
数据链路要经过四次内核协议栈,Pod1 协议栈、ECS1 协议栈、Pod2 协议栈、ECS2 协议栈
场景五:Cluster 模式,集群内非 SVC 后端 pod 所在节点访问 SVC External IP
环境
cn-hongkong.10.0.3.49 节点上存在 nginx-7d6877d777-h4jtf 和 10.0.3.58cn-hongkong.10.0.1.82 节点上存在 centos-67756b6dc8-h5wnp 和 10.0.1.91
Service2 是 ngin1 , ClusterIP 是 192.168.2.253 ExternalIP 是 10.0.3.63
内核路由
内核路由部分已经在场景二和场景三小结中详细说明,这里不再进行过多阐述
源端 ECS 上的的 IPVS 规则
根据场景二小结中的源端 ECS 上的 IPVS 规则, 我们可以得到:ExternalTrafficPolicy 为 Cluster 模式下,对于 ExternalIP 来说,会把所有 SVC 后端 Pod 都会加到该节点的 IPVS 转发规则
小结:可以访问到目的端
Conntrack 表信息
Service nginx1 的 ExternalTrafficPolicy 是 Cluster
SVC nginx1 CLusterIP 是 192.168.2.253, ExternalIP 是 10.0.3.63, 后端是 10.0.1.104 和 10.0.3.58
cn-hongkong.10.0.1.82
源端 ECS 上 src 是源端 Pod 10.0.1.91 ,dst 是 SVC ExternalIP 10.0.3.63,dport 是 SVC 中的 port。并且期望是 10.0.3.58 来回包给源端 ECS 的地址 10.0.1.82。
cn-hongkong.10.0.3.49
目的端 ECS 上 src 是源端 Pod 所在的 ECS 地址 10.0.1.82 ,dst 是 pod 的 IP 10.0.3.58,dport 是 pod 的 port。并且期望此 pod 来回包给源端 ECS 的地址 10.0.1.82。
在 ExternalTrafficPolicy 为 Cluster 下,对于 ExternalIP 来说,源端 ECS 会把所有 SVC 后端 Pod 都会加到该节点的 IPVS 转发规则,目的端 ECS 是捕获不到任何 SVC ExternalIP 信息的,只能捕获到源端 Pod 所在的 ECS 的 IP,所以回包的时候会回到源端 Pod 所在的 ECS 的主网卡上,这一点明显和场景四小结中访问 CusterIP 有很明显区别 。
数据链路转发示意图
会经过 calicao 网卡,每个非 hostnetwork 的 pod 会和 calicao 网卡形成 veth pair,用于和其他 pod 或 node 进行通信
整个链路请求会经过 pod 所分配的 ENI,直接在 OS 的 ns 中命中 Ip rule 被转发;
出 ECS 后,根据要访问的 pod 和该 pod ENI 所属 vswitch,命中 VPC 路由规则或者直接 VSW 上的二层转发;
整个请求链路是 ECS1 Pod1 eth0 -> ECS1 Pod1 calixxxx -> ECS1 主网卡 ENI eth0 -> vpc route rule(如有) -> ECS2 附属网卡 ethx -> ECS2 Pod2 calixxx -> ECS2 Pod2 eth0
在 ExternalTrafficPolicy 为 Cluster 下,对于 ExternalIP 来说,源端 ECS 会把所有 SVC 后端 Pod 都会加到该节点的 IPVS 转发规则,目的端 ECS 是捕获不到任何 SVC ExternalIP 信息的,只能捕获到源端 Pod 所在的 ECS 的 IP,所以回包的时候会回到源端 Pod 所在的 ECS 的主网卡 。
数据链路要经过四次内核协议栈,Pod1 协议栈、ECS1 协议栈、Pod2 协议栈、ECS2 协议栈
场景六:Local 模式,集群内非 SVC 后端 pod 所在节点访问 SVC External IP
环境
cn-hongkong.10.0.3.49 节点上存在 nginx-7d6877d777-h4jtf 和 10.0.3.58
cn-hongkong.10.0.1.82 节点上存在 centos-67756b6dc8-h5wnp 和 10.0.1.91
Service1 是 nginx , ClusterIP 是 192.168.2.115 ExternalIP 是 10.0.3.62
内核路由
内核路由部分已经在场景二和场景三小结中详细说明,这里不再进行过多阐述
源端 ECS 上的的 IPVS 规则
Service 的 ExternalTrafficPolicy 是 Local
SVC nginx CLusterIP 是 192.168.2.115, ExternalIP 是 10.0.3.62, 后端是 10.0.1.104 和 10.0.3.58
cn-hongkong.10.0.1.82
对于 SVC 的 ExternalIP,可以看到 SVC 的后端,无任何转发规则
根据场景二小结中的源端 ECS 上的 IPVS 规则, 我们可以得到:ExternalTrafficPolicy 为 Local 模式下,对于 ExternalIP 来说,只会把本节点上的 SVC 的后端 Pod 加到节点上的 IPVS 转发规则,如果该节点没有 SVC 后端,则不会有任何可以转发的规则。
小结:不可以访问到目的端
Conntrack 表信息
Service 的 ExternalTrafficPolicy 是 Local
SVC nginx1 CLusterIP 是 192.168.2.253, ExternalIP 是 10.0.3.63, 后端是 10.0.1.104 和 10.0.3.58
cn-hongkong.10.0.1.82 无任何 conntrack 记录表生成
数据链路转发示意图
会经过 calicao 网卡,每个非 hostnetwork 的 pod 会和 calicao 网卡形成 veth pair,用于和其他 pod 或 node 进行通信
整个链路请求不会经过 pod 所分配的 ENI,直接在 OS 的 ns 中命中 Ip rule 被转发;
整个请求链路是 ECS1 Pod1 eth0 -> ECS1 Pod1 calixxxx -> ECS host 空间 ipvs/iptables 规则,无后端转发 ep 终止链路。
ExternalTrafficPolicy 为 Local 模式下,对于 ExternalIP 来说,只会把本节点上的 SVC 的后端 Pod 加到节点上的 IPVS 转发规则,如果该节点没有 SVC 后端,则不会有任何可以转发的规则。
场景七:集群外访问 SVC External IP
环境
cn-hongkong.10.0.3.49 节点上存在 nginx-7d6877d777-h4jtf 和 10.0.3.58cn-hongkong.10.0.1.47 节点上存在 nginx-7d6877d777-kxwdb 和 10.0.1.29
Service1 是 nginx , ClusterIP 是 192.168.2.115 ExternalIP 是 10.0.3.62
SLB 相关配置
在 SLB 控制台,可以看到 lb-j6cw3daxxukxln8xccive 虚拟服务器组的后端服务器组是两个后端 nginx pod 的 ENI eni-j6c4qxbpnkg5o7uog5kr 和 eni-j6c6r7m3849fodxdf5l7
从集群外部角度看,SLB 的后端虚拟服务器组是 SVC 的后端 Pod 所属的两个 ENI 网卡,内网的 IP 地址就是 Pod 的地址
小结:可以访问到目的端
数据链路转发示意图
数据链路:client -> SLB -> Pod ENI + Pod Port -> ECS1 Pod1 eth0
数据链路要经过二次内核协议栈,Pod1 协议栈和 ECS 协议栈
总结
本篇文章主要聚焦 ACK 在 Terway ENIIP 模式下,不同 SOP 场景下的数据链路转发路径。伴随着客户对性能的极致追求的需求,在 Terway ENIIP 模式下,一共可以分为 7 个 SOP 场景,并对这七个场景的转发链路,技术实现原理,云产品配置等一一梳理并总结,这对我们遇到 Terway ENIIP 架构下的链路抖动、最优化配置,链路原理等提供了初步指引方向。在 Terway ENIIP 模式下,利用 veth pair 来联通宿主机和 pod 的网络空间,pod 的地址是来源于弹性网卡的辅助 IP 地址,并且节点上需要配置策略路由来保证辅助 IP 的流量经过它所属的弹性网卡,通过此种方式可以实现 ENI 多 Pod 共享,大大提升了 Pod 的部署密度,但是 veth pair 必然会利用 ECS 的内核协议栈进行转发,此架构下性能必然不如 ENI 模式,ACK 产研为了提升性能,结合内核的 ebpf 和 ipvlan 技术,开发了 Terway ebpf + ipvlan 架构。下一系列我们将进入到 Terway ENIIP 模式的全景解析——《ACK 全景剖析阿里云容器网络数据链路(四)—— Terway IPVLAN+EBPF》。
点击此处查看阿里云容器服务
版权声明: 本文为 InfoQ 作者【阿里巴巴云原生】的原创文章。
原文链接:【http://xie.infoq.cn/article/23e60dfd157012780a749f81a】。文章转载请联系作者。
评论