共计 15584 个字符,预计需要花费 39 分钟才能阅读完成。
本系列文章由余凯执笔创作,联结作者:阿里云容器服务 谢石 对本文亦有奉献
近几年,企业基础设施云原生化的趋势越来越强烈,从最开始的 IaaS 化到当初的微服务化,客户的颗粒度精细化和可观测性的需要更加强烈。容器网络为了满足客户更高性能和更高的密度,也始终在高速的倒退和演进中,这必然对云原生网络的可观测性带来了极高的门槛和挑战。为了进步云原生网络的可观测性,同时便于客户和前后线同学减少对业务链路的可读性,ACK 产研和 AES 联结共建,合作开发 ack net-exporter 和云原生网络数据面可观测性系列,帮忙客户和前后线同学理解云原生网络架构体系,简化对云原生网络的可观测性的门槛,优化客户运维和售后同学解决疑难问题的体验,进步云原生网络的链路的稳定性。
鸟瞰容器网络,整个容器网络能够分为三个局部:Pod 网段,Service 网段和 Node 网段。这三个网络要实现互联互通和访问控制,那么实现的技术原理是什么?整个链路又是什么,限度又是什么呢?Flannel,Terway 有啥区别?不同模式下网络性能如何?这些,须要客户在下搭建容器之前,就要根据本人的业务场景进行抉择,而搭建结束后,相干的架构又是无奈转变,所以客户须要对每种架构特点要有充沛理解。比方下图是个简图,Pod 网络既要实现同一个 ECS 的 Pod 间的网络互通和管制,又要实现不同 ECS Pod 间的拜访,Pod 拜访 SVC 的后端可能在同一个 ECS 也可能是其余 ECS,这些在不同模式下,数据链转发模式是不同的,从业务侧体现后果也是不一样的。
本文是 [全景分析容器网络数据链路] 第四局部局部,次要介绍 Kubernetes Terway EBPF+IPVLAN 模式下,数据面链路的转转发链路,一是通过理解不同场景下的数据面转发链路,从而探知客户在不同的场景下拜访后果体现的起因,帮忙客户进一步优化业务架构;另一方面,通过深刻理解转发链路,从而在遇到容器网络抖动时候,客户运维以及阿里云同学能够晓得在哪些链路点进行部署观测手动,从而进一步定界问题方向和起因。
- 系列一:全景分析阿里云容器网络数据链路(一)—— Flannel
- 系列二:全景分析阿里云容器网络数据链路(二)—— Terway ENI
- 系列三:全景分析阿里云容器网络数据链路(三)—— Terway ENIIP
- 系列五:全景分析阿里云容器网络数据链路(五)—— Terway ENI-Trunking
- 系列六:全景分析阿里云容器网络数据链路(六)—— ASM Istio
Terway IPVLAN+EBPF 模式架构设计
弹性网卡 (ENI) 反对配置多个辅助 IP 的性能,单个弹性网卡 (ENI) 依据实例规格能够调配 6 -20 个辅助 IP,ENI 多 IP 模式就是利用了这个辅助 IP 调配给容器,从而大幅提高了 Pod 部署的规模和密度。在网络联通的形式上,Terway 反对抉择 Veth pair 策略路由和 ipvlan l 两种计划,Linux 在 4.2 以上的内核中反对了 ipvlan 的虚构网络,能够实现单个网卡虚构进去多个子网卡用不同的 IP 地址,而 Terway 便利用了这种虚构网络类型,将弹性网卡的辅助 IP 绑定到 IPVlan 的子网卡上来买通网络,应用这种模式使 ENI 多 IP 的网络结构足够简略,性能也绝对 veth 策略路由较好。
ipvlan:
https://www.kernel.org/doc/Do…
Pod 所应用的的 CIDR 网段和节点的 CIDR 是同一个网段
Pod 外部能够看到是有一张网卡的,一个是 eth0,其中 eth0 的 IP 就是 Pod 的 IP,此网卡的 MAC 地址和管制台上的 ENI 的 MAC 地址不统一,同时 ECS 上有多张 ethx 的网卡,阐明 ENI 从属网卡并不是间接挂在到了 Pod 的网络命名空间
Pod 内有只有指向 eth0 的默认路由,阐明 Pod 拜访任何地址段都是从 eth0 为对立的出入口
那么 Pod 是如何 ECS OS 进行通信呢?在 OS 层面,咱们一看到 ipvl_x 的网卡,能够看到是从属于 eth1 的,阐明在 OS 层面会给每个从属网卡创立一个 ipvl_x 的网卡,用于建设 OS 和 Pod 内的连贯隧道。
ECS OS 内对于数据流量是怎么判断去哪个容器呢?通过 OS Linux Routing 咱们能够看到,所有目标是 Pod IP 的流量都会被转发到 Pod 对应的 ipvl_x 虚构往卡上,到这里为止,ECS OS 和 Pod 的网络命名空间曾经建设好残缺的出入链路配置了。到目前为止介绍了 IPVLAN 在网络架构上的实现。
对于 eni 多 IP 的实现,这个相似于《全景分析阿里云容器网络数据链路(三)—— Terway ENIIP》原理,Terway Pod 是通过 daemonset 的形式部署在每个节点上的,通过上面命令能够看到每个节点上的 Terway Pod。通过 terway-cli show factory 命令能够看到节点上的从属 ENI 数量、MAC 地址以及每个 ENI 上的 IP
那么对于 SVC 来说,是如何实现的呢?看过后面 四个系列的敌人,应该晓得对于 Pod 拜访 SVC,容器是利用各种方法将申请转发到 Pod 所在的 ECS 层面,由 ECS 内的 netfilter 模块来实现 SVC IP 的解析,这诚然是个好方法,然而因为数据链路须要从 Pod 的网络命名空间切换到 ECS 的 OS 的网络命名空间,两头通过了 2 次内核协定栈,必然会产生性能损失,如果对高并发和高性能有极致谋求,可能并不齐全满足客户的需要。那么对于高并发和提早敏感业务,该如何实现呢?有没有方法让 Pod 拜访 SVC 间接在 Pod 的网络命名空间中就实现了后端解析,这样联合 IPVLAN 这样至实现了一次内核协定栈。在 4.19 版本内核中,ebpf 的呈现,很好的实现了这个需要,这里不对 ebpf 做过多阐明,感兴趣的能够拜访 官网链接,小伙伴们只须要晓得 ebpf 是一种能够平安在内核层面运行的平安沙盒,当触发内核的指定行为,ebpf 设定程序会被执行。利用这个个性,咱们能够实现在 tc 层面对拜访 SVC IP 的数据包进行批改。
官网链接:
https://ebpf.io/what-is-ebpf/
例如,同上图,能够看到集群内有一个名为 nginx 的 svc,clusterIP 是 192.168.27.242,后端 pod IP 是 10.0.3.38. 通过 cilium bpf lb list 能够看到在 ebpf 程序中对于 clusterIP 192.168.27.242 的拜访会被转到 10.0.3.38 这个 IP 上,而 Pod 内只有一个默认路由。此处阐明,IPVLAN+EBPF 模式下,如果 Pod 拜访 SVC IP,SVCIP 在 Pod 的网络命名空间内就会被 ebpf 转为某个 SVC 后端 pod 的 IP,之后数据链路被收回 Pod。也就是说 SVCIP 只会在 Pod 内被捕捉,在源端 ECS,目标端 Pod 和目标端的 Pod 所在 ECS 都无奈被捕捉到。那如果一个 SVC 后后段有 100+ pod,因为 ebpf 存在,Pod 外无奈捕捉到 SVCIP,所在一旦呈现网络抖动,对于抓包该抓那个后端 IP 或该在哪个后端 Pod 出抓包呢?想一想,是不是一个十分头疼又无解的场景? 目前容器服务和 AES 共创了 ACK Net-Exporter 容器网络 可观测性工具,能够针对此场景进行继续化的观测和问题判断。
ACK Net-Exporter 容器网络:
https://help.aliyun.com/docum…
故 Terway IPVLAN+EBPF 模式总体能够演绎为:
- 4.2 以上内核中反对了 ipvlan 的虚构网络,能够实现单个网卡虚构进去多个子网卡用不同的 IP 地址,而 Terway 便利用了这种虚构网络类型,将弹性网卡的辅助 IP 绑定到 IPVlan 的子网卡上来买通网络,应用这种模式使 ENI 多 IP 的网络结构足够简略,性能也绝对 veth 策略路由较好。
- 节点拜访 pod 须要通过 host 的协定栈,pod 和 pod 间拜访 不通过 host 的 协定栈
- IPVLAN+EBPF 模式下,如果 Pod 拜访 SVC IP,SVCIP 在 Pod 的网络命名空间内就会被 ebpf 转为某个 SVC 后端 pod 的 IP,之后数据链路被收回 Pod。也就是说 SVCIP 只会在 Pod 内被捕捉,在源端 ECS,目标端 Pod 和目标端的 Pod 所在 ECS 都无奈被捕捉到。
Terway IPVLAN+EBPF 模式容器网络数据链路分析
针对容器网络特点,咱们能够将 Terway IPVLAN+EBPF 模式下的网络链路大体分为以 Pod IP 对外提供服务和以 SVC 对外提供服务两个大的 SOP 场景,进一步细分,能够演绎为 12 个不同的小的 SOP 场景。
对这 11 个场景的数据链路梳理合并,这些场景能够演绎为上面 12 类典型的场景:
TerwayENI 架构下,不同的数据链路拜访状况下,能够总结演绎为为 12 类:
- 拜访 Pod IP,同节点拜访 Pod
- 拜访 Pod IP,同节点 pod 间互访(pod 属于同 ENI)
- 拜访 Pod IP,同节点 pod 间互访(pod 属于不同 ENI)
- 不同节点间 Pod 之间互访
- 集群内 Pod 拜访的 SVC ClusterIP(含 Terway 版本≥1.2.0,拜访 ExternalIP),SVC 后端 Pod 和客户端 Pod 配属同一个 ENI
- 集群内 Pod 拜访的 SVC ClusterIP(含 Terway 版本≥1.2.0,拜访 ExternalIP),SVC 后端 Pod 和客户端 Pod 配属不同 ENI(同 ECS)
- 集群内 Pod 拜访的 SVC ClusterIP(含 Terway 版本≥1.2.0,拜访 ExternalIP),SVC 后端 Pod 和客户端 Pod 不属于不同 ECS
- 集群内 Pod 拜访的 SVC ExternalIP(Terway 版本≤1.2.0),SVC 后端 Pod 和客户端 Pod 配属同一个 ENI
- 集群内 Pod 拜访的 SVC ExternalIP(Terway 版本≤1.2.0),SVC 后端 Pod 和客户端 Pod 配属不同 ENI(同 ECS)
- 集群内 Pod 拜访的 SVC ExternalIP(Terway 版本≤1.2.0),SVC 后端 Pod 和客户端 Pod 部署于不同 ECS
- 集群外拜访 SVC ExternalIP
2.1 场景一:拜访 Pod IP,同节点拜访 pod
环境
cn-hongkong.10.0.3.15 节点上存在 nginx-7d6877d777-j7dqz 和 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
2.2 场景二:拜访 Pod IP,同节点 pod 间互访(pod 属于同 ENI)
环境
cn-hongkong.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:16:3e:04:08:3a,阐明这两个 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 相比,防止了 calico 网卡设施的两次转发,性能是更好的。
2.3 场景三:拜访 Pod IP,同节点 pod 间互访(pod 属于不同 ENI)
环境
cn-hongkong.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:16:3e:01:b7:bd 和 00:16:3e:04:08: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
2.4 场景四:不同节点间 Pod 之间互访
环境
cn-hongkong.10.0.3.15 节点上存在 nginx-7d6877d777-j7dqz,IP 分为 10.0.3.38
cn-hongkong.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 属于 cn-hongkong.10.0.3.15 上的 MAC 地址 为 00:16:3e:04:08:3a 的 ENI 网卡
通过 此节点的 terway pod,咱们能够 利用 terway-cli show factory 的命令看到 centos-6c48766848-dz8hz IP 10.0.3.127 属于 cn-hongkong.10.0.3.93 上的 MAC 地址 为 00:16:3e:02:20: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
2.5 场景五:集群内 Pod 拜访的 SVC ClusterIP(含 Terway 版本≥1.2.0,拜访 ExternalIP),SVC 后端 Pod 和客户端 Pod 配属同一个 ENI
环境
cn-hongkong.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:16:3e:04:08:3a,阐明这两个 IP 属于同一个 ENI,进而能够推断出 nginx-7d6877d777-j7dqz 和 centos-6c48766848-znkl8 属于同一个 ENI 网卡
通过 describe svc 能够看到 nginx pod 被退出到了 svc nginx 的后端。SVC 的 CLusterIP 是 192.168.27.242。如果是集群内拜访 External IP,对于 Terway 版本≥ 1.20 来说,集群内拜访 SVC 的 ClusterIP 或 External IP,整个链路架构是统一的,此大节不在针对 External IP 独自阐明,对立用 ClusterIP 作为示例(Terway 版本< 1.20 状况下,拜访 External 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 中对于 CLusterIP 192.168.27.242:80 记录的后端是 10.0.3.38:80。这上述的一切都是通过 EBPF 记录到了 源端 Pod centos-6c48766848-znkl8 pod 的 tc 中。
通过以上,能够实践推断出,如果集群内的 pod 拜访 SVC 的 CLusterIP 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。
EBPF 技术让集群内拜访避开了 ECS OS 外部的内核协定栈和缩小了局部 Pod 内核协定栈,大大提高了网络性能和 Pod 密度,带来了不弱于 独自 ENI 的网络性能,然而此形式会对咱们观测带来微小的扭转和影响。试想一下,如果您的集群内存在相互调用状况,这个调用的 IP 是 SVC 的 IP,退出此 SVC 后端所援用的 Pod 有几十上百个。源端 pod 调用时候呈现问题,个别状况下报错是‘connect to <svc IP> failed’等相似信息,传统的抓包伎俩是在源端 Pod 内,目标 Pod,ECS 上等进行抓包,筛选 SVC IP 来串起来不同包之间的同一个数据流,可是 eBPF 状况下因为上述技术实现,造成无奈捕捉 SVC 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 网络命名空间 eth0 抓包,抓包地址是目标 SVC 的 IP 和 客户端 POD IP。能够看到只能抓到客户端 Pod IP。
cilium 提供了一个 monitor 的性能,咱们应用 cilium monitor –related-to <endpoint ID>,能够看到,源端 POD IP 拜访 SVCIP 192.168.27.242,之后被解析到 SVC 的后端 POD IP 10.0.3.38.,阐明 SVC IP 间接在 tc 层做了转发,这也解释了为什么抓包无奈抓到 SVC IP,因为抓包是在 netdev 上抓的,此时曾经过了 协定栈和 tc。
后续大节如果波及 SVC IP 的拜访,如有相似,不再做具体的抓包展现
数据链路转发示意图
- 不会通过任何宿主机 ECS 的网络空间的两头节点
- 整个链路申请不会通过 pod 所调配的 ENI,间接在 OS 的 ns 中命中 Ip rule 被转发到对端 pod
- 整个申请链路是 ECS1 Pod1 -> ECS1 pod2(产生在 ECS 外部),和 IPVS 相比,防止了 calico 网卡设施的两次转发,性能是更好的。
- ECS1 Pod1 的 eth0 网卡无奈捕捉到 SVC IP,SVC IP 在 pod 网络命名空间内曾经通过 ebpf 转换成了 SVC 后端 Pod 的 IP
2.6 场景六:集群内 Pod 拜访的 SVC ClusterIP(含 Terway 版本≥1.2.0,拜访 ExternalIP),SVC 后端 Pod 和客户端 Pod 配属不同 ENI(同 ECS)
环境
cn-hongkong.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:16:3e:01:b7:bd 和 00:16:3e:04:08:3a,阐明这两个 IP 属于不同 ENI,进而能够推断出 nginx-7d6877d777-j7dqz 和 busybox-d55494495-8t677 属于不同 ENI 网卡
通过 describe svc 能够看到 nginx pod 被退出到了 svc nginx 的后端。SVC 的 CLusterIP 是 192.168.27.242。如果是集群内拜访 External IP,对于 Terway 版本≥ 1.20 来说,集群内拜访 SVC 的 ClusterIP 或 External IP,整个链路架构是统一的,此大节不在针对 External IP 独自阐明,对立用 ClusterIP 作为示例(Terway 版本< 1.20 状况下,拜访 External 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 中对于 CLusterIP 192.168.27.242:80 记录的后端是 10.0.3.38:80。这上述的一切都是通过 EBPF 记录到了 源端 Pod centos-6c48766848-znkl8 pod 的 tc 中。
![75.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0eaf17b2ad0f4fd7bfc91461bcca7b89~tplv-k3u1fbpfcp-zoom-1.image "75.png")
这里不再过多对于 svc ClusterIP 的 ebpf 转发进行形容,详细信息能够参考 2.5 大节中的形容,从上述形容状况,能够得悉被拜访的 SVC 的 IP 在 客户端 busybox 的网络命名空间中曾经被 ebpf 转为 svc 的后端 pod 的 IP,在任何 dev 上都无奈捕捉到客户端拜访的 SVC 的 IP。故此场景和 2.3 大节的网络架构十分相似,只是在客户端内会由 cilium ebpf 转发的动作
小结
数据链路转发示意图
- 不会通过任何宿主机 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
2.7 场景七:集群内 Pod 拜访的 SVC ClusterIP,SVC 后端 Pod 和客户端 Pod 不属于不同 ECS
环境
cn-hongkong.10.0.3.15 节点上存在 nginx-7d6877d777-j7dqz,IP 分为 10.0.3.38cn-hongkong.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 属于 cn-hongkong.10.0.3.15 上的 MAC 地址 为 00:16:3e:04:08:3a 的 ENI 网卡
通过 此节点的 terway pod,咱们能够 利用 terway-cli show factory 的命令看到 centos-6c48766848-dz8hz IP 10.0.3.127 属于 cn-hongkong.10.0.3.93 上的 MAC 地址 为 00:16:3e:02:20:f5 的 ENI 网卡
通过 describe svc 能够看到 nginx pod 被退出到了 svc nginx 的后端。SVC 的 CLusterIP 是 192.168.27.242。如果是集群内拜访 External IP,对于 Terway 版本≥ 1.20 来说,集群内拜访 SVC 的 ClusterIP 或 External IP,整个链路架构是统一的,此大节不在针对 External IP 独自阐明,对立用 ClusterIP 作为示例(Terway 版本< 1.20 状况下,拜访 External IP,会在后续大节阐明)。
内核路由
Pod 拜访 SVC 的 Cluster IP,而 SVC 的后端 Pod 和 客户端 Pod 部署在不同 ECS 上,此架构相似 2.4 大节中的不同 ECS 节点上的 Pod 间互访状况,只不此场景是 Pod 拜访 SVC 的 ClusterIP,要留神此处是拜访 ClusterIP,如果是拜访 External IP,那么场景会进一步简单了,本门的前面几个大节会具体阐明。对于 ClusterIP 的 ebpf 转发进行形容,详细信息能够参考 2.5 大节中的形容,和后面几个大节一样,在任何 dev 上都无奈捕捉到客户端拜访的 SVC 的 IP。
小结
数据链路转发示意图
- 不会通过任何宿主机 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
2.8 场景八:集群内 Pod 拜访的 SVC ExternalIP(Terway 版本≤1.2.0),SVC 后端 Pod 和客户端 Pod 配属同一个 ENI
环境
此处环境和 2.5 大节 状况相似,不做过多形容,只是此大节是在 terway 版本小于 1.2.0 状况下,拜访 External IP 47.243.139.183
内核路由
请参考 2.5 大节。
因为客户端 Pod 和被拜访的 SVC 的后端 Pod 同属于同一个 ENI,那么在 terway 版本小于 1.2.0 的状况下,拜访 External IP,实际上数据链路会通过 ENI 出 ECS 到 External IP 的 SLB,在被转发到同一个 ENI 上。四层 SLB 目前是不反对同一个 EI 同时作为客户端和服务端,所以会造成回环,详细信息能够参考上面连贯:https://help.aliyun.com/docum…
https://help.aliyun.com/docum…
小结
数据链路转发示意图
- 整个申请链路是 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 会短路集群内拜访 ExternalIP、LoadBalancer 的流量,即集群内拜访这些内部地址,理论流量不会到内部,而会被转为对应后端的 Endpoint 间接拜访。在 Terway IPvlan 模式下,Pod 拜访这些地址流量由 Cilium 而不是 kube-proxy 进行解决,在 Terway v1.2.0 之前版本并不反对这种链路的短路。在 Terway v1.2.0 版本公布后,新建集群将默认开启该性能,已创立的集群不会开启。(此处就是 2.5 大节场景)https://help.aliyun.com/docum…
https://help.aliyun.com/docum…
2.9 场景九:集群内 Pod 拜访的 SVC ExternalIP(Terway 版本≤1.2.0),SVC 后端 Pod 和客户端 Pod 配属不同 ENI(同 ECS)
环境
此处环境和 2.6 大节 状况相似,不做过多形容,只是此大节是在 terway 版本小于 1.2.0 状况下,拜访 External IP 47.243.139.183
内核路由
请参考 2.6 和 2.8 大节。
因为客户端 Pod 和被拜访的 SVC 的后端 Pod 尽管同属于同一个 ECS,然而不属于同一个 ENI,那么在 terway 版本小于 1.2.0 的状况下,拜访 External IP,实际上数据链路会通过客户端 pod ENI 出 ECS 到 External IP 的 SLB,在被转发到另一个一个 ENI 上。尽管从内部感知上看 两个客户端 Pod 和 SVC 的后端 Pod 都是在同一个 ECS,然而因为属于不同 ENI,所以不会造成回环,能够拜访胜利,此处的后果和 2.8 大节齐全不同,须要留神。
小结
数据链路转发示意图
- 整个申请链路是 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,能够拜访胜利
2.10 场景十:集群内 Pod 拜访的 SVC ExternalIP(Terway 版本≤1.2.0),SVC 后端 Pod 和客户端 Pod 部署于不同 ECS
环境
此处环境和 2.6 大节 状况相似,不做过多形容,只是此大节是在 terway 版本小于 1.2.0 状况下,拜访 External IP 47.243.139.183
内核路由
请参考 2.7 和 2.9 大节。
此处和 2.7 的架构场景类似,都是客户端 Pod 和 SVC 的后端 Pod 不属于不同的 ECS 节点,客户端去拜访 SVC 的 External IP。只有 Terway 的版本不同,2.7 大节 Terway 版本是≥1.2.0,此大节是<1.2.0,仅仅是 Terway 版本和 eniconfig 的不同,两者拜访链路一个会通过 SLB,一个则不会通过 SLB,这一点须要关注。置于不同的起因是因为 1.2.0 Terway 版本之后开启集群内负载平衡,对于拜访 ExternalIP 会被负载到 Service 网段,具体信息请见 2.8 大节。
小结
数据链路转发示意图
- 整个申请链路是 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 会造成回环
2.11 场景十一:集群外拜访 SVC ExternalIP
环境
cn-hongkong.10.0.3.15 节点上存在 nginx-7d6877d777-j7dqz,IP 分为 10.0.3.34 通过 describe svc 能够看到 nginx pod 被退出到了 svc nginx 的后端。SVC 的 CLusterIP 是 192.168.27.242。
内核路由
在 SLB 控制台,能够看到 lb-j6cj07oi6uc705nsc1q4m 虚构服务器组的后端服务器组是两个后端 nginx pod 的的 ENI eni-j6cgs979ky3evp81j3n8
从集群内部角度看,SLB 的后端虚构服务器组是 SVC 的后端 Pod 所属的 ENI 网卡,内网的 IP 地址就是 Pod 的地址
小结
数据链路转发示意图
- ExternalTrafficPolicy 为 Local 或 Cluster 模式下,SLB 只会将 pod 调配的 ENI 挂在到 SLB 的虚构服务器组
- 数据链路:client -> SLB -> Pod ENI + Pod Port -> ECS1 Pod1 eth0
总结
本篇文章次要聚焦 ACK 在 Terway IPVLAN+EBPF 模式下,不同 SOP 场景下的数据链路转发门路。随同着客户对性能极致谋求的需要,在 Terway IPVLAN+EBPF 相比 Terway ENI,有更高的 Pod 密度;相比 Terway ENIIP,有更高的性能,但因而也带了网络链路的复杂性和可观测性带来了调整,此场景能够分为 11 个 SOP 场景,并对这 11 个场景的转发链路,技术实现原理,云产品配置等一一梳理并总结,这对咱们遇到 Terway IPVLAN 架构下的链路抖动、最优化配置,链路原理等提供了初步指引方向。在 Terway IPVLAN 模式下,利用 EBPF 和 IPVLAN 隧道,防止了数据链路在 ECS OS 内核协定栈的转发,这必然带来了更高的性能,同时也有 ENIIP 模式一样的多 IP 共享 ENI 的形式来保障 Pod 密度。然而随着业务场景越来越趋于简单,业务的 ACL 管控也更加趋于 Pod 维度去治理,比方须要针对 Pod 维度进行平安 ACL 规定设置的需要等。下一系列咱们将进入到 Terway ENI-Trunking 模式的全景解析——《ACK 全景分析阿里云容器网络数据链路(五)—— Terway ENI-Trunking》。
点击此处查看阿里云容器服务