更多精彩内容,欢迎观看:
《云原生网络数据面可观测性最佳实践》——二、全景剖析阿里云容器网络数据链路——4. Terway IPVLAN+EBPF 模式架构设计(上):https://developer.aliyun.com/article/1221415?groupCode=supportservice
5) 场景四:不同节点间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。
通过此节点的terwayPod,我们可以利用 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网卡。
通过此节点的terwayPod,我们可以利用 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;
6) 场景五:集群内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。
通过此节点的terwayPod,我们可以利用 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 可以看到 nginxPod 被加入到了 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-znkl8Pod,可以找到此pod所在的ECS的TerwayPod为terway-eniip-6cfv9,在TerwayPod 中运行下面的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-znkl8Pod的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 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 ,可以看到,源端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;
1) 场景六:集群内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。
通过此节点的terwayPod,我们可以利用 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 可以看到 nginxPod 被加入到了 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-8t677Pod,可以找到此pod所在的ECS的TerwayPod为terway-eniip-6cfv9,在TerwayPod 中运行下面的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-znkl8Pod的tc中。
这里不再过多对于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;
https://help.aliyun.com/document_detail/197320.htm
https://help.aliyun.com/document_detail/113090.html#p-lim-520-w07
更多精彩内容,欢迎观看:
《云原生网络数据面可观测性最佳实践》——二、全景剖析阿里云容器网络数据链路——4. Terway IPVLAN+EBPF 模式架构设计(下):https://developer.aliyun.com/article/1221412?groupCode=supportservice