弹性网卡(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呢?TerwayPod是通过daemonset的方式部署在每个节点上的,通过下面命令可以看到每个节点上的TerwayPod。通过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部署的规模和密度。
1) Terway ENIIP 模式容器网络数据链路剖析
针对容器网络特点,我们可以将Terway ENI模式下的网络链路大体分为以Pod IP对外提供服务和以SVC对外提供服务两个大的SOP场景,进一步细分,可以归纳为7个不同的小的SOP场景。
对这12 个场景的数据链路梳理合并,这些场景可以归纳为下面7 类典型的场景:
TerwayENI架构下,不同的数据链路访问情况下,可以总结归纳为7 类:
● 访问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
2) 场景一:访问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网卡在这里的主要作用是用于:1.节点访问Pod 2. 当节点或者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 ->ECSPod net eth0。
● 整个链路会经过两次内核协议栈:ECS OS和Pod。
● 数据链路要经过两次内核协议栈,是Pod1协议栈、ECS1协议栈。
3) 场景二:访问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网卡在这里的主要作用是用于:1.节点访问Pod 2. 当节点或者Pod访问 SVC的CIDR时,会走ECS OS内核协议栈转换,走到calixxx和eth0访问pod。
说明相关的路由转发是在ECS OS层面进行的,Pod的calixx网卡起到了一个桥梁和连通的作用。
源端ECS上的IPVS规则(如果访问的是SVC IP)
如果同节点上访问的是SVC的IP(ClusterIP or ExternalIP),在节点上我们查看SVC的相关IPVS转发规则:
更多精彩内容,欢迎观看:
《云原生网络数据面可观测性最佳实践》——二、全景剖析阿里云容器网络数据链路——3. Terway ENIIP 模式架构设计(中):https://developer.aliyun.com/article/1221454?spm=a2c6h.13148508.setting.27.15f94f0eR4QihT