全景剖析阿里云容器网络数据链路(三):Terway ENIIP

简介: 本篇文章主要聚焦 ACK 在 Terway ENIIP 模式下,不同 SOP 场景下的数据链路转发路径。伴随着客户对性能的极致追求的需求,在 Terway ENIIP 模式下,一共可以分为 7 个 SOP 场景,并对这七个场景的转发链路,技术实现原理,云产品配置等一一梳理并总结,这对我们遇到 Terway ENIIP 架构下的链路抖动、最优化配置,链路原理等提供了初步指引方向

本系列文章由余凯执笔创作,联合作者:阿里云容器服务 谢石 对本文亦有贡献


前言


近几年,企业基础设施云原生化的趋势越来越强烈,从最开始的 IaaS 化到现在的微服务化,客户的颗粒度精细化和可观测性的需求更加强烈。容器网络为了满足客户更高性能和更高的密度,也一直在高速的发展和演进中,这必然对客户对云原生网络的可观测性带来了极高的门槛和挑战。为了提高云原生网络的可观测性,同时便于客户和前后线同学增加对业务链路的可读性,ACK 产研和 AES 联合共建,合作开发 ack net-exporter 和云原生网络数据面可观测性系列,帮助客户和前后线同学了解云原生网络架构体系,简化对云原生网络的可观测性的门槛,优化客户运维和售后同学处理疑难问题的体验 ,提高云原生网络的链路的稳定性。


鸟瞰容器网络,整个容器网络可以分为三个部分:Pod 网段,Service 网段和Node 网段。这三个网络要实现互联互通和访问控制,那么实现的技术原理是什么?整个链路又是什么,限制又是什么呢?Flannel, Terway 有啥区别?不同模式下网络性能如何?这些,需要客户在下搭建容器之前,就要依据自己的业务场景进行选择,而搭建完毕后,相关的架构又是无法转变,所以客户需要对每种架构特点要有充分了解。比如下图是个简图,Pod 网络既要实现同一个 ECS 的 Pod 间的网络互通和控制,又要实现不同 ECS Pod 间的访问, Pod 访问 SVC 的后端可能在同一个ECS 也可能是其他 ECS,这些在不同模式下,数据链转发模式是不同的,从业务侧表现结果也是不一样的。


1.png


本文是[全景剖析容器网络数据链路]第三部分,主要介绍 Kubernetes Terway ENIIP 模式下,数据面链路的转转发链路,一是通过了解不同场景下的数据面转发链路,从而探知客户在不同的场景下访问结果表现的原因,帮助客户进一步优化业务架构;另一方面,通过深入了解转发链路,从而在遇到容器网络抖动时候,客户运维以及阿里云同学可以知道在哪些链路点进行部署观测手动,从而进一步定界问题方向和原因。


系列一:

全景剖析阿里云容器网络数据链路(一)—— Flannel


系列二:

全景剖析阿里云容器网络数据链路(二)—— 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 主要考虑了这些:


1. 在节点上如何把弹性网卡 (ENI) 的辅助 IP 的流量都走对应的弹性网卡出去,并使用弹性网卡本身的 mac 地址而不被丢包

2.如何兼容容器服务目前广泛的 Centos 7.x 的 3.10 的版本的内核


2.png


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


3.png


Pod 内部可以看到是有一张网卡的,一个是 eth0,其中 eth0 的 IP 就是 Pod 的 IP,此网卡的 MAC 地址和控制台上的 ENI 的 MAC 地址不一致,同时 ECS 上有多张 ethx 的网卡,说明 ENI 附属网卡并不是直接挂在到了 Pod 的网络命名空间


4.png5.png6.png


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


7.png


如上图所示,我们可以容器的网络命名空间中通过 ip addr 看到一个 eth0@if63 的标志位,其中 ‘63' 这个将会协助我们在 ECS 的 OS 内找到找到和容器网络命名空间中的veth pair 相对一个。在 ECS OS 内我们通过 ip addr | grep 63: 可以找到 cali44ae9fbceeb 这个虚拟网卡,这个就是 veth pair 在 ECS OS 侧相对的那一个。


8.png


ECS OS 内对于数据流量是怎么判断去哪个容器呢?通过 OS Linux Routing 我们可以看到,所有目的是 Pod  IP 的流量都会被转发到 Pod 对应的 calico 虚拟往卡上,到这里为止,ECS OS 和 Pod 的网络命名空间已经建立好完整的出入链路配置了。


9.png


在 veth pair 中实现了多个 Pod 共享一个 ENI 的方式来提升了 ECS 的 Pod 部署密度,那么如何知道 Pod 是被分配到哪个 ENI 呢?Terway Pod 是通过 daemonset 的方式部署在每个节点上的,通过下面命令可以看到每个节点上的 Terway Pod。通过 terway-cli show factory 命令可以看到节点上的附属 ENI 数量、MAC 地址以及每个 ENI 上的 IP


10.png11.png


故 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 场景。


12.png


对这 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


环境


13.png


cn-hongkong.10.0.1.82  节点上存在 nginx-7d6877d777-zp5jg 和 10.0.1.104


内核路由


nginx-7d6877d777-zp5jg IP地址 10.0.1.104  ,该容器在宿主机表现的 PID 是1094736,该容器网络命名空间有指向容器 eth0 的默认路由


14.png15.png


该容器 eth0 在 ECS OS 内对应 veth pair 是 calif03b26f9a43


16.png


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


故:calixx 网卡在这里的主要作用是用于:


1. 节点访问 Pod

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


17.png


小结:可以访问到目的端


nginx-7d6877d777-zp5jg   netns  eth0   可以抓到数据包


18.png


nginx-7d6877d777-zp5jg    calif03b26f9a43  可以抓到数据包


19.png20.png

数据链路转发示意图


  • 会经过 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)


环境


21.png22.png


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 的默认路由


23.png24.png


该容器 eth0 在 ECS OS 内对应 veth pair 是 calif03b26f9a43


25.png


用上述类似办法可以发现 centos-67756b6dc8-h5wnp 的 veth pair的 cali44ae9fbceeb,Pod 网络空间只有默认路由。


26.png27.png


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


故:calixx 网卡在这里的主要作用是用于:


1. 节点访问 Pod

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


28.png


说明相关的路由转发是在 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


29.png


cn-hongkong.10.0.1.82


对于 SVC 的 ClusterIP,可以看到 SVC 的后端两个 Pod 都会被加到 IPVS 的转发规则


30.png


对于 SVC 的 ExternalIP,可以看到 SVC 的后端,只有该节点的后端 Pod 10.0.1.104才会被加到 IPVS 的转发规则


31.png


在 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


32.png


cn-hongkong.10.0.1.82


对于 SVC 的 ClusterIP,可以看到 SVC 的后端两个 Pod 都会被加到 IPVS 的转发规则


33.png


对于 SVC 的 ExternalIP,可以看到 SVC 的后端两个 Pod 都会被加到 IPVS 的转发规则


34.png


在 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  。


35.png


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  。


36.png


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  。


37.png


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  。


38.png


综上可以看到 src 变换了多次,故在 Cluster 模式下,会存在丢失真实客户端IP的情况


39.png

数据链路转发示意图


  • 会经过 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 间互访


环境


40.png


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 网络空间只有默认路由。


41.png42.png


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


故:calixx 网卡在这里的主要作用是用于:


1. 节点访问 Pod

2. 当节点或者 Pod 访问 SVC 的 CIDR 时,会走 ECS OS 内核协议栈转换,走到 calixxx和 eth0 访问 pod,对于目的为外部地址,则走 Pod 所属的 ENI 出 ECS 进入到了 VPC。


43.png


小结:可以访问到目的端


44.png

数据链路转发示意图


  • 会经过 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


环境


45.png46.png47.png


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


48.png


源端 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


49.png


目的端 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


50.png


源端 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


51.png


目的端 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 的附属网卡上。


52.png

数据链路转发示意图


  • 会经过 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


环境


53.png54.png


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


55.png


源端 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


56.png


目的端 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 有很明显区别 。


57.png

数据链路转发示意图


  • 会经过 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


环境


58.png59.png


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


60.png


cn-hongkong.10.0.1.82


对于 SVC 的 ExternalIP,可以看到 SVC 的后端,无任何转发规则


61.png


根据场景二小结中的源端 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 记录表生成


62.png63.png

数据链路转发示意图


  • 会经过 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


环境


64.png65.png


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


66.png


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


小结:可以访问到目的端


67.png

数据链路转发示意图


  • 数据链路: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》。


点击此处查看阿里云容器服务

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
10月前
|
存储 Kubernetes 网络安全
关于阿里云 Kubernetes 容器服务(ACK)添加镜像仓库的快速说明
本文介绍了在中国大陆地区因网络限制无法正常拉取 Docker 镜像的解决方案。作者所在的阿里云 Kubernetes 集群使用的是较旧版本的 containerd(1.2x),且无法直接通过 SSH 修改节点配置,因此采用了一种无需更改 Kubernetes 配置文件的方法。通过为 `docker.io` 添加 containerd 的镜像源,并使用脚本自动修改 containerd 配置文件中的路径错误(将错误的 `cert.d` 改为 `certs.d`),最终实现了通过多个镜像站点拉取镜像。作者还提供了一个可重复运行的脚本,用于动态配置镜像源。虽然该方案能缓解镜像拉取问题,
1011 3
|
Docker 容器
Docker网关冲突导致容器启动网络异常解决方案
当执行`docker-compose up`命令时,服务器网络可能因Docker创建新网桥导致IP段冲突而中断。原因是Docker默认的docker0网卡(172.17.0.1/16)与宿主机网络地址段重叠,引发路由异常。解决方法为修改docker0地址段,通过配置`/etc/docker/daemon.json`调整为非冲突段(如192.168.200.1/24),并重启服务。同时,在`docker-compose.yml`中指定网络模式为`bridge`,最后通过检查docker0地址、网络接口列表及测试容器启动验证修复效果。
1880 39
|
12月前
|
存储 Linux 容器
【Container App】在容器中抓取网络包的方法
本文介绍在Azure Container App中安装tcpdump抓取网络包,并通过Storage Account上传抓包文件的方法。内容包括使用curl和nc测试外部接口连通性、长Ping端口、安装tcpdump、抓取网络包、以及通过crul命令上传文件至Azure Storage。适用于需要分析网络请求和排查网络问题的场景。
331 0
|
网络协议 Docker 容器
使用网络--容器互联
使用网络--容器互联
266 18
|
Kubernetes Cloud Native 区块链
Arista cEOS 4.30.10M - 针对云原生环境设计的容器化网络操作系统
Arista cEOS 4.30.10M - 针对云原生环境设计的容器化网络操作系统
449 0
|
安全 持续交付 云计算
课时5:阿里云容器服务:最原生的集成Docker和云服务
阿里云容器服务以服务化形式构建容器基础设施,大幅提升开发效率,简化应用部署流程。通过Docker容器和DevOps工具(如Jenkins),实现自动化部署与迭代,优化企业内部复杂部署问题。该服务支持GPU调度、混合云架构无缝迁移,并与阿里云产品体系无缝集成,提供安全防护、网络负载均衡等多重功能支持。凭借微服务架构,帮助企业突破业务瓶颈,提高资源利用率,轻松应对海量流量。
524 0
课时5:阿里云容器服务:最原生的集成Docker和云服务
|
人工智能 Kubernetes Serverless
阿里云向全球客户推出创新容器计算服务ACS,可降低算力成本高达55%
阿里云向全球客户推出创新容器计算服务ACS,可降低算力成本高达55%
|
弹性计算 监控 持续交付
面对热点事件,阿里云如何通过云上弹性与容器服务帮助客户应对流量洪峰
面对热点事件,阿里云如何通过云上弹性与容器服务帮助客户应对流量洪峰
441 0
|
监控 Cloud Native Java
基于阿里云容器服务(ACK)的微服务架构设计与实践
本文介绍如何利用阿里云容器服务Kubernetes版(ACK)构建高可用、可扩展的微服务架构。通过电商平台案例,展示基于Java(Spring Boot)、Docker、Nacos等技术的开发、容器化、部署流程,涵盖服务注册、API网关、监控日志及性能优化实践,帮助企业实现云原生转型。
|
11月前
|
Kubernetes Docker Python
Docker 与 Kubernetes 容器化部署核心技术及企业级应用实践全方案解析
本文详解Docker与Kubernetes容器化技术,涵盖概念原理、环境搭建、镜像构建、应用部署及监控扩展,助你掌握企业级容器化方案,提升应用开发与运维效率。
1375 108