作者:余凯
本系列文章由余凯执笔创造,联合作者:阿里云云原生应用平台 谢石 对本文亦有奉献
前言
近几年,企业基础设施云原生化的趋势越来越激烈,从最开端的 IaaS 化到现在的微服务化,客户的颗粒度精细化和可观测性的需求更加激烈。容器网络为了满意客户更高功能和更高的密度,也一直在高速的发展和演进中,这必定对客户对云原生网络的可观测性带来了极高的门槛和挑战。为了提高云原生网络的可观测性,同时便于客户和前后线同学增加对事务链路的可读性,ACK 产研和 AES 联合共建,合作开发 ack net-exporter 和云原生网络数据面可观测性系列,协助客户和前后线同学了解云原生网络架构系统,简化对云原生网络的可观测性的门槛,优化客户运维和售后同学处理疑难问题的体会 ,提高云原生网络的链路的稳定性。
俯瞰容器网络,整个容器网络能够分为三个部分:Pod 网段,Service 网段和 Node 网段。这三个网络要完成互联互通和拜访操控,那么完成的技能原理是什么?整个链路又是什么,限制又是什么呢?Flannel, Terway 有啥区别?不同形式下网络功能怎么?这些,需求客户鄙人树立容器之前,就要依据自己的事务场景进行挑选,而树立结束后,相关的架构又是无法转变,所以客户需求对每种架构特色要有充分了解。比方下图是个简图,Pod 网络既要完成同一个ECS的Pod间的网络互通和操控,又要完成不同 ECS Pod 间的拜访, Pod 拜访 SVC 的后端或许在同一个 ECS 也或许是其他 ECS,这些在不同形式下,数据链转发形式是不同的,从事务侧体现成果也是不一样的。
本文是[全景分析容器网络数据链路]第一部分,首要介绍 Kubernetes Flannel 形式下,数据面链路的转转发链路,一是经过了解不同场景下的数据面转发链路,然后探知客户在不同的场景下拜访成果体现的原因,协助客户进一步优化事务架构;另一方面,经过深入了解转发链路,然后在遇到容器网络颤动时候,客户运维以及阿里云同学能够知道在哪些链路点进行布置观测手动,然后进一步定界问题方向和原因。
系列二:
全景分析阿里云容器网络数据链路(二):Terway ENI
系列三:
全景分析阿里云容器网络数据链路(三):Terway ENIIP
系列四:
全景分析阿里云容器网络数据链路(四):Terway IPVLAN+EBPF
系列五:
全景分析阿里云容器网络数据链路(五):Terway ENI-Trunking
系列六:
全景分析阿里云容器网络数据链路(六):ASM Istio
Flannel 形式架构设计
Flannel 形式下,ECS 只要一个主网卡 ENI,无其他隶属网卡,ECS 和节点上的 Pod 与外部通信都需求经过主网卡进行。ACK Flannel 会在每个节点创建 cni0 虚拟网卡作为 Pod 网络和 ECS 的主网卡 eth0 之间的桥梁。
集群的每个节点会起一个 flannel agent,而且会给每个节点预分配一个 Pod CIDR,这个 Pod CIDR 是ACK集群的 Pod CIDR 的子集。
容器的网络命名空间内会有一个 eth0 的虚拟网卡,同时存鄙人一跳指向该网卡的路由,该网卡会作为容器和宿主内核进行数据交流的收支口。容器和宿主机之间的数据链路是经过 veth pair 进行交流的,现在咱们现已找到 veth pair 其间一个,怎么去找另一个 veth 呢?
如上图所示,咱们能够容器的网络命名空间中经过 p addr 看到一个 eth0@if81 的标志位,其间 ‘81′ 这个将会协助咱们在 ECS 的 OS 内找到找到和容器网络命名空间中的 veth pair 相对一个。在 ECS OS 内咱们经过 ip addr | grep 81: 能够找到 vethd7e7c6fd 这个虚拟网卡,这个便是 veth pair 在 ECS OS 侧相对的那一个。
到目前停止容器内和 OS 数据链路现已树立链接了,那么 ECS OS 内关于数据流量是怎么判断去哪个容器呢?经过 OS Linux Routing 咱们能够看到,一切意图是 Pod CIDR 网段的流量都会被转发到 cni0 这张虚拟网卡,那么 cni0 是经过 bridge 方法将不同意图的数据链路指向到不同的 vethxxx。到这儿停止,ECS OS 和 Pod 的网络命名空间现已树立好完整的收支链路装备了。
Flannel 形式容器网络数据链路分析
针对容器网络特色,咱们能够将 Flannel 形式下的网络链路大体分为以 Pod IP 对外供给服务和以 SVC 对外供给服务两个大的 SOP 场景,进一步细分能够拆分到 10 个不同的小的 SOP 场景。
对这 10 个场景的数据链路梳理合并,这些场景能够概括为下面 5 类典型的场景:
- Client 和服务端 Pod 布置于同一个 ECS
- Client 和服务端 Pod 布置于不同 ECS
- 拜访 SVC External IP, ExternalTrafficPolicy 为 Cluster 时,Client 和服务端 Pod 布置于不同ECS,其间client为集群外
- 拜访 SVC External IP, ExternalTrafficPolicy 为 Local 时, Client 和服务端 Pod 布置于不同 ECS,其间client为集群内
- 拜访 SVC External IP, ExternalTrafficPolicy 为 Local 时, Client 和服务端 Pod 布置于不同 ECS,其间 client 为集群外
场景一:Client和服务端Pod布置于同一个ECS
此场景包括下面几个子场景,数据链路能够概括为一种:
- 以 Pod IP 对外供给服务,Client 和 Pod 布置于同一个节点;
- 以 SVC ClusterIP 对外供给服务,Client 和 SVC 后端 Pod 布置于同一节点;
- 以 SVC ExternalIP 对外供给服务,ExternalTrafficPolicy 为 Cluster/Local 状况下,Client 和 SVC 后端 Pod 布置于同一节点
环境
ap-southeast-1.10.0.0.180 节点上存在两个pod:centos-67756b6dc8-rmmxt IP地址172.23.96.23 和 nginx-7d6877d777-6jkfg 和172.23.96.24
内核路由
centos-67756b6dc8-rmmxt IP地址172.23.96.23,该容器在宿主机体现的 PID 是503478,该容器网络命名空间有指向容器 eth0 的默认路由
该容器 eth0 在 ECS OS 内对应 veth pair 是 vethd7e7c6fd
经过上述相似的方法,能够找到nginx-7d6877d777-6jkfg IP地址172.23.96.24,该容器在宿主机体现的 PID 是2981608,该容器 eth0 在 ECS OS 内对应veth pair是vethd3fc7ff4
在 ECS OS 内,有指向 Pod CIDR,下一跳为 cni0 的路由,以及 cni0 中有两个容器的vethxxx 网桥信息
小结:能够拜访到意图端
▲数据链路转发暗示图
▲内核协议栈暗示图
- 数据链路:ECS1 Pod1 eth0 -> vethxxx1 -> cni0 -> vethxxxx2 -> ECS1 Pod2 eth0
- 数据链路要经过三次内核协议栈,分别是 Pod1 协议栈, ECS OS 协议栈 和 Pod2 协议栈
场景二:Client 和服务端 Pod 布置于不同 ECS
此场景包括下面几个子场景,数据链路能够概括为一种:
- 以 Pod IP 对外供给服务,Client 和 Pod 布置于不同节点;
- 以 SVC ClusterIP 对外供给服务,Client和SVC 后端Pod布置于不同节点;
- 以 SVC ExternalIP 对外供给服务,ExternalTrafficPolicy 为 Cluster 状况下,集群内 Client 和 SVC 后端 Pod 布置于不同节点;
环境
ap-southeast-1.10.0.0.180 节点上存在两个 pod:centos-67756b6dc8-rmmxt IP地址172.23.96.23 和 nginx1-76c99b49df-7plsr IP 地址172.23.96.163
Service nginx1 的 ExternalTrafficPlicy 为 Cluster
内核路由
Pod 网络空间和 ECS OS 网络空间的数据交流在 2.1 场景一中现已做了详细描绘,此处不再决断篇幅描绘。
源端 Pod 地点 ECS 的 IPVS 规矩
能够看到,源端数据链路拜访 svc 的clusterip 192.168.13.23 时,假如链路抵达 ECS 的OS 内,会射中 ipvs 规矩,被解析到 svc 的后端 endpoint 之一(本实例中只要一个 pod,所以 endpoint 只要一个)
小结:能够成功拜访到意图端
▲数据链路转发暗示图
VPC 路由表会主动装备意图地址是 pod CIDR, 下一跳为 POD 网段所归属的 ECS 的自定义路由条目,该规矩由 ACK 管控测经过 openapi 调用 VPC 去装备,无需手动装备和删去
▲内核协议栈暗示图
Conntack 表信息(拜访 SVC 状况)
Node1:
src是源pod IP,dst是svc的ClusterIP,而且希望是由svc的其间一个endpoint 172.23.96.163 来回音讯给源端 pod
Node2:
意图 pod 地点 ECS 上 conntrack 表记载是由源端 pod 拜访意图 pod,不会记载 svc 的clusterip 地址
- 数据链路:ECS1 Pod1 eth0 -> vethxxx1 -> cni0 -> ECS 1 eth0 -> VPC -> ECS2 eth0 -> cni0 -> vethxxxx2 -> ECS2 Pod2 eth0
- 数据链路要经过四次内核协议栈,分别是 Pod1 协议栈, ECS1 OS 协议栈 , ECS2 OS 协议栈和 Pod2 协议栈
- VPC 路由表会主动装备意图地址是 pod CIDR, 下一跳为 POD 网段所归属的 ECS 的自定义路由条目,该规矩由 ACK 管控测经过 openapi 调用 VPC 去装备,无需手动装备和删去
- 假如拜访的 SVC 的 cluster IP,或者是 Cluster 形式下,拜访 SVC 的 externalIP,数据链路经过veth pair进到 ECS OS 内后,会射中相应的 IPVS 规矩,并根据负载规矩,挑选IPVS的某一个后端,进而打到其间的一个 SVC 的后端 endpoint,SVC 的 IP 只会再 PoD 的 eth0 , veth pair vethxxx 被捕捉到,其他链路环节不会捕捉到 svc 的 IP
场景三:ExternalTrafficPolicy 为 Local时,Client 和服务端 Pod 布置于集群内不同 ECS
此场景包括下面几个子场景,数据链路能够概括为一种:
1.以SVC ExternalIP对外供给服务,ExternalTrafficPolicy 为 Local状况下,集群内 Client 和 SVC 后端 Pod 布置于不同节点;
环境
ap-southeast-1.10.0.0.180 节点上存在两个pod:centos-67756b6dc8-rmmxt IP地址172.23.96.23 和 nginx1-76c99b49df-7plsr IP 地址172.23.96.163
Service nginx1 ExternalTrafficPolicy 为 Local
内核路由
Pod 网络空间和 ECS OS 网络空间的数据交流在 2.1 场景一中现已做了详细描绘,此处不再决断篇幅描绘。
源端 Pod 地点 ECS 的 IPVS 规矩
能够看到,源端数据链路拜访 svc 的 externalip 8.219.164.113 时,假如链路抵达 ECS 的OS内,会射中ipvs规矩,可是咱们能够看到EcternalIP 并没有相关的后端 endpoint,链路到达 OS 后,会射中 IPVS 规矩,可是没有后端 pod,所以会出现 connection refused
小结:不能够拜访到意图端,此刻会拜访失败,Connection refused
▲数据链路转发暗示图
▲内核协议栈暗示图
- 数据链路:ECS1 Pod1 eth0 -> vethxxx1 ->
- 数据链路要经过一次半内核协议栈,分别是 Pod1 协议栈,半个 ECS1 OS 协议栈
- 假如拜访的 SVC 的 External IP,或者是 Local 形式下,拜访 SVC 的 externalIP,数据链路经过 veth pair 进到 ECS OS内后,会射中相应的 IPVS 规矩,可是由于 Local 形式,External IP的 IPVS 为空,所以射中规矩可是无转发后端,整个链路会在 ipvs 停止,拜访失败。所以建议集群内选用 clusterip 拜访,这也是 k8s 官方引荐的最佳实践。
场景四:ExternalTrafficPolicy 为 Local 时,Client 来自于集群外
此场景包括下面几个子场景,数据链路能够概括为一种:A.拜访SVC External IP, ExternalTrafficPolicy 为 Local时, Client 和服务端 Pod 布置于不同 ECS,其间 client 为集群外
环境
Deployment为nginx1, 分别为三个pod nginx1-76c99b49df-4zsdj和nginx1-76c99b49df-7plsr 布置在 ap-southeast-1.10.0.1.206 ECS上,最终一个pod nginx1-76c99b49df-s6z79 布置在其他节点 ap-southeast-1.10.0.1.216 上
Service nginx1 的ExternalTrafficPlicy 为 Local
内核路由
Pod 网络空间和 ECS OS 网络空间的数据交流在 2.1 场景一中现已做了详细描绘,此处不再决断篇幅描绘。
SLB 相关装备
从 SLB 操控台,能够看到 SLB 后端的虚拟服务器组中只要两个 ECS 节点ap-southeast-1.10.0.1.216 和 ap-southeast-1.10.0.1.206。集群内的其他节点 ,比方 ap-southeast-1.10.0.0.180 并未被加到 SLB 的后端虚拟服务器组中。虚拟服务器组的 IP 为 ECS 的 IP,端口为 service 里边的 nodeport 端口 32580.
故 ExternalTrafficPolicy 为 Local 形式下,只要有 Service 后端 pod 地点的 ECS 节点才会被加入到 SLB 的后端虚拟服务器组中,参加 SLB 的流量转发,集群内的其他节点不参加 SLB 的转发
SLB 虚拟服务器组 ECS 的 IPVS 规矩
从SLB的虚拟服务器组中的两个 ECS 能够看到,关于 nodeip+nodeport 的 ipvs转发规矩是不同。ExternalTrafficPolicy 为 Local 形式下,只要该节点上的护短 pod 才会被加到该节点的 ipvs 转发规矩中,其他节点上的后端 pod 不会加进来,这样保证了被 SLB 转发的链路,只会被转到该节点上的 pod,不会转发到其他节点上。
node1:ap-southeast-1.10.0.1.206
node1:ap-southeast-1.10.0.1.216
小结:能够拜访到意图端
▲数据链路转发暗示图
该图暗示了只要后端 pod 地点 ECS 才会加到 SLB 后端中,从集群外部拜访 SVC 的externalIP(SLB IP)的状况,可见数据链路只会被转发到虚拟服务器组中的 ECS,不会再被转发到集群内其他节点上。
▲内核协议栈暗示图
Conntack 表信息
Node:
src 是集群外部客户端IP,dst 是节点 IP,dport 是 SVC 中的 nodeport。而且希望是由该 ECS 上的 pod 172.23.96.82 来回包给源端
- 数据链路:client -> SLB -> ECS eth0 + ECS nodeport -> cni0 -> vethxxxxx -> ECS1 Pod1 eth0
- 数据链路要经过两次内核协议栈,分别是 Pod1 协议栈, ECS1 OS 协议栈
- ExternalTrafficPolicy 为 Local 形式下,只要有 Service 后端 pod 地点的 ECS 节点才会被加入到SLB的后端虚拟服务器组中,参加 SLB 的流量转发,集群内的其他节点不参加 SLB 的转发
场景五:ExternalTrafficPolicy 为 Cluster 时,Client 来自于集群外
此场景包括下面几个子场景,数据链路能够概括为一种:
1.拜访 SVCExternal IP, ExternalTrafficPolicy 为 Cluster 时, Client 和服务端 Pod布置于不同 ECS,其间 client 为集群外
环境
Deployment为nginx1, 分别为三个pod nginx1-76c99b49df-4zsdj和nginx1-76c99b49df-7plsr 布置在 ap-southeast-1.10.0.1.206 ECS上,最终一个pod nginx1-76c99b49df-s6z79 布置在其他节点 ap-southeast-1.10.0.1.216 上
Service nginx2 的 ExternalTrafficPlicy 为 Cluster
内核路由
Pod 网络空间和 ECS OS 网络空间的数据交流在 2.1 场景一中现已做了详细描绘,此处不再决断篇幅描绘。
SLB 相关装备
从SLB 操控台,集群内一切节点ap-southeast-1.10.0.0.180、ap-southeast-1.10.0.1.216 和 ap-southeast-1.10.0.1.206 都被加到SLB的虚拟服务器组中。其间 虚拟服务器组的 IP 为 ECS 的 IP,端口为 service 里边的 nodeport 端口 30875.
故 ExternalTrafficPolicy 为 CLuster 形式下,集群内一切的 ECS 节点都会被加入到 SLB 的后端虚拟服务器组中,参加 SLB 的流量转发。
SLB 虚拟服务器组 ECS 的 IPVS 规矩
从SLB的虚拟服务器组中的能够看到,关于 nodeip+nodeport 的 ipvs 转发规矩是共同的。ExternalTrafficPolicy为 CLuster 形式下,一切的 service 后端 pod 都会被加到一切节点的 ipvs 的转发规矩中,即使是该节点有后端 pod,流量也不一定会被转发到该节点上 pod,或许会被转发到其他节点上的后端 pod。
node1:ap-southeast-1.10.0.1.206 (该节点有后端pod)
node1:ap-southeast-1.10.0.1.216 (该节点有后端pod)
node3: ap-southeast-1.10.0.0.180 (该节无后端pod)
小结:能够拜访到意图端
▲数据链路转发暗示图
该图暗示了集群内一切 ECS 都会被加到 SLB 后端中,从集群外部拜访 SVC 的externalIP(SLB IP)的状况,数据流量或许会被转发到其他节点上
内核协议栈暗示图:
内核协议栈暗示图现已在 2.4 场景一中现已做了详细描绘,此处不再决断篇幅描绘。
Conntack 表信息
链路1:
ap-southeast-1.10.0.0.180:
此刻数据链路对应暗示图中的链路1,能够看到数据链路被转到 ap-southeast-1.10.0.0.180 节点,该节点上并没有 service 的后端 pod,经过 conntrack 信息,能够看到
src 是集群外部客户端 IP,dst 是节点 IP,dport 是 SVC 中的 nodeport。而且希望是172.23.96.163 来回包给 10.0.0.180 。经过前述信息,能够得知172.23.96.163 是nginx1-76c99b49df-7plsr pod,布置在 ap-southeast-1.10.0.1.206
ap-southeast-1.10.0.1.206:
经过此节点conntrack 表,能够看到src是 node ap-southeast-1.10.0.0.180,dst 是 172.23.96.163的80 端口,回包也是直接回给 node ap-southeast-1.10.0.0.180.
综上能够看到 src 变换了屡次,故在 CLuster 形式下,会存在丢掉实在客户端 IP 的状况
链路2:
src 是集群外部客户端 IP,dst 是节点IP,dport 是 SVC 中的 nodeport。而且希望是由该 ECS 上的 pod 172.23.96.82 来回包给 172.23.96.65,此地址是 SLB 集群中的一个地址
- 数据链路:情形一:client -> SLB -> ECS eth0 + ECS nodeport -> cni0 -> vethxxxxx -> ECS1 Pod1 eth0情形二:client -> SLB -> ECS1 eth0 + ECS1 nodeport -> VPC Routing -> ECS2 eth0 + pod port -> cni0 -> vethxxxxx -> ECS2 Pod1 eth0
- 数据链路要经过三次内核协议栈,分别是 ECS1 OS、 ECS2 OS 协议栈 和 Pod 协议栈
- ExternalTrafficPolicy 为 CLuster 形式下,kubernetes 一切 ECS 节点都会被加入到 SLB 的后端虚拟服务器组中,参加 SLB 的流量转发,此刻会存在数据路在集群内被多个 ECS 转发的场景,该状况下会丢掉实在客户端IP的状况
总结
本篇文章首要聚集 ACK 在 Flannel 形式下,不同 SOP 场景下的数据链路转发途径。随着微服务化和云原生化,网络场景日趋复杂,作为 kubernetes 原生的网络模型——Flannel,不同的拜访环境,一共能够分为10个 SOP 场景。经过深入简出的分析,能够概括为5个场景,并对这五个场景的转发链路,技能完成原理,云产品装备等逐个梳理并总结,这对咱们遇到 Flannel 架构下的链路颤动、最优化装备,链路原理等供给了开始指引方向。接下来将进入到阿里自研的 CNI 接口 Terway 形式,也是目前线上集群使用最多的形式,下一系列咱们先带来 Terway ENI 形式的全景解析——ACK 全景分析阿里云容器网络数据链路(二):Terway ENI。
点击此处了解阿里云容器服务