《阿里云:云原生网络数据面可观测性最佳实践(2023)(300页).pdf》由会员分享,可在线阅读,更多相关《阿里云:云原生网络数据面可观测性最佳实践(2023)(300页).pdf(300页珍藏版)》请在三个皮匠报告上搜索。
1、前言前言近几年,企业基础设施云原生化的趋势越来越强烈,从最开始的 IaaS 化到现在的微服务化,客户的颗粒度精细化和可观测性的需求更加强烈。容器网络为了满足客户更高性能和更高的密度,也一直在高速的发展和演进中,这必然对客户对云原生网络的可观测性带来了极高的门槛和挑战。鸟瞰容器网络,整个容器网络可以分为三个部分:Pod 网段,Service 网段和Node 网段。这三个网络要实现互联互通和访问控制,那么实现的技术原理是什么?整个链路又是什么,限制又是什么呢?Flannel,Terway 有啥区别?不同模式下网络性能如何?这些,需要客户在下搭建容器之前,就要依据自己的业务场景进行选择,而搭建完毕后
2、,相关的架构又是无法转变,所以客户需要对每种架构特点要有充分了解。比如下图是个简图,Pod 网络既要实现同一个 ECS 的 Pod 间的网络互通和控制,又要实现不同 ECSPod 间的访问,Pod 访问 SVC 的后端可能在同一个 ECS也可能是其他 ECS,这些在不同模式下,数据链转发模式是不同的,从业务侧表现结果也是不一样的。为了提高云原生网络的可观测性,同时便于客户和前后线同学增加对业务链路的可读性,ACK 产研和 GTS-AES 联合共建,合作开发 ACK Net-Exporter 和云原生网络数据面可观测性系列,帮助客户和前后线同学了解云原生网络架构体系,简化对云原生网络的可观测性的
3、门槛,优化客户运维和售后同学处理疑难问题的体验,提高云原生网络的链路的稳定性。目录一、容器网络内核原理.61.概述filter 框架.93.tc 子系统.184.eBPF 技术.26二、全景剖析阿里云容器网络数据链路.291.Flannel 模式架构设计.292.Terway ENI 模式架构设计.503.Terway ENIIP 模式架构设计.804.Terway IPVLAN+EBPF 模式架构设计.1105.Terway ENI-Trunking 模式架构设计.1546.ASM Istio 模式架构.190三、容器网络常见观测工具及特点.2361.常见网络排查工具.2362.Net-Ex
4、port 技术原理.240四、ACK Net-Exporter 快速上手.2431.Prometheus+Grafana 配置.2442.ACK Net-Exporter 部署.2553.典型问题排查指南.267五、典型问题华山论剑.2741.某客户 nginx ingress 偶发性出现 4xx or 5xx.2742.某客户偶发 RTT 增高.2843.某客户反馈 pod 偶发性健康检查失败.2894.某客户偶发请求延迟.2945.某客户 SVC 后端负载不均.295容器网络内核原理6一、容器网络内核原理Linux 网络子系统是 Linux 系统最为基础的组成部分,理解 Linux 网络子
5、系统的核心和基础架构,能够让我们在排查网络问题的过程中对问题有较为全局的认识,避免由于缺乏了解而多走弯路。本章节会以全景概览的方式对 Linux 网络子系统进行简单的描述。1.概述网络通信的本质是电磁波高低电位变化在物理介质上的传输,高低变化的电位形成二进制的数据传递给网络硬件设备,硬件网络设备则会根据特定的编码方式讲二进制的数据变成以太网报文,此时,物理网络的信息就被解调制成为了数据帧,在 OSI 七层网络协议的定义中,二进制的数据处于物理层,而以太网数据帧则处于数据链路层,对于 Linux内核来说,物理层和数据链路层之间的转换通常是由硬件设备的驱动完成,Linux 内核定义了与硬件设备驱动
6、通信的标准,在完成数据链路层的收包后,硬件网络设备会将数据帧传递给操作系统 Linux 的内核进行处理,所以 Linux 网络协议栈的源头是数据链路层的数据帧报文。Linux 内核在处理数据帧报文是,按照数据帧的分片,TSO 等特性,将数据帧转化为可见的网络层报文,从而进行下一步的操作,内核在处理网络报文的时候,才用了一种非常高效的方式:内核通过一个 sk_buff 结构体,保存所有的报文数据。在网络层处理后传递给传输层的操作中,内核并不会为每一层进行复制,而是通过指针偏移的方式处理同一个 sk_buff 结构体。容器网络内核原理7下图是对 Linux 网络子系统的一个简单示意图:根据网络报文
7、的流向,我们按照两个不同的方向对豹纹处理的流程进行概述。容器网络内核原理81)1)收包方向的报文处理收包方向的报文处理从上图中可以发现,当内核从网络驱动设备中获取到报文后:首先进行 TC 子系统的操作,在收包方向,不会有特别复杂的操作。完成了网络层报文的重组后,报文进入了网络层的处理,在网络层的处理中,比较重要的是,netfilter 框架和路由查找,这里实现了大量的功能,在云原生的场景中,netfilter 和路由子系统有着至关重要的作用。网络层完成处理后,会交由传输层进行处理,传输层的协议最常见的是 tcp 和 udp,其中 tcp 协议在传输层通过重传和序号校验等保证了连接的可靠性。传输
8、层完成处理后,内核会将真正的报文数据提取出来并交给 socket 子系统,socket 子系统抽象了网络的所有操作,屏蔽了网络报文的细节,让用户程序可以按照文件 io 的方式读写网络数据。socket 子系统的数据最终会被用户程序读取,此时,一些编程语言的底层依赖库会进行一些封装,提供应用层协议的支持,如 http,mqtt 等,提供用户友好的操作体验。2)2)发包方向的报文处理发包方向的报文处理发包方向的处理,相比收包方向来说,一个重要的区别是,收包方向的操作是内核的软中端处理线程进行收包操作,而发包方向的操作则是由进程上下文进入内核态进行,因此,发包方向出现由于调度问题产生的偶发延迟都懂的
9、概率比收包方向要小。应用程序通常都是调用编程语言或者第三方的类库提供的方法进行发包动作,而这些法宝动作最终都会调用 socket 子系统的写入调用来实现发送数据:应用程序写入 socket 后,在达到一定的条件,如内存充裕,tcp 发送窗口足够等情况下,内核会给当前需要发送的数据申请一个 sk_buff 结构体的内存,并将需要发送的数据填充到 sk_buff 的数据中。sk_buff 数据报文首先会经过传输层的处理,根据当前的系统状态,内核会给报文sk_buff 的 tcp 报头进行填充,然后调用网络层提供的方法进行发送。容器网络内核原理9网络层和收包方向类似,也会经历过 netfilter
10、框架的选取路由的动作,在这里实现了大量的雨网络抽象相关的逻辑。在网络层完成处理后,按照 OSI 七层网络定义,会进入数据链路层,实际上在 Linux 中,邻居子系统的信息填充,也会在路由子系统完成路由的选取后一并填入到报文的报头中,随后报文会进入发送方向的 TC 子系统。TC 子系统是实现网络流量整形的关键,和收包方向不同的是,发包方向的 TC 子系统会进行复杂的排序工作,通过数据包的类型与配置的规则进行匹配,实现网络流控的功能。TC 子系统会将优先级最高的报文传递给网络设备驱动。网络设备驱动的发送方法的实现逻辑细节已经不再属于 Linux 内核的范畴,通常在进入网络设备后,我们就可以认为数据
11、包已经完成了发送。filter 框架netfilter 框架是 Linux 操作系统中内置的,通过向内核模块提供对协议栈中的网络数据包进行修改和操作的能力,来实现流量过滤,网络地址转换等高级功能。1)1)netfilternetfilter 如何工作如何工作对于网络数据报文,网络设备驱动通过将二层的以太网数据报文按照 Linux 内核定义的网络设备驱动规范,以 sk_buff 结构体的方式进行接收或者发送,即通常我们所描述的报文的最小单元 skb。内核通过将网络设备缓冲区环形队列中的 skb 取出,并按照以太网层,网络层,传输层的顺序处理后,将报文数据放置到对应的 Socket 缓冲区中,通知
12、用户程序进行读取,从而完成收包。内核为 Socket 缓冲区的待发送数据封装为 skb,经过传输层,网络层和以太网层依次填充对应的报头后,调用网络设备驱动的方法将 skb 发送到网络上,从而完成发包。netfilter工作的核心原理则是在网络层,通过在五个不同的内核处理skb数据包的位置,执行注册到 netfilter 框架中的回调函数,并根据回调函数的返回来选择下一步的处理,容器网络内核原理10来实现复杂的功能。netfilternetfilter 触发触发的的时机时机netfilter 在内核网络数据包的处理流程中,注册了 5 个可以出发的实际,详情如下:/*IP Hooks*/*Afte
13、r promisc drops,checksum checks.*/#define NF_IP_PRE_ROUTING0/*If the packet is destined for this box.*/#define NF_IP_LOCAL_IN1/*If the packet is destined for another interface.*/#define NF_IP_FORWARD2/*Packets coming from a local process.*/#define NF_IP_LOCAL_OUT3/*Packets about to hit the wire.*/#d
14、efine NF_IP_POST_ROUTING4#define NF_IP_NUMHOOKS5#endif/*!_KERNEL_*/根据源代码中的定义,我们可以参考下图:容器网络内核原理11从上面的代码定义和示意图中可以知道,在以下几个地方会调用 netfilter 定义好的方法对数据包进行处理:数据包从网卡进入协议栈后,所有的报文都会走到 NF_IP_PRE_ROUTING。数据包经过入向的路由选择后,确认是由本机的传输层进行处理的,会进入到NF_IP_LOCAL_IN。数据包经过入向的路由选择后,不是由本机处理,需要转发给其他机器的,会进入到 NF_IP_FORWARD。由本机的传输层发
15、出的报文,都会经过 NF_IP_LOCAL_OUT。经过出向的路由选择后的报文,会经过 NF_IP_POST_ROUTING,包括从本机发出的和需要本机转发的。在以上五个时机,当数据包 skb 到达时,netfilter 框架定义的回调方法就会被内核执行。netfilternetfilter 如何操作网络数据如何操作网络数据使用 netfilter 框架的模块,需要按照 netfilter 定义的结构体来实现自己的行为,才能正确注册到 netfilter 框架中,并被内核调用,netfilter 约束的注册结构体的定义如下:struct nf_hook_ops/这是真正被内核执行的函数,会对
16、skb 进行读取和修改nf_hookfn*hook;struct net_device*dev;void*priv;u_int8_tpf;/hooknum 定义了回调函数生效的位置,从上文可知有五个位置可以选择unsigned inthooknum;/priority 定义了回调函数的优先级,通过每个 hook 时机都会有多个回调函数需要生效intpriority;以 ipvlan 模块为例:容器网络内核原理12static const struct nf_hook_ops ipvl_nfops=.hook=ipvlan_nf_input,.pf=NFPROTO_IPV4,.hooknum=N
17、F_INET_LOCAL_IN,.priority=INT_MAX,#if IS_ENABLED(CONFIG_IPV6).hook=ipvlan_nf_input,.pf=NFPROTO_IPV6,.hooknum=NF_INET_LOCAL_IN,.priority=INT_MAX,#endif;我们可以看到,ipvlan 模块根据 IP 协议的版本定义了两个 hook 结构体,其中:hookfn 是核心的处理逻辑,ipvlan 模块注册了 ipvlan_nf_input 方法。pf 是 netfilter 的协议版本,ipvlan 模块分别注册了 IPv6 和 IPv4 对应的方法。ho
18、oknum 定义了这个 hook 在 netfilter 中生效的位置,ipvlan 模块将自己的回调方法注册到了 NF_INET_LOCAL_IN,也就是完成路由之后,进入传输层之前。priotity 定义了 hook 的优先级。那么,hookfn 作为真正核心的处理逻辑,他是如何工作的呢?以 ipvlan 注册在 NF_INET_LOCAL_IN 上的 hook 方法 ipvlan_nf_input 为例:unsigned int ipvlan_nf_input(void*priv,struct sk_buff*skb,const struct nf_hook_state*state)/参
19、数中可以看到,有前一个生效的 hook 结构体,当前处理的 skb 报文本身以及当前netfilter 框架的上下文信息struct ipvl_addr*addr;unsigned int len;addr=ipvlan_skb_to_addr(skb,skb-dev);if(!addr)goto out;容器网络内核原理13skb-dev=addr-master-dev;len=skb-len+ETH_HLEN;ipvlan_count_rx(addr-master,len,true,false);out:/这里返回了 netfilter 框架规定的返回码return NF_ACCEPT;从
20、 ipvlan_nf_input 可以看到,注册到 netfilter 中的回调函数的核心在于两个约束:回调函数的入参定义,可以接受协议栈中真正的报文结构体 skb 以及 netfilter 的上下文状态为参数。回调函数的返回值,需要是 netfilter 规定好的返回值,他们的定义如下:/*Responses from hook functions.*/#define NF_DROP 0#define NF_ACCEPT 1#define NF_STOLEN 2#define NF_QUEUE 3#define NF_REPEAT 4#define NF_STOP 5/*Deprecated
21、,for userspace nf_queue compatibility.*/#define NF_MAX_VERDICT NF_STOP从以上的分析不难看出,只要满足 netfilter 的注册条件,就可以在回调函数中直接对数据报文 skb 内容进行读取和修改操作,而通过返回值的定义,则可以借助 netfilter 框架完成对数据包的处理,比如丢弃,接收或者传递到用户态进行处理。netfilternetfilter 的内核实现的内核实现在负责对所有 hook 方法进行遍历处理的函数中,可以看到,netfilter 核心的工作流程就是在相应的触发时机调用这个时机上注册的所有方法,按照优先级进
22、行处理,并根据每一次处理的结果进行操作,包括丢弃,传输给用户态等等:int nf_hook_slow(struct sk_buff*skb,struct nf_hook_state*state,const struct nf_hook_entries*e,unsigned int s)unsigned int verdict;int ret;容器网络内核原理14for(;s num_hook_entries;s+)/在这里调用对应的 hook 时机上的所有注册的 hook 回调方法,然后根据结果选择是不是继续循环verdict=nf_hook_entry_hookfn(&e-hookss,sk
23、b,state);switch(verdict&NF_VERDICT_MASK)case NF_ACCEPT:break;case NF_DROP:kfree_skb(skb);ret=NF_DROP_GETERR(verdict);if(ret=0)ret=-EPERM;return ret;case NF_QUEUE:ret=nf_queue(skb,state,e,s,verdict);if(ret=1)continue;return ret;default:/*Implicit handling for NF_STOLEN,as well as any other*non conven
24、tional verdicts.*/return 0;return 1;2)2)netfilternetfilter 的常见应用的常见应用conntrackconntrack 连接跟踪连接跟踪conntrack 是 netfilter 提供的核心功能之一,通过对 tcp,udp 等协议的连接状态的记录,来实现连接的会话状态保持的功能,例如:对于 iptables 或者 ipvs 进行的 NAT 操作,可以记录单个已经建立的连接的 NAT信息,对于相同的 tcp 连接,可以减少 NAT 操作中分配五元组计算的频率,保持连接状态的存续。容器网络内核原理15对于没有建立完成的连接,也不是握手请求的情
25、况,可以在差抄不到 conntrack 的情况下避免其进入协议栈,从而减少非必要的消耗。在 Linux 中,我们可以借助 conntrack-tools 工具提供的 conntrack 命令来管理conntrack 操作,常见的使用方法如下:#输出当前 netns 中所有的 conntrack 条目信息conntrack-L#通过 netlink stream 的方式实时观察 conntrack 的写入事件conntrack-E#查看按照 cpu 进行统计的 conntrack 数据conntrack-Sconntrack 在内核中也是通过注册在 netfilter 上的 hook 函数进行工
26、作的,此外,conntrack机制还依赖于按照cpu的数量来为每一个cpu分配一块用于存放conntrack信息的内存,以下是 conntrack 机制在 Linux 上的实现:static const struct nf_hook_ops ipv4_conntrack_ops=.hook=ipv4_conntrack_in,.pf=NFPROTO_IPV4,.hooknum=NF_INET_PRE_ROUTING,.priority=NF_IP_PRI_CONNTRACK,.hook=ipv4_conntrack_local,.pf=NFPROTO_IPV4,.hooknum=NF_INET
27、_LOCAL_OUT,.priority=NF_IP_PRI_CONNTRACK,.hook=ipv4_helper,.pf=NFPROTO_IPV4,.hooknum=NF_INET_POST_ROUTING,.priority=NF_IP_PRI_CONNTRACK_HELPER,.hook=ipv4_confirm,.pf=NFPROTO_IPV4,.hooknum=NF_INET_POST_ROUTING,.priority=NF_IP_PRI_CONNTRACK_CONFIRM,容器网络内核原理16,.hook=ipv4_helper,.pf=NFPROTO_IPV4,.hooknu
28、m=NF_INET_LOCAL_IN,.priority=NF_IP_PRI_CONNTRACK_HELPER,.hook=ipv4_confirm,.pf=NFPROTO_IPV4,.hooknum=NF_INET_LOCAL_IN,.priority=NF_IP_PRI_CONNTRACK_CONFIRM,;网络地址转换网络地址转换NAT 网络地址转换是 netfilter 框架提供的核心功能之一,NAT 作为网络中非常重要的概念,在云原生场景下提供很多功能,包括:在多种 cni 插件的数据面设计中,依赖 nat 实现跨节点的 pod 之间的通信。通过 nat 实现 service 与 p
29、od 之间的负载均衡。iptables 和 ipvs 都可以实现 NAT 功能,其中 ipvs 通常都是用于对目的地址进行 NAT操作,也就是 DNAT,iptables 则具有包括 masquerade 在内的多种 NAT 组合而来的复杂功能,例如,在默认的 docker 容器访问公网的场景中,为了能够让节点内的,只有内网地址的 docker 容器可以正常访问公网,就需要添加如下的一条规则:#对于从 eth0 出节点的流量,访问目的为 123.12.23.43 的,自动将原地址切换为节点的出公网地址iptables-t nat-A POSTROUTING-o eth0-j SNAT-to 1
30、23.12.23.43iptables 的 NAT 有多个实现,目前版本较新并且被广泛采用的是基于 nft 的 iptables,对于 IPv4 协议,nft 实现的 NAT 功能在 netfilter 中注册的 hook 方法有如下几个:static const struct nf_hook_ops nf_nat_ipv4_ops=/*Before packet filtering,change destination*/.hook=nf_nat_ipv4_in,.pf=NFPROTO_IPV4,.hooknum=NF_INET_PRE_ROUTING,容器网络内核原理17.priority
31、=NF_IP_PRI_NAT_DST,/*After packet filtering,change source*/.hook=nf_nat_ipv4_out,.pf=NFPROTO_IPV4,.hooknum=NF_INET_POST_ROUTING,.priority=NF_IP_PRI_NAT_SRC,/*Before packet filtering,change destination*/.hook=nf_nat_ipv4_local_fn,.pf=NFPROTO_IPV4,.hooknum=NF_INET_LOCAL_OUT,.priority=NF_IP_PRI_NAT_DST
32、,/*After packet filtering,change source*/.hook=nf_nat_ipv4_fn,.pf=NFPROTO_IPV4,.hooknum=NF_INET_LOCAL_IN,.priority=NF_IP_PRI_NAT_SRC,;3)3)netfilternetfilter 在云原生中的应用在云原生中的应用基于基于 ipvsipvs 实现实现 ServiceServiceipvs 是基于 netfilter 框架实现的 Linux 内核态负载均衡器,通过 DNAT 方式来实现负载均衡,在云原生场景下,由于性能上的优势,ipvs 是实现 Service 功能
33、的首选,我们可以通过以下命令来简单的查看 Service 真正产生在网络数据面的 ipvs 规则:#查看 ipvs connection 信息,在出节点是,ipvs connection 是独立并且优先于conntrack 机制的选择,即流量会优先匹配到 ipvs 的规则,如果没有命中,才会进入conntrack 的匹配逻辑ipvsadm-Lnc#添加一个 service 192.168.1.100:80,将 192.168.1.123 作为他的一个 realserver 后端ipvsadm-A-t 192.168.1.100:80-s rripvsadm-a-t 192.168.1.100:
34、80-r 192.168.1.123-g-w 2容器网络内核原理18#查看不同的 ipvs service 的数据统计ipvsadm-Ln-stats基于基于 iptablesiptables 实现实现 NetworkPolicyNetworkPolicyNetworkPolicy 是云原生网络中非常重要的网络功能,其核心在于如何对流量进行权限管理,通常 cni 插件会采用 iptables 队 policy 未放行的流量进行屏蔽操作,实现NetworkPolicy 的功能。ipables 实现 NetworkPolicy 功能的数据面原理非常简单,通过白名单放行的方式,默认丢弃所有流量,只允
35、许白名单中的流量,即可实现简单的 NetworkPolicy 功能,我们可以通过以下几个命令简单模拟 iptables 实现的 NetworkPolicy:#默认丢弃所有流量iptables-A INPUT-j DROP#将 192.168.1.100 的 80 端口进行放行iptables-A INPUT-s 192.168.1.100-p tcp-m tcp-dport 80-j ACCEPT3.tc 子系统Linux Traffic Control(TC)子系统是 Linux 操作系统中用于对从网络设备驱动进出的流量进行分配,整形,调度以及其他修改操作的子系统,借助对数据包比较直接的处理
36、,可以实现流量控制,过滤,行为模拟和带宽限制等功能。1)1)LinuxLinux TrafficTraffic ControlControl 的核心原理的核心原理对于网络数据报文,网络设备驱动通过将二层的以太网数据报文按照 Linux 内核定义的网络设备驱动规范,以 sk_buff 结构体的方式进行接收或者发送,即通常我们所描述的报文的最小单元 skb。容器网络内核原理19内核通过将网络设备缓冲区环形队列中的 skb 取出,并按照以太网层,网络层,传输层的顺序处理后,将报文数据放置到对应的 Socket 缓冲区中,通知用户程序进行读取,从而完成收包。内核为 Socket 缓冲区的待发送数据封装
37、为 skb,经过传输层,网络层和以太网层依次填充对应的报头后,调用网络设备驱动的方法将 skb 发送到网络上,从而完成发包。TC子系统通过工作在网络设备驱动操作和内核真正进行每一层的收包与发包动作之间,按照不同的模式对数据包进行处理,实现复杂的功能。TC 子系统比较常见的作用是对需要发送的数据包进行操作,由于作为收包一侧的 Linux内核,无法控制所有发送方的行为,因此 TC 子系统主要的功能实现都是围绕着发送方向,以下介绍也都是基于发送方向的 TC 子系统进行。TCTC 子系统的关键概念子系统的关键概念TC 子系统与 netfilter 框架工作在内核网络数据处理流程的不同位置,相比于 ne
38、tfilter,TC 子系统工作的实际更加靠近网络设备,因此,在 TC 子系统的设计中,是与网络设备密不可分,在 TC 子系统中,有三个关键的概念用于对 TC 子系统的工作流程进行描述:Qdisc 是 queueing discipline 的简写,与我们理解的网卡的队列(queue)不同,qdisc 是 sk_buff 报文进行排队等待处理的队列,不同类型的 qdisc 有着不同的排队规则,TC 子系统会为每个网卡默认创建一个根队列,在跟队列的基础上,可以通过 Class 来创建不同的子队列,用于对流量进行分类处理。Class,如下图所示,class 将流量进行分类,不同分类的流量会进入不同
39、的 qdisc进行处理。Filter,如下图所示,filter 通过制定匹配的规则来实现将流量进行分类的作用,filter与 class 配合之后就可以降流量按照特征,采用不同的 qdisc 进行处理。容器网络内核原理20不同的 qdisc 之间的主要差别就是他们对排队的数据包进行调度的算法的区别,你可以通过一下命令查看网卡的 qdisc 信息:#查看 eth0 的 class 为 2 的流量的默认 qdisc,其中 handle 指代 qdisc id,parent指代 class idtc qdisc show dev eth0 handle 0 parent 2常见的 qdisc 包含以
40、下几种:mq(Multi Queue),即默认有多个 qdisc。fq_codel(Fair Queuing Controlled Delay),一种公平和随机分配流量带宽的算法,会根据数据包的大小,五元组等信息,尽量公平得分配不同的流之间的带宽。pfifo_fast,一种不分类的常见先进先出的队列,但是默认有三个不同的 band,可以支持简单的 tos 优先级。netem,network emulator 队列,常见的依赖 TC 子系统进行延迟,乱序和丢包模拟,都是通过 netem 来实现。clsact,这是 TC 子系统专门为了支持 eBPF 功能而提供的一种 qdisc 队列,在通过cl
41、ass 分配到这个 qdisc 之后,流量会触发已经挂载到 TC 子系统上的对应的 eBPF程序的处理流程。htb,一种通过令牌桶的算法对流量进行带宽控制的常用 qdisc,用于在单个往卡上对不同用户,场景的流量进行独立的带宽限流。容器网络内核原理21报文在报文在 TCTC 子系统的处理子系统的处理在 egress 方向,当以太网层完成数据报文 skb 的报头封装后,一个 skb 就可以直接调用网卡的方法进行发送了,而在 Linux 内核中,当以太网层完成封装并调用_dev_queue_xmit 时,会将 skb 放入他所在网络设备的 TC 队列中:static inline int c(st
42、ruct sk_buff*skb,struct Qdisc*q,struct net_device*dev,struct netdev_queue*txq)if(q-flags&TCQ_F_NOLOCK)if(unlikely(test_bit(_QDISC_STATE_DEACTIVATED,&q-state)_qdisc_drop(skb,&to_free);rc=NET_XMIT_DROP;else/对于大多数数据包,都会从这里进入 qdisc 进行排队rc=q-enqueue(skb,q,&to_free)&NET_XMIT_MASK;qdisc_run(q);if(unlikely(
43、to_free)kfree_skb_list(to_free);return rc;在入队动作发生后,内核一般都会直接进行一次 qdisc 的发包操作,将队列进行排序并按照规则发送符合条件的数据包:void _qdisc_run(struct Qdisc*q)int quota=dev_tx_weight;int packets;/每次 restart 都会发送数据包,直到发送完成,这并不意味着所有数据都发送完了,只是这次发送完成了条件while(qdisc_restart(q,&packets)quota-=packets;if(quota 22qdisc 每次被触发执行,都会将已经进入 q
44、disc 的数据进行入队操作,同时选择符合发送条件的数据包进行出队动作,也就是调用网卡的操作方法进行数据的发送,以pfifo_fast 为例:static int pfifo_fast_enqueue(struct sk_buff*skb,struct Qdisc*qdisc)/检测 Qdisc 队列数据包数量是否达到 dev 预定的最大值if(skb_queue_len(&qdisc-q)tx_queue_len)/确定数据包需要进入哪个通道int band=prio2bandskb-priority&TC_PRIO_MAX;struct pfifo_fast_priv*priv=qdisc
45、_priv(qdisc);/获取通道列表的 headstruct sk_buff_head*list=band2list(priv,band);priv-bitmap|=(1 q.qlen+;/添加到通道队尾return _qdisc_enqueue_tail(skb,qdisc,list);return qdisc_drop(skb,qdisc);static struct sk_buff*pfifo_fast_dequeue(struct Qdisc*qdisc)struct pfifo_fast_priv*priv=qdisc_priv(qdisc);int band=bitmap2ba
46、ndpriv-bitmap;if(likely(band=0)struct sk_buff_head*list=band2list(priv,band);struct sk_buff*skb=_qdisc_dequeue_head(qdisc,list);qdisc-q.qlen-;if(skb_queue_empty(list)priv-bitmap&=(1 23qdisc 流量控制由于设计非常复杂,所以很难简单概括其特性,通常在排查网络问题的过程中,我们需要了解的就是常见的 qdisc 的算法的大致工作原理,以及查看 qdisc 统计信息。2)Linux Traffic Control 在
47、云原生中的应用基于基于 CgroupCgroup 的网络数据包的网络数据包 QosQosCgroup 子系统是容器技术的基础,通常我们对 cgroup 的理解都在于 cgroup 通过cgroupfs 文件接口,让内核在为应用程序提供 cpu 时间片分配和内存分配的过程中遵循一定的配额限制,实际上 cgroup 在较早的版本中已经支持对某个 cgroup 中的网络流量进行优先级的调整,以实现单个节点内不同 cgroup 之间的 Qos 动作。Cgroup 子系统中提供网络流量优先级的功能为 net_cls 和 net_prio,需要配合 TC 子系统一起生效,例如,我们给某一个容器所在的 cg
48、roup 添加一个 net_cls 设置:mkdir/sys/fs/cgroup/net_cls/0echo 0 x100001/sys/fs/cgroup/net_cls/0/net_cls.classid在这里,我们选取了设定的 class 为 100001,然后,我们将 eth0 网卡的 root 根队列的 class 设置为 10,类型修改为 htb,用于进行限速:tc qdisc add dev eth0 root handle 10:htb我们在 10:这个根队列下,针对我们配置的 10:1 这个 class 配置带宽限流配置:tc class add dev eth0 paren
49、t 10:classid 10:1 htb rate 40mbit最后配置一个 filter,将 cgroup 流量引入到 10:1 的 class 中,完成对这个 cgroupnet_cls 的配置:tc filter add dev eth0 parent 10:protocol ip prio 10 handle 1:cgroup容器网络内核原理24而 net_prio 的原理则相对更加直观一点,通过在对应的 cgroup 路径中的 ifpriomap种配置网卡和对应的优先级数值,使对应的 cgroup 中管理的进程创建出来的 socket都具有priority属性,priority属性
50、会成为sk_buff结构体的属性从而携带到进入qdisc,如果 qdisc 支持优先级调度,则会根据 priority 来完成流量的 Qos,操作如下:echo eth0 5 /cgroup/net_prio/iscsi/net_prio.ifpriomap基于基于 TCTC eBPFeBPF 的高性能可编程数据面实现的高性能可编程数据面实现从上文的介绍中,我们了解到,在 eBPF 的多个内核提供的可执行的触发点中,TC 子系统是其中原生支持的一种,实际上,许多开源的解决方案也都选择 TC 子系统作为 eBPF程序执行的触发点,包括 cilium 和 terway。我们通过一个简单的 eBPF
51、 程序来对 TC 子系统支持 eBPF 的能力进行验证:首先,我们需要按照规范,在 TC 子系统提供的上下文环境中开发一个简单的 eBPF 程序:#include#include#include#include#ifndef _section#define _section(NAME)_attribute_(section(NAME),used)#endif#ifndef _inline#define _inlineinline _attribute_(always_inline)#endif#ifndef lock_xadd#define lock_xadd(ptr,val)(void)_s
52、ync_fetch_and_add(ptr,val)#endif#ifndef BPF_FUNC#define BPF_FUNC(NAME,.)容器网络内核原理25(*NAME)(_VA_ARGS_)=(void*)BPF_FUNC_#NAME#endifstatic void*BPF_FUNC(map_lookup_elem,void*map,const void*key);struct bpf_elf_map acc_map _section(maps)=.type=BPF_MAP_TYPE_ARRAY,.size_key=sizeof(uint32_t),.size_value=size
53、of(uint32_t),.pinning=PIN_GLOBAL_NS,.max_elem=2,;static _inline int account_data(struct _sk_buff*skb,uint32_t dir)uint32_t*bytes;bytes=map_lookup_elem(&acc_map,&dir);if(bytes)lock_xadd(bytes,skb-len);return TC_ACT_OK;_section(ingress)int tc_ingress(struct _sk_buff*skb)return account_data(skb,0);_sec
54、tion(egress)int tc_egress(struct _sk_buff*skb)return account_data(skb,1);char _license _section(license)=GPL;随后我们创建一个 clsact 类型的 qdisc,并且将流量全部定位到这个 qdisc 中:clang-g-O2-Wall-target bpf-I/iproute2/include/-c tc-example.c-o tc-example.o#创建一个 clsact 类型的 qdisc 作为 root 根 qdisc,然后加载 ebpf 程序到发送方向tc qdisc add
55、 dev enp3s0 clsact容器网络内核原理26tc filter add dev enp3s0 egress bpf da obj tc-example.o sec egress#通过 filter show 可以查看到网卡在 egress 上家在的 ebpf 程序tc filter show dev enp3s0 egress4.eBPF 技术eBPF 是 Linux 内核提供可以在不借助内核模块的场景下,对内核进行观测,注入来实现高阶功能的机制。eBPF 技术作为内核当前最为突破性的技术,具有轻量级,无侵入的特性,在排查网络问题上可以提供很多帮助,在当前的 eBPF 生态中,bp
56、ftrace 和 bcc 都提供了很多出色的功能协助我们进行观测,本章节会简单介绍 eBPF 的实现原理以及 eBPF 在云原生场景下的应用的简单介绍。eBPF 能够在实现接近内核模块的功能的基础上,具备上述的有点,得益于内核为 eBPF提供的多个改变:提供了高效的 jit,eBPF 的代码在内核中会被编译为机器码从而向真正的内核代码一样被执行。bpf()系统调用和map机制以及bpf helper辅助函数的提供,让内核操作更加便捷。内核在高频通用的代码中提供了安全的注入点,让 eBPF 程序只需要关注于代码逻辑。下图是 eBPF 程序的生命流程概述。容器网络内核原理27对于一个 eBPF 程
57、序来说,他的完整的生命流程包括:使用 eBPF 兼容的 C 语言子集进行代码开发,然后通过 clang 进行编译。通过各种开发框架进行初步的检查,然后通过 bpf()系统调用进行加载,在这个过程中会完成 map 的创建和替换以及符号的重定位。加载到内核的过程中,内核的 verifier 会对程序进行校验,如果通过了校验,则可以被 JIT 编译为字节码然后被添加到指定的位置。当内核代码执行到某个位置,内核会自动执行已经完成加载和attach的eBPF程序,例如 socket 的读取和写入会触发 sockops 这个执行点的 eBPF 程序的执行,完成流量的统计或者劫持动作。eBPF 在在安全,网
58、络和可观测行上都有很广泛的应用,也诞生了许多影响力较大的开源项目。容器网络内核原理28Linux 内核为提升可观测性而提供了多个可执行的点,我们常用的包括:kprobe,kretprobe,fentry,fexit 通过执行到某个函数是,触发 INT3 中断,使得eBPF 程序可以在进程现场状态下观测到信息。tracepoint 内核 的 debugfs 子系 统提供 的可供 执行的 点,内核 在固定 的tracepoint 会执行注册的 eBPF 程序。我们可以通过一些开源的项目很快体验到 eBPF 的价值,例如通过 bpftrace,我们能够很快看到所有经过内核的数据报文在 netfilt
59、er 中的返回值:bpftrace-e kretprobe:nf_hook_slow printf(%d%sn,retval,comm)此外,eBPF 在容器网络中也扮演着越来越关键的角色,包括 cilium,terway,calico 等多个知名的网络插件都开始使用 eBPF 来取代传统的 netfilter 框架等机制的作用,达到更加高效的抽象。全景剖析阿里云容器网络数据链路29二、全景剖析阿里云容器网络数据链路鸟瞰容器网络,整个容器网络可以分为三个部分:Pod 网段,Service 网段和 Node 网段。这三个网络要实现互联互通和访问控制,那么实现的技术原理是什么?整个链路又是什么,限
60、制又是什么呢?Flannel,Terway 有啥区别?不同模式下网络性能如何?这些,需要客户在下搭建容器之前,就要依据自己的业务场景进行选择,而搭建完毕后,相关的架构又是无法转变,所以客户需要对每种架构特点要有充分了解。比如下图是个简图,Pod网络既要实现同一个ECS的Pod间的网络互通和控制,又要实现不同ECSPod间的访问,Pod 访问 SVC 的后端可能在同一个 ECS 也可能是其他 ECS,这些在不同模式下,数据链转发模式是不同的,从业务侧表现结果也是不一样的。1.Flannel 模式架构设计Flannel 模式下,ECS 只有一个主网卡 ENI,无其他附属网卡,ECS 和节点上的 P
61、od 与外部通信都需要通过主网卡进行。ACK Flannel 会在每个节点创建 cni0 虚拟网卡作为Pod 网络和 ECS 的主网卡 eth0 之间的桥梁。全景剖析阿里云容器网络数据链路30集群的每个节点会起一个 flannel agent,并且会给每个节点预分配一个 Pod CIDR,这个 Pod CIDR 是 ACK 集群的 Pod CIDR 的子集。容器的网络命名空间内会有一个 eth0 的虚拟网卡,同时存在下一跳指向该网卡的路由,该网卡会作为容器和宿主内核进行数据交换的出入口。容器和宿主机之间的数据链路是通过 veth pair 进行交换的,现在我们已经找到 veth pair 其中
62、一个,如何去找另一个veth 呢?全景剖析阿里云容器网络数据链路31如上图所示,我们可以容器的网络命名空间中通过 ip addr 看到一个 eth0if8 的标志位,其中81 这个将会协助我们在 ECS 的 OS 内找到找到和容器网络命名空间中的 vethpair 相对一个。在 ECS OS 内我们通过 ip addr|grep 81:可以找到 vethd7e7c6fd 这个虚拟网卡,这个就是 veth pair 在 ECS OS 侧相对的那一个。到目前为止容器内和 OS 数据链路已经建立链接了,那么 ECS OS 内对于数据流量是怎么判断去哪个容器呢?通过 OS Linux Routing
63、我们可以看到,所有目的是 Pod CIDR 网段的流量都会被转发到 cni0 这张虚拟网卡,那么 cni0 是通过 bridge 方式将不同目的的数据链路指向到不同的 vethxxx。到这里为止,ECS OS 和 Pod 的网络命名空间已经建立好完整的出入链路配置了。全景剖析阿里云容器网络数据链路321)1)FlannelFlannel 模式容器网络数据链路剖析模式容器网络数据链路剖析针对容器网络特点,我们可以将 Flannel 模式下的网络链路大体分为以 Pod IP 对外提供服务和以 SVC 对外提供服务两个大的 SOP 场景,进一步细分可以拆分到 10 个不同的小的 SOP 场景。对这
64、10 个场景的数据链路梳理合并,这些场景可以归纳为下面 5 类典型的场景:Client 和服务端 Pod 部署于同一个 ECS;Client 和服务端 Pod 部署于不同 ECS;全景剖析阿里云容器网络数据链路33访问 SVC External IP,ExternalTrafficPolicy 为 Cluster 时,Client 和服务端 Pod部署于不同 ECS,其中 client 为集群外;访问 SVC External IP,ExternalTrafficPolicy 为 Local 时,Client 和服务端 Pod 部署于不同 ECS,其中 client 为集群内;访问 SVC E
65、xternal IP,ExternalTrafficPolicy 为 Local 时,Client 和服务端 Pod 部署于不同 ECS,其中 client 为集群外;2)2)场景一:场景一:ClientClient 和服务端和服务端 PodPod 部署于同一个部署于同一个 ECSECS此场景包含下面几个子场景,数据链路可以归纳为一种:以 Pod IP 对外提供服务,Client 和 Pod 部署于同一个节点;以 SVC ClusterIP 对外提供服务,Client 和 SVC 后端 Pod 部署于同一节点;以 SVC ExternalIP 对外提供服务,ExternalTrafficPol
66、icy 为 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 的默认路由。全景剖析阿里云容器网络数据链路34该容器 eth
67、0 在 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 网桥信息。全景剖析阿里云容器网络数据链路35小结小结可以访问到目的端数据链路转发示意图:全景剖析阿里云容器网络数据链路36内核协议栈示意图:数
68、据链路:ECS1 Pod1 eth0-vethxxx1-cni0-vethxxxx2-ECS1 Pod2 eth0;数据链路要经过三次内核协议栈,分别是 Pod1 协议栈,ECS OS 协议栈和 Pod2 协议栈;3)3)场景二:场景二:ClientClient 和服务端和服务端 PodPod 部署于不同部署于不同 ECSECS此场景包含下面几个子场景,数据链路可以归纳为一种:以 Pod IP 对外提供服务,Client 和 Pod 部署于不同节点;以 SVC ClusterIP 对外提供服务,Client 和 SVC 后端 Pod 部署于不同节点;以 SVC ExternalIP 对外提供服
69、务,ExternalTrafficPolicy 为 Cluster 情况下,集群内 Client 和 SVC 后端 Pod 部署于不同节点;环境环境全景剖析阿里云容器网络数据链路37ap-southeast-1.10.0.0.180 节点上存在两个 pod:centos-67756b6dc8-rmmxt IP地址 172.23.96.23 和 nginx1-76c99b49df-7plsr IP 地址 172.23.96.163Service nginx1 的 ExternalTrafficPlicy 为 Cluster。内核路由内核路由Pod 网络空间和 ECS OS 网络空间的数据交换在
70、2.1 场景一中已经做了详细描述,此处不再果断篇幅描述。源端源端 PodPod 所在所在 ECSECS 的的 IPVSIPVS 规则规则可以看到,源端数据链路访问 svc 的 clusterip 192.168.13.23 时,如果链路到达 ECS的 OS 内,会命中 ipvs 规则,被解析到 svc 的后端 endpoint 之一(本实例中只有一个pod,所以 endpoint 只有一个)。小结小结可以成功访问到目的端数据链路转发示意图:全景剖析阿里云容器网络数据链路38VPC 路由表会自动配置目的地址是 pod CIDR,下一跳为 Pod 网段所归属的 ECS 的自定义路由条目,该规则由
71、ACK 管控测通过 openapi 调用 VPC 去配置,无需手动配置和删除。内核协议栈示意图:全景剖析阿里云容器网络数据链路39Conntack 表信息(访问 SVC 情况)Node1:src 是源 pod IP,dst 是 svc 的 ClusterIP,并且期望是由 svc 的其中一个 endpoint172.23.96.163 来回消息给源端 pod。Node2:目的 pod 所在 ECS 上 conntrack 表记录是由源端 pod 访问目的 pod,不会记录 svc的 clusterip 地址。数据链路:ECS1 Pod1 eth0-vethxxx1-cni0-ECS 1 eth
72、0-VPC-ECS2eth0-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 内后,会命中相应的
73、 IPVS 规则,并根据负载规则,选择 IPVS 的某一个后端,进而打到其中的一个 SVC 的后端 endpoint,SVC的 IP 只会再 Pod 的 eth0,veth pair vethxxx 被捕捉到,其他链路环节不会捕捉到 svc 的 IP;全景剖析阿里云容器网络数据链路404)4)场景三:场景三:ExternalTrafficPolicyExternalTrafficPolicy 为为 LocalLocal 时,时,ClientClient 和服务端和服务端 PodPod 部部署于集群内不同署于集群内不同 ECSECS此场景包含下面几个子场景,数据链路可以归纳为一种:以 SVC E
74、xternalIP 对外提供服务,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.163Service nginx1 ExternalTrafficPolicy 为 Local。内核路由内核路由Pod 网络空间和 ECS OS 网络空间的数据交换在 2.1 场景一中已
75、经做了详细描述,此处不再果断篇幅描述。全景剖析阿里云容器网络数据链路41源端源端 PodPod 所在所在 ECSECS 的的 IPVSIPVS 规则规则可以看到,源端数据链路访问 svc 的 externalip 8.219.164.113 时,如果链路到达 ECS的 OS 内,会命中 ipvs 规则,但是我们可以看到 EcternalIP 并没有相关的后端endpoint,链路达到 OS 后,会命中 IPVS 规则,但是没有后端 pod,所以会出现connection refused。小结小结不可以访问到目的端,此时会访问失败,Connection refused数据链路转发示意图:内核协议
76、栈示意图:全景剖析阿里云容器网络数据链路42数据链路: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 官方推荐的最佳实践
77、;5)场景四:场景四:ExternalTrafficPolicyExternalTrafficPolicy 为为 LocalLocal 时,时,ClientClient 来自于集群外来自于集群外此场景包含下面几个子场景,数据链路可以归纳为一种:A.访问 SVC External IP,ExternalTrafficPolicy 为 Local 时,Client 和服务端 Pod 部署于不同 ECS,其中 client 为集群外。环境Deployment 为 nginx1,分别为三个 pod nginx1-76c99b49df-4zsdj 和nginx1-76c99b49df-7plsr 部署在
78、 ap-southeast-1.10.0.1.206ECS 上,最后一个pod nginx1-76c99b49df-s6z79 部署在其他节点 ap-southeast-1.10.0.1.216 上Service nginx1 的 ExternalTrafficPlicy 为 Local。全景剖析阿里云容器网络数据链路43内核路由内核路由Pod 网络空间和 ECS OS 网络空间的数据交换在 2.1 场景一中已经做了详细描述,此处不再果断篇幅描述。SLBSLB 相关配置相关配置从 SLB 控制台,可以看到 SLB 后端的虚拟服务器组中只有两个 ECS 节点ap-southeast-1.10.0
79、.1.216 和 ap-southeast-1.10.0.1.206。集群内的其他节点,比如 ap-southeast-1.10.0.0.180 并未被加到 SLB 的后端虚拟服务器组中。虚拟服务器组的 IP 为 ECS 的 IP,端口为 service 里面的 nodeport 端口 32580。故故 ExternalTrafficPolicyExternalTrafficPolicy 为为 LocalLocal 模式下模式下,只有有只有有 ServiceService 后端后端 podpod 所在的所在的 ECSECS 节点节点才会被加入到才会被加入到 SLBSLB 的后端虚拟服务器组中,
80、参与的后端虚拟服务器组中,参与 SLBSLB 的流量转发,集群内的其他节点的流量转发,集群内的其他节点不参与不参与 SLBSLB 的转发的转发。SLBSLB 虚拟服务器组虚拟服务器组 ECSECS 的的 IPVSIPVS 规则规则从 SLB 的虚拟服务器组中的两个 ECS 可以看到,对于 nodeip+nodeport 的 ipvs 转发规则是不同。ExternalTrafficPolicy 为 Local 模式下,只有该节点上的护短 pod 才会被加到该节点的 ipvs 转发规则中,其他节点上的后端 pod 不会加进来,这样保证了被全景剖析阿里云容器网络数据链路44SLB 转发的链路,只会被
81、转到该节点上的 pod,不会转发到其他节点上。node1:ap-southeast-1.10.0.1.206node1:ap-southeast-1.10.0.1.216小结小结可以访问到目的端数据链路转发示意图:该图示意了只有后端 pod 所在 ECS 才会加到 SLB 后端中,从集群外部访问 SVC 的externalIP(SLB IP)的情况,可见数据链路只会被转发到虚拟服务器组中的 ECS,不会再被转发到集群内其他节点上。全景剖析阿里云容器网络数据链路45内核协议栈示意图:Conntack 表信息Node:src 是集群外部客户端 IP,dst 是节点 IP,dport 是 SVC 中
82、的 nodeport。并且期望是由该 ECS 上的 pod 172.23.96.82 来回包给源端。数据链路:client-SLB-ECS eth0+ECS nodeport-cni0-vethxxxxx-ECS1Pod1 eth0;数据链路要经过两次内核协议栈,分别是 Pod1 协议栈,ECS1 OS 协议栈;ExternalTrafficPolicy 为 Local 模式下,只有有 Service 后端 pod 所在的 ECS 节点才会被加入到 SLB 的后端虚拟服务器组中,参与 SLB 的流量转发,集群内的其他节点不参与 SLB 的转发;全景剖析阿里云容器网络数据链路466)场景五:场景
83、五:ExternalTrafficPolicyExternalTrafficPolicy 为为 ClusterCluster 时,时,ClientClient 来自于集群外来自于集群外此场景包含下面几个子场景,数据链路可以归纳为一种:访问 SVCExternal IP,ExternalTrafficPolicy 为 Cluster 时,Client 和服务端 Pod 部署于不同 ECS,其中 client 为集群外。环境环境Deployment 为 nginx1,分别为三个 pod nginx1-76c99b49df-4zsdj 和nginx1-76c99b49df-7plsr 部署在 ap-
84、southeast-1.10.0.1.206ECS 上,最后一个pod nginx1-76c99b49df-s6z79 部署在其他节点 ap-southeast-1.10.0.1.216 上Service nginx2 的 ExternalTrafficPlicy 为 Cluster。内核路由内核路由Pod 网络空间和 ECS OS 网络空间的数据交换在 2.1 场景一中已经做了详细描述,此处不再果断篇幅描述。SLBSLB 相关配置相关配置从 SLB 控制台,集群内所有所有节点 ap-southeast-1.10.0.0.180、ap-southeast-1.10.0.1.216和ap-sou
85、theast-1.10.0.1.206都被加到SLB的虚拟服务全景剖析阿里云容器网络数据链路47器组中。其中虚拟服务器组的 IP 为 ECS 的 IP,端口为 service 里面的 nodeport 端口30875。故故ExternalTrafficPolicExternalTrafficPolicy y 为为CLusteCLuster r 模式下模式下,集群内所有集群内所有的的ECECS S节点都会被加入节点都会被加入到到SLSLB B的后端虚拟服务器组中,参与的后端虚拟服务器组中,参与 SLBSLB 的流量转发。的流量转发。SLBSLB 虚拟服务器组虚拟服务器组 ECSECS 的的 IP
86、VSIPVS 规则规则从 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-southea
87、st-1.10.0.0.180(该节无后端 pod)全景剖析阿里云容器网络数据链路48小结小结可以访问到目的端数据链路转发示意图:该图示意了集群内所有 ECS都会被加到SLB 后端中,从集群外部访问SVC 的externalIP(SLB IP)的情况,数据流量可能会被转发到其他节点上。内核协议栈示意图:内核协议栈示意图已经在 2.4 场景一中已经做了详细描述,此处不再过多篇幅描述。Conntack 表信息链路 1:ap-southeast-1.10.0.0.180:此时数据链路对应示意图中的链路 1,可以看到数据链路被转到全景剖析阿里云容器网络数据链路49ap-southeast-1.10.0
88、.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-7plsrPod,部署在 ap-southeast-1.10.0.1.206。ap-southeast-1.10.0.1.206:通过此节点 conntrack 表,可以看到 src 是 node ap-southeast-1.1
89、0.0.0.180,dst是 172.23.96.163 的 80 端口,回包也是直接回给 node ap-southeast-1.10.0.0.180。综上可以看到综上可以看到 srcsrc 变换了多次,故在变换了多次,故在 CLusterCLuster 模式下,会存在丢失真实客户端模式下,会存在丢失真实客户端 IPIP 的情的情况况。链路 2:src 是集群外部客户端 IP,dst 是节点 IP,dport 是 SVC 中的 nodeport。并且期望是由该 ECS 上的 pod 172.23.96.82 来回包给 172.23.96.65,此地址是 SLB 集群中的一个地址。数据链路:情
90、景一:client-SLB-ECS eth0+ECS nodeport-cni0-vethxxxxx-ECS1Pod1 eth0;情景二:client-SLB-ECS1 eth0+ECS1 nodeport-VPC Routing-ECS2 eth0+Pod port-cni0-vethxxxxx-ECS2 Pod1 eth0;数据链路要经过三次内核协议栈,分别是 ECS1 OS、ECS2 OS 协议栈和 Pod 协议栈;全景剖析阿里云容器网络数据链路50ExternalTrafficPolicy 为 CLuster 模式下,kubernetes 所有 ECS 节点都会被加入到 SLB 的后端
91、虚拟服务器组中,参与 SLB 的流量转发,此时会存在数据路在集群内被多个 ECS 转发的场景,该情况下会丢失真实客户端 IP 的情况;7)7)小结小结本节主要聚焦 ACK 在 Flannel 模式下,不同 SOP 场景下的数据链路转发路径。随着微服务化和云原生化,网络场景日趋复杂,作为 kubernetes 原生的网络模型Flannel,不同的访问环境,一共可以分为 10 个 SOP 场景。通过深入简出的剖析,可以归纳为 5个场景,并对这五个场景的转发链路,技术实现原理,云产品配置等一一梳理并总结,这对我们遇到 Flannel 架构下的链路抖动、最优化配置,链路原理等提供了初步指引方向。2.T
92、erway ENI 模式架构设计Terway ENI 模式下,ENI 的网络都是和 VPC 同样的网段,ENI 网络就是从 Aliyun 的VPC 网络中创建和绑定一个弹性网卡到 ECS 节点上,然后 Pod 利用这个弹性网卡和别的网络互通,这里需要关注的是弹性网卡的数量是有限制的,具体的根据实例类型有不同的配额。全景剖析阿里云容器网络数据链路51Pod 所使用的的 CIDR 网段和节点的 CIDR 是同一个网段。pod 内部可以看到是有两张网卡的,一个是 eth0,另一个是 veth1,其中 eth0 的 IP就是 Pod 的 IP,此网卡的 MAC 地址和控制台上的 ENI 的 MAC 地
93、址可以匹配,说明此此网卡就是附属网卡就是附属 ENIENI 网卡,被直接挂载到了网卡,被直接挂载到了 PodPod 的网络命名空间内。的网络命名空间内。Pod 内有指向 eth0 的默认路由,同时还有指向目的网段为 192.168.0.0/16,下一跳为veth1 网卡的路由,其中 192.168.0.0/16 网段为集群的 service 网段,说明集群内 Pod全景剖析阿里云容器网络数据链路52访问 SVC 的 clusterIP 网段,数据链路会经过 veth1 网卡到宿主机 ECS 的 OS 内进行下一步判断,其他情况是走 eth0 直接进入到 VPC。如上图所示,我们可以容器的网络命
94、名空间中通过 ip addr 看到一个 veth1if19 的标志位,其中19 这个将会协助我们在 ECS 的 OS 内找到找到和容器网络命名空间中的veth pair 相对一个。在 ECS OS 内我们通过 ip addr|grep 19:可以找到cali38ef34581a9 这个虚拟网卡,这个就是 veth pair 在 ECS OS 侧相对的那一个。到目前为止,容器访问 SVC 的 ClusterIP 时,容器和 OS 数据链路已经建立链接了,那么 ECS OS 内对于数据流量是怎么判断去哪个容器呢?通过 OS Linux Routing 我们可以看到,所有目的是 Pod CIDR 网
95、段的流量都会被转发到 Pod 对应的 calico 虚拟往卡上,到这里为止,ECS OS 和 Pod 的网络命名空间已经建立好完整的出入链路配置了。全景剖析阿里云容器网络数据链路531 1)TerwayTerway ENIENI 模式容器网络数据链路剖析模式容器网络数据链路剖析针对容器网络特点,我们可以将 Terway ENI 模式下的网络链路大体分为以 Pod IP 对外提供服务和以 SVC 对外提供服务两个大的 SOP 场景,进一步细分可以拆分到 8 个不同的小的 SOP 场景。对这 8 个场景的数据链路梳理合并,这些场景可以归纳为下面 8 类典型的场景:TerwayENI 架构下,不同的
96、数据链路访问情况下,可以总结归纳为为 8 类:访问 Pod IP,同节点访问 pod;全景剖析阿里云容器网络数据链路54访问 Pod IP,同节点 pod 间互访;访问 Pod IP,异节点 pod 间互访;集群内访问 SVC IP(Cluster IP),源端和 SVC 后端 Pod 为同一节点;集群内访问 SVC IP(Cluster IP),源端和 SVC 后端 Pod 为不同节点;集群内访问 SVC IP(External IP),源端和 SVC 后端 Pod 为同一节点;集群内访问 SVC IP(External IP),源端和 SVC 后端 Pod 为不同节点;集群外访问 SVC
97、External IP;2 2)场景一:访问场景一:访问 PodPod IPIP,同节点访问,同节点访问 podpod环境环境ap-southeast-1.10.0.0.196 节点上存在 nginx1-5969d8fc89-9t99h 和 10.0.0.203。内核路由内核路由nginx1-5969d8fc89-9t99h IP 地址 10.0.0.203,该容器在宿主机表现的 PID 是1094736,该容器网络命名空间有指向容器 eth0 的默认路由。和下一跳为 veth1,目的网段为 service 的两条路由。全景剖析阿里云容器网络数据链路55该容器 veth1 在 ECS OS 内
98、对应 veth pair 是 cali5068e632525。在 ECS OS 内,有指向 Pod IP,下一跳为为 calixxxx 的路由,通过前文可以知道 calixxx网卡是和每个 pod 内的 veth1 组成的 pair,所以,pod 内访问 SVC 的 CIDR 会有指向veth1 的路由,不会走默认的 eth0 路由。故:calixx 网卡在这里的主要作用是用于:节点访问 Pod 2.当节点或者 Pod 访问 SVC 的 CIDR 时,会走 ECS OS 内核协议栈转换,走到 calixxx 和 veth1 访问 pod。全景剖析阿里云容器网络数据链路56小结小结可以访问到目的
99、端nginx1-5969d8fc89-9t99h netns veth1 可以抓到数据包。nginx1-5969d8fc89-9t99h cali5068e632525 可以抓到数据包。全景剖析阿里云容器网络数据链路57数据链路转发示意图:数据链路是 ECS-Linux routing-calicxxx-Pod net ns veth1。数据链路完成,宿主机 ns 切换至 Pod ns;通过宿主机上的路由切换至 pod 所属的 veth pair;该网卡为被分配的 pod 独占,无法和其他 pod 进行共享;数据链路经过两次协议栈;3)3)场景二:访问场景二:访问 PodPod IPIP,同节
100、点,同节点 podpod 访问访问 podpod环境环境全景剖析阿里云容器网络数据链路58ap-southeast-1.10.0.0.196 节点上存在两个 pod:centos-59cdc5c9c4-89f8x IP 地址 10.0.0.202 和 nginx1-5969d8fc89-9t99h 和 10.0.0.203。内核路由内核路由centos-59cdc5c9c4-89f8x IP 地址 10.0.0.202,该容器在宿主机表现的 PID 是2314075,该容器网络命名空间有指向容器 eth0 的默认路由。和下一跳为 veth1,目的网段为 service 的两条路由。通过上述类似
101、的办法,可以找到 nginx1-5969d8fc89-9t99hIP 地址 10.0.0.203,该容器在宿主机表现的 PID 是 1094736。小结小结可以访问到目的端全景剖析阿里云容器网络数据链路59centos-59cdc5c9c4-89f8x netns eth1 可以抓到数据包。nginx1-5969d8fc89-9t99h netns eth1 可以抓到数据包。数据链路转发示意图:数据链路转发示意图:全景剖析阿里云容器网络数据链路60数据链路是 Pod1 netns eth1-VPC-Pod2 netns eth2。数据链路不经过宿主机host namespace,数据链路会先出
102、 ECS,到 VPC 再回到原来的 ECS;在 pod 内的 net namespace 中,直接命中默认路有规则,从 eth0 网卡出 pod 直接到 VPC。这里的 eth0 其实就是附属网卡 ENI,直接被挂载在了 pod 的 net ns,走了 PCI 网卡;该网卡为被分配的 pod 独占,无法和其他 pod 进行共享;数据链路经过两次协议栈;4)4)场景三:访问场景三:访问 PodPod IPIP,异节点,异节点 podpod 访问访问 podpod环境环境全景剖析阿里云容器网络数据链路61ap-southeast-1.10.0.0.196 节点上存在 pod:centos-59cd
103、c5c9c4-89f8x IP 地址10.0.0.202。ap-southeast-1.10.0.2.80节点上存在pod:nginx-6f545cb57c-jmbrq和10.0.2.86。内核路由内核路由centos-59cdc5c9c4-89f8x IP 地址 10.0.0.202,该容器在宿主机表现的 PID 是2314075,该容器网络命名空间有指向容器 eth0 的默认路由。和下一跳为 veth1,目的网段为 service 的两条路由。通过上述类似的办法,可以找到 nginx-6f545cb57c-jmbrq IP 地址 10.0.2.86,该容器在宿主机表现的 PID 是 108
104、3623。全景剖析阿里云容器网络数据链路62小结小结可以访问到目的端centos-59cdc5c9c4-89f8x netns eth0 可以抓到数据包。nginx-6f545cb57c-jmbrq netns eth0 可以抓到数据包。全景剖析阿里云容器网络数据链路63数据链路转发示意图:数据链路转发示意图:数据链路是 ECS1 Pod1 netns eth0-VPC-ECS2 Pod2 netns eth0。数据链路不经过宿主机 host namespace,数据链路会先出 ECS1,到 AVS 再回到 ECS2;全景剖析阿里云容器网络数据链路64在 pod 内的 net namespac
105、e 中,直接命中默认路有规则,从 eth0 网卡出 pod 直接到 VPC。这里的 eth0 其实就是附属网卡 ENI,直接被挂载在了 pod 的 net ns,走了 PCI 设备;该网卡为被分配的 pod 独占,无法和其他 pod 进行共享;数据链路经过两次协议栈;5)5)场景四:集群内访问场景四:集群内访问 SVCSVC IPIP(ClusterCluster IPIP),源端和,源端和 SVCSVC 后端后端 PodPod 为为同一节点同一节点环境环境ap-southeast-1.10.0.0.196 节点上存在两个 pod:centos-59cdc5c9c4-89f8x IP 地址 1
106、0.0.0.202 和 nginx1-5969d8fc89-9t99h 和 10.0.0.203。Service是nginx1集群内clusterIP是192.168.41.244,external IP是8.219.175.179。内核路由内核路由centos-59cdc5c9c4-89f8x IP 地址 10.0.0.202,该容器在宿主机表现的 PID 是2314075,该容器网络命名空间有指向容器 eth0 的默认路由。和下一跳为 veth1,目的网段为 service 的两条路由。全景剖析阿里云容器网络数据链路65该容器 eth0 在 ECS OS 内对应 veth pair 是 c
107、ali38ef34581a9。通过上述类似的办法,可以找到 nginx1-5969d8fc89-9t99hIP 地址 10.0.0.203,该容器在宿主机表现的 PID 是 1094736,该容器 eth0 在 ECS OS 内对应 veth pair 是cali5068e632525。全景剖析阿里云容器网络数据链路66在 ECS OS 内,有指向 Pod IP,下一跳为为 calixxxx 的路由,通过前文可以知道 calixxx网卡是和每个 pod 内的 veth1 组成的 pair,所以,pod 内访问 SVC 的 CIDR 会有指向veth1 的路由,不会走默认的 eth0 路由。故
108、calixx 网卡在这里的主要作用是用于:节点访问 Pod 2.当节点或者 Pod 访问 SVC的 CIDR 时,会走 ECS OS 内核协议栈转换,走到 calixxx 和 veth1 访问 pod。全景剖析阿里云容器网络数据链路67小结小结可以访问到目的端centos-59cdc5c9c4-89f8x netns veth1 可以抓到数据包。centos-59cdc5c9c4-89f8x netns cali38ef34581a9 可以抓到数据包。全景剖析阿里云容器网络数据链路68nginx1-5969d8fc89-9t99h netns veth1 可以抓到数据包。nginx1-5969
109、d8fc89-9t99h netns cali5068e632525 可以抓到数据包。全景剖析阿里云容器网络数据链路69数据链路转发示意图:数据链路转发示意图:数据链路是 ECS1 Pod1 netns veth1-calixxx1-calixxx2-ECS2 Pod2 netnsveth1;在 pod 内的 net namespace 中,命中 svc 的路由,从 veth1 网卡出 pod 到 ECS的 namespace,然后通过 linux routing 转到另一个 pod 的 calixx 网卡。这里的veth1 和 calixxx 是 veth pair;源端 pod 所分配的
110、veth,calicoxxx 网卡可以捕获到 svc IP 和源端 pod IP。SVC IP会在源端 ECS host 内命中 ipvs/iptables 规则,做了 nat 转化;目的段 pod 所分配的 veth,calicoxxx 网卡可以捕获 calicoxxx 网卡默认 ip 和目的pod IP;该网卡为被分配的 pod 独占,无法和其他 pod 进行共享;数据链路经过三次协议栈:Pod1,ECS OS 和 Pod2;全景剖析阿里云容器网络数据链路706)6)场景五:集群内访问场景五:集群内访问 SVCSVC IPIP(ClusterCluster IPIP),源端和,源端和 SV
111、CSVC 后端后端 PodPod 为为不同节点不同节点环境环境ap-southeast-1.10.0.0.196 节点上存在 pod:centos-59cdc5c9c4-89f8x IP 地址10.0.0.202。ap-southeast-1.10.0.2.80节点上存在pod:nginx-6f545cb57c-jmbrq和10.0.2.86。Service 是 nginx 集群内 clusterIP 是 192.168.204.233,external IP 是 8.219.199.33。内核路由内核路由centos-59cdc5c9c4-89f8x IP 地址 10.0.0.202,该容器
112、在宿主机表现的 PID 是2314075,该容器网络命名空间有指向容器 eth0 的默认路由。和下一跳为 veth1,目的网段为 service 的两条路由。该容器 eth0 在 ECS OS 内对应 veth pair 是 cali38ef34581a9。全景剖析阿里云容器网络数据链路71通过上述类似的办法,可以找到 nginx-6f545cb57c-jmbrqIP 地址 10.0.2.86,该容器在宿主机表现的 PID 是 1083623,该 pod 网卡 ENI 是直接被挂载到了 Pod 的网络命名空间内。小结小结可以访问到目的端全景剖析阿里云容器网络数据链路72数据链路转发示意图:数据
113、链路转发示意图:数据链路是 ECS1 Pod1 netns veth1-cali38ef34581a9-ECS1 eth0-VPC-ECS2 Pod2 netns veth1;在客户端 pod 内的 net namespace 中,命中 svc 的路由,从 veth1 网卡出 pod到 ECS 的 namespace,然后通过 linux routing 转到客户端 ECS eth0 网卡,然后进入到 vpc 转发到目的 Pod 所属的 eth 网卡;源端 pod 所分配的 veth,calicoxxx 网卡可以捕获到 svc IP 和源端 pod IP;SVC IP 会在源端 ECS hos
114、t 内命中 ipvs/iptables 规则,做了 fnat 转化。在源端 ECS所属的 eth0 只能捕获到 ipvs/iptables 规则所分配的目的 pod IP 和源 ECS IP;目的 pod 内 eth0 所捕获的 IP 是源端 ECS IP 和目的 POD IP。(源 POD IP 和 SVC IP不会体现);该网卡为被分配的 pod 独占,无法和其他 pod 进行共享;数据链路经过三次协议栈:Pod1,ECS1 OS 和 Pod2;7)7)场景六场景六:集群内访问集群内访问 SVCSVC IPIP(ExternalExternal IPIP),源端和源端和 SVCSVC 后端
115、后端 PodPod 为为同一节点同一节点环境环境全景剖析阿里云容器网络数据链路73ap-southeast-1.10.0.0.196 节点上存在两个 pod:centos-59cdc5c9c4-89f8x IP 地址 10.0.0.202 和 nginx1-5969d8fc89-9t99h 和 10.0.0.203Service 是 nginx1 集群内 clusterIP 是 192.168.221.163,external IP 是 10.0.2.89。内核路由内核路由centos-59cdc5c9c4-89f8x IP 地址 10.0.0.202,该容器在宿主机表现的 PID 是2314
116、075,该容器网络命名空间有指向容器 eth0 的默认路由。和下一跳为 veth1,目的网段为 service 的 ClusterIP 的两条路由。SLBSLB 相关配置相关配置在 SLB 控制台,可以看到虚拟服务器组的后端只有 nginx1-5969d8fc89-9t99h 的 ENIeni-t4n6qvabpwi24w0dcy55。综上,可以判断如果访问的是 SVC 的 External IP,是走默认路由 eth0,直接出 ECS 进全景剖析阿里云容器网络数据链路74入到 avs,访问到 SLB 的实例,再由 SLB 实例转发到后端 eni 上。小结小结可以访问到目的端数据链路转发示意图
117、:数据链路转发示意图:数据链路是 ECS1 Pod1 netns eth0-VPC-SLB-VPC-ECS1 Pod2 netnseth0。数据链路不经过宿主机 host namespace,数据链路会先出 ECS1,到 AVS再回到 ECS1;在 pod 内的 net namespace 中,直接命中默认路有规则,从 eth0 网卡出 pod 直接到 VPC。这里的 eth0 其实就是附属网卡 ENI,直接被挂载在了 pod 的 net ns,走了 PCI 设备;全景剖析阿里云容器网络数据链路75该网卡为被分配的 pod 独占,无法和其他 pod 进行共享;与 2.4 场景可以看到非常大的不
118、同,虽然都是前后端 Pod 都是部署在同一个 ECS访问 SVC 的 IP,但是可以看到如果访问的是 SVC 的 ClusterIP,则数据链路会进入到 ECS OS 层面,会经过三次协议栈;如果访问的是 External IP,则不会经过 ECSOS,直接出 ECS,经过 SLB 转发到目的 Pod 上,只经过两次协议栈(Pod1 和 Pod2);8)8)场景七:集群内访问场景七:集群内访问 SVCSVC IPIP(ExternalExternal IPIP),源端和,源端和 SVCSVC 后端后端 PodPod 为为不同节点不同节点环境环境ap-southeast-1.10.0.0.196
119、 节点上存在 pod:centos-59cdc5c9c4-89f8x IP 地址10.0.0.202。ap-southeast-1.10.0.2.80节点上存在pod:nginx-6f545cb57c-jmbrq和10.0.2.86。Service 是 nginx 集群内 clusterIP 是 192.168.254.141,external IP 是 10.0.2.90。内核路由内核路由centos-59cdc5c9c4-89f8x IP 地址 10.0.0.202,该容器在宿主机表现的 PID 是2314075,该容器网络命名空间有指向容器 eth0 的默认路由。和下一跳为 veth1,
120、目的网段为 service 的 ClusterIP 的两条路由。全景剖析阿里云容器网络数据链路76SLBSLB 相关配置相关配置在 SLB 控制台,可以看到 lb-t4nih6p8w8b1dc7p587j9 虚拟服务器组的后端只有nginx-6f545cb57c-jmbrq 的 ENI eni-t4n5kzo553dfak2sp68j。综上,可以判断如果访问的是 SVC 的 External IP,是走默认路由 eth0,直接出 ECS 进入到 avs,访问到 SLB 的实例,再由 SLB 实例转发到后端 eni 上。全景剖析阿里云容器网络数据链路77小结小结可以访问到目的端数据链路转发示意图
121、:数据链路转发示意图:数据链路是 ECS1 Pod1 netns eth0-VPC-SLB-VPC-ECS2 Pod2 netnseth0。数据链路不经过宿主机 host namespace,数据链路会先出 ECS1,到 SLB再回到 ECS2;在 pod 内的 net namespace 中,直接命中默认路有规则,从 eth0 网卡出 pod 直接到 VPC。这里的 eth0 其实就是附属网卡 ENI,直接被挂载在了 pod 的 net ns,走了 PCI 设备;该网卡为被分配的 pod 独占,无法和其他 pod 进行共享;与 2.5 场景可以看到非常大的不同,虽然都是前后端 Pod 都是部
122、署在不同 ECS 访问 SVC 的 IP,但是可以看到如果访问的是 SVC 的 ClusterIP,则数据链路会进入到ECS OS 层面,通过 ECS 的 eth0 出 ECS,进入到 AVS,会经过三次协议栈;如果访问的是 External IP,则不会经过 ECS OS,直接通过 Pod 所属的的附属 ENI 出ECS,经过 SLB 转发到目的 Pod 上,只经过两次协议栈(Pod1 和 Pod2);9)9)场景八:集群外访问场景八:集群外访问 SVCSVC ExternalExternal IPIP环境环境全景剖析阿里云容器网络数据链路78ap-southeast-1.10.0.2.80
123、节点上存在pod:nginx-6f545cb57c-jmbrq和10.0.2.86。ap-southeast-1.10.0.1.233 节点上存在 pod:nginx-6f545cb57c-25k9z 和10.0.1.239。Service 是 nginx 集群内 clusterIP 是 192.168.254.141,external IP 是 10.0.2.90。SLBSLB 相关配置相关配置在 SLB 控制台,可以看到 lb-t4nih6p8w8b1dc7p587j9 虚拟服务器组的后端服务器组是两个后端 nginxPod 的的 ENI eni-t4n5kzo553dfak2sp68j
124、和eni-t4naaozjxiehvmg2lwfo。从集群外部角度看,SLB 的后端虚拟服务器组是 SVC 的后端 Pod 所属的两个 ENI 网卡,内网的 IP 地址就是 Pod 的地址。没有经过后端 Pod 所在的 ECS 的 OS 层面,直接进入到了 OS 的的协议栈。全景剖析阿里云容器网络数据链路79小结小结可以访问到目的端数据链路转发示意图:数据链路转发示意图:数据链路:client-SLB-Pod ENI+Pod Port-ECS1 Pod1 eth0;数据链路要经过一次内核协议栈,是 Pod1 协议栈;10)10)小结小结本篇文章主要聚焦 ACK 在 Terway ENI 模式下
125、,不同 SOP 场景下的数据链路转发路径。伴随着客户对性能的极致追求的需求,在 Terway ENI 模式下,一共可以分为 8 个 SOP场景,并对这八个场景的转发链路,技术实现原理,云产品配置等一一梳理并总结,这对我们遇到 Terway ENI 架构下的链路抖动、最优化配置,链路原理等提供了初步指引方向。在 Terway ENI 模式下,ENI 是以 PCI 方式直接挂载到 Pod 的命名空间内,这就以为 ENI 属于被分配的 Pod 独享,而 ECS 所能部署的 Pod 数量取决于 ECS 所能挂载 ENI 网卡数量的限制,而这个限制和 ECS 的实例规格类型有关,比如神龙 ecs.ebm
126、g7.32xlar全景剖析阿里云容器网络数据链路80ge,128C 512GB 也只支持最多 32 个 ENI,这往往会造成资源的浪费和部署密度的降低,为了解决这个资源效率问题,ACK 带来了 Terway ENIIP 的方式,来实现 ENI 网卡可以被多个 Pod 所共享,这大大增加了单个 ECS 上的 Pod 数量 quota,提升了部署密度,这也是目前线上集群采用最多的架构。下一系列我们将进入到 Terway ENIIP 模式的全景解析。3.Terway ENIIP 模式架构设计弹性网卡(ENI)支持配置多个辅助 IP 的功能,单个弹性网卡(ENI)根据实例规格可以分配6-20 个辅助
127、IP,ENI 多 IP 模式就是利用了这个辅助 IP 分配给容器,从而大幅提高了Pod 部署的规模和密度。在网络联通的方式上,Terway 支持选择 Veth pair 策略路由和 ipvlan l 两种方案,Terway 主要考虑了这些:在节点上如何把弹性网卡(ENI)的辅助 IP 的流量都走对应的弹性网卡出去,并使用弹性网卡本身的 mac 地址而不被丢包;2.如何兼容容器服务目前广泛的 Centos 7.x 的 3.10 的版本的内核;全景剖析阿里云容器网络数据链路81Pod 所使用的的 CIDR 网段和节点的 CIDR 是同一个网段。pod 内部可以看到是有一张网卡的,一个是 eth0,
128、其中 eth0 的 IP 就是 Pod 的 IP,此网卡的 MAC 地址和控制台上的 ENI 的 MAC 地址不一致,同时 ECS 上有多张 ethx 的网卡,说明 ENI 附属网卡并不是直接挂在到了 Pod 的网络命名空间。全景剖析阿里云容器网络数据链路82Pod 内有只有指向 eth0 的默认路由,说明说明 PodPod 访问任何地址段都是从访问任何地址段都是从 eth0eth0 为统一的为统一的出入口。出入口。如上图所示,我们可以容器的网络命名空间中通过 ip addr 看到一个 eth0if63 的标志位,其中63 这个将会协助我们在 ECS 的 OS 内找到找到和容器网络命名空间中的
129、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 的网络命名空间已经建立好完整的出入链路配置了。全景剖析阿里云容器网络数据链路83在 veth pair 中实现了多个 Pod 共享一个 ENI 的方式来提升了
130、 ECS 的 Pod 部署密度,那么如何知道 Pod 是被分配到哪个 ENI 呢?TerwayPod 是通过 daemonset 的方式部署在每个节点上的,通过下面命令可以看到每个节点上的 TerwayPod。通过 terway-clishow factory 命令可以看到节点上的附属 ENI 数量、MAC 地址以及每个 ENI 上的 IP。全景剖析阿里云容器网络数据链路84故 Terway ENIIP 模式总体可以归纳为:在网络联通的方式上,采用选择 Veth pair 策略路由。一对 veth pair 来联通宿主机和 pod 的网络空间,pod 的地址是来源于弹性网卡的辅助 IP 地址,
131、并且节点上需要配置策略路由来保证辅助 IP 的流量经过它所属的弹性网卡。同主机上的容器通信直接通过主机上的路由到同一个主机上别的容器对应的 veth上。不同主机的容器通信经过 VPC 的网络进行转发到对应的机器上,再通过机器上的路由转发到容器中。容器和其所在的宿主机之间的通信直接通过连接到宿主机 namespace 的 vethpair 和路由打通。容器到其他主机通过 VPC 的网络转发到对应的机器,其他主机到容器通过 VPC 网络转发到对应的弹性网卡,然后通过路由转发到容器的 Veth 上。容器到专线和共享服务也都是通过 VPC 的网络转发。容器到公网的访问经过 VSwitch 配置的 SN
132、AT 网关直接将源 IP 转换成 EIP 的地址到外部网络。弹性网卡(ENI)支持配置多个辅助 IP 的功能,单个弹性网卡(ENI)根据实例规格可以分配 6-20 个辅助 IP,ENI 多 IP 模式就是利用了这个辅助 IP 分配给容器,从而大幅提高了 Pod 部署的规模和密度。1)1)TerwayTerway ENIIPENIIP 模式容器网络数据链路剖析模式容器网络数据链路剖析针对容器网络特点,我们可以将 Terway ENI 模式下的网络链路大体分为以 Pod IP 对外提供服务和以 SVC 对外提供服务两个大的 SOP 场景,进一步细分,可以归纳为 7 个不同的小的 SOP 场景。全景
133、剖析阿里云容器网络数据链路85对这 8 个场景的数据链路梳理合并,这些场景可以归纳为下面 8 类典型的场景:TerwayENI 架构下,不同的数据链路访问情况下,可以总结归纳为为 8 类:访问 Pod IP,同节点访问 Pod访问 Pod IP/SVC IP(Cluster or Local),同节点 pod 间互访(pod 属于同 or 不同ENI)访问 PodIP,异节点 pod 间互访集群内非 SVC 后端 pod 所在节点访问 SVC ClusterIPCluster 模式,集群内非 SVC 后端 pod 所在节点访问 SVC External IPLocal 模式,集群内非 SVC
134、后端 pod 所在节点访问 SVC External IP集群外访问 SVC External IP2)2)场景一:访问场景一:访问 PodPod IPIP,同节点访问,同节点访问 podpod环境环境全景剖析阿里云容器网络数据链路86cn-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 内对
135、应 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。全景剖析阿里云容器网络数据链路87小结小结可以访问到目
136、的端nginx-7d6877d777-zp5jg netns eth0 可以抓到数据包。nginx-7d6877d777-zp5jg calif03b26f9a43 可以抓到数据包。全景剖析阿里云容器网络数据链路88数据链路转发示意图:数据链路转发示意图:会经过calicao网卡,每个非hostnetwork的pod会和calicao网卡形成veth pair,用于和其他 pod 或 node 进行通信。整个链路不会和请求不会经过pod所分配的ENI,直接在OS的ns中命中Ip rule 被转发。整个请求链路是 OS-calixxxxx-ECSPod net eth0。整个链路会经过两次内核协
137、议栈:ECS OS 和 Pod。数据链路要经过两次内核协议栈,是 Pod1 协议栈、ECS1 协议栈。全景剖析阿里云容器网络数据链路893 3)场景二:访问场景二:访问 PodPod IP/SVCIP/SVC IP(ClusterIP(Cluster oror Local)Local),同节点,同节点 podpod 访访问问podpod(podpod 属于同属于同 oror 不同不同 ENIENI)环境环境cn-hongkong.10.0.1.82 节点上存在 nginx-7d6877d777-zp5jg 和 10.0.1.104cn-hongkong.10.0.1.82 节点上存在 cent
138、os-67756b6dc8-h5wnp 和 10.0.1.91Service 是 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。全景剖析阿里云容器网络数据链路90用上述类似办法可以发现 centos-67756b6dc8-h5wnp 的 v
139、eth 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。全景剖析阿里云容器网络数据链路91
140、说明相关的路由转发是在 ECS OS 层面进行的,Pod 的 calixx 网卡起到了一个桥梁和连通的作用。源端源端 ECSECS 上的上的 IPVSIPVS 规则(如果访问的是规则(如果访问的是 SVCSVC IPIP)如果同节点上访问的是 SVC 的 IP(ClusterIP or ExternalIP),在节点上我们查看 SVC的相关 IPVS 转发规则:ServiceService 的的 ExternalTrafficPolicyExternalTrafficPolicy 是是 LocalLocalSVC nginx CLusterIP 是 192.168.2.115,External
141、IP 是 10.0.3.62。后端是 10.0.1.104和 10.0.3.58。全景剖析阿里云容器网络数据链路92cn-hongkong.10.0.1.82对于 SVC 的 ClusterIP,可以看到 SVC 的后端两个 Pod 都会被加到 IPVS 的转发规则。对于 SVC 的 ExternalIP,可以看到 SVC 的后端,只有该节点的后端 Pod 10.0.1.104 才会被加到 IPVS 的转发规则在在LoadBalanceLoadBalancer r 的的SVSVC C模式下模式下,如如果果ExternalTrafficPolicExternalTrafficPolicy y 为
142、为LocalLocal,对对于于ClusterIClusterIP P来说,会把所有来说,会把所有 SVCSVC 后端后端 PodPod 都会加到该节点的都会加到该节点的 IPVSIPVS 转发规则;对于转发规则;对于 ExternalIPExternalIP,只会把该节点上的只会把该节点上的 SVCSVC 后端后端 PodPod 才会加到才会加到 IPVSIPVS 规则中。如果该节点没有规则中。如果该节点没有 SVCSVC 后后端端PodPod,则该节点上的,则该节点上的 PodPod 访问访问 SVCSVC 的的 ExternalIPExternalIP 将会是失败。将会是失败。Servi
143、ceService 的的 ExternalTrafficPolicyExternalTrafficPolicy 是是 ClusterClusterSVC nginx1 CLusterIP 是 192.168.2.253,ExternalIP 是 10.0.3.63,后端是 10.0.1.104和 10.0.3.58全景剖析阿里云容器网络数据链路93cn-hongkong.10.0.1.82对于 SVC 的 ClusterIP,可以看到 SVC 的后端两个 Pod 都会被加到 IPVS 的转发规则。对于 SVC 的 ExternalIP,可以看到 SVC 的后端两个 Pod 都会被加到 IPVS
144、 的转发规则。在在 LoadBalancerLoadBalancer 的的 SVCSVC 模式下,如果模式下,如果 ExternalTrafficPolicyExternalTrafficPolicy 为为 ClusterCluster,对,对于于ClusterIPClusterIP 或或 ExternalIPExternalIP 来说,会把所有来说,会把所有 SVCSVC 后端后端 PodPod 都会加到该节点的都会加到该节点的 IPVSIPVS 转发转发规则。规则。小结小结可以访问到目的端全景剖析阿里云容器网络数据链路94ConntrackConntrack 表信息表信息ServiceSe
145、rvice nginxnginx 的的 ExternalTrafficPolicyExternalTrafficPolicy 是是 LocalLocal。SVC nginx CLusterIP 是 192.168.2.115,ExternalIP 是 10.0.3.62。后端是 10.0.1.104和 10.0.3.58。如果访问的是 SVC 的 ClusterIP,通过 conntrack 信息,可以看到 src 是源端 Pod10.0.1.91,dst 是 SVC ClusterIP 192.168.2.115,dport 是 SVC 中的 port。并且期望是 10.0.1.104 来回
146、包给 10.0.1.91。如果访问的是 SVC 的 ExternalIP,通过 conntrack 信息,可以看到 src 是源端 Pod10.0.1.91,dst 是 SVC ExternalIP 10.0.3.62。dport 是 SVC 中的 port。并且期望是 10.0.1.104 来回包给 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。如
147、果访问的是 SVC 的 ClusterIP,通过 conntrack 信息,可以看到 src 是源端 Pod10.0.1.91,dst 是 SVC ClusterIP 192.168.2.253,dport 是 SVC 中的 port。并且期望是 10.0.1.104 来回包给 10.0.1.91。如果访问的是 SVC 的 ExternalIP,通过 conntrack 信息,可以看到 src 是源端 Pod10.0.1.91,dst 是 SVC ExternalIP 10.0.3.63,dport 是 SVC 中的 port。并且期望是节点 ECS 的 IP 10.0.1.82 来回包给 1
148、0.0.1.91。全景剖析阿里云容器网络数据链路95综上可以看到 src 变换了多次,故在 Cluster 模式下,会存在丢失真实客户端 IP 的情况。数据链路转发示意图:数据链路转发示意图:会经过calicao网卡,每个非hostnetwork的pod会和calicao网卡形成veth pair,用于和其他 pod 或 node 进行通信;整个链路不会和请求不会经过pod所分配的ENI,直接在OS的ns中命中Ip rule 被转发;整个请求链路是ECS1 Pod1 eth0-Pod1 calixxxx-Pod2 calixxxx-ECS1 Pod2eth0;访问 SVC IP,SVC 会在源
149、端 pod eth0 和 calixxx 网卡捕捉到,在目的端 pod 的eth0 和 calixxx 时捕捉不到;在 LoadBalancer 的 SVC 模式下,如果 ExternalTrafficPolicy 为 Local,对于ClusterIP 来说,会把所有 SVC 后端 Pod 都会加到该节点的 IPVS 转发规则;对于ExternalIP,只会把该节点上的 SVC 后端 Pod 才会加到 IPVS 规则中;全景剖析阿里云容器网络数据链路96在 LoadBalancer 的 SVC 模式下,如果 ExternalTrafficPolicy 为 Cluster,对于ClusterI
150、P 或 ExternalIP 来说,会把所有 SVC 后端 Pod 都会加到该节点的 IPVS 转发规则,同时无法保留 src 地址;数据链路要经过三次内核协议栈,是 Pod1 协议栈、ECS1 协议栈、Pod2 协议栈;4)4)场景三:访问场景三:访问 PodIPPodIP,异节点,异节点 podpod 间互访间互访环境环境cn-hongkong.10.0.1.82 节点上存在 centos-67756b6dc8-h5wnp 和 10.0.1.91cn-hongkong.10.0.3.49 节点上存在 nginx-7d6877d777-lwrfc 和 10.0.3.58。内核路由内核路由ce
151、ntos-67756b6dc8-h5wnp IP 地址 10.0.1.104,该容器在宿主机表现的 PID 是2211426,该容器网络命名空间有指向容器 eth0 的默认路由。用上述类似办法可以发现 centos-67756b6dc8-h5wnp 的 veth pair 的cali44ae9fbceeb,Pod 网络空间只有默认路由。全景剖析阿里云容器网络数据链路97在 ECS OS 内,有指向 Pod IP,下一跳为为 calixxxx 的路由,通过前文可以知道 calixxx网卡是和每个 pod 内的 veth1 组成的 pair,所以,pod 内访问 SVC 的 CIDR 会有指向ve
152、th1 的路由,不会走默认的 eth0 路由。故:calixx 网卡在这里的主要作用是用于:1.节点访问 Pod 2.当节点或者 Pod 访问 SVC 的 CIDR 时,会走 ECS OS 内核协议栈转换,走到 calixxx 和 eth0 访问 pod,对于目的为外部地址,则走 Pod 所属的 ENI 出 ECS 进入到了 VPC。全景剖析阿里云容器网络数据链路98小结小结可以访问到目的端数据链路转发示意图:数据链路转发示意图:会经过calicao网卡,每个非hostnetwork的pod会和calicao网卡形成veth pair,用于和其他 pod 或 node 进行通信;整个链路请求会
153、经过 pod 所分配的 ENI,直接在 OS 的 ns 中命中 Ip rule 被转发;出 ECS 后,根据要访问的 pod 和该 pod ENI 所属 vswitch,命中 VPC 路由规则或者直接 VSW 上的二层转发;整个请求链路是 ECS1 Pod1 eth0-ECS1 Pod1 calixxxxx-ECS1 ethx-vpcroute rule(如有)-ECS2 ethx-ECS2 Pod2 calixxxxx-ECS2 Pod2 eth0;数据链路要经过四次内核协议栈,Pod1 协议栈、ECS1 协议栈、Pod2 协议栈、ECS2协议栈;全景剖析阿里云容器网络数据链路995)5)场
154、景四:群内非场景四:群内非 SVCSVC 后端后端 podpod 所在节点访问所在节点访问 SVCSVC ClusterIPClusterIP环境环境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。Service1 是 nginx,ClusterIP 是 192.168.2.115 ExternalIP 是 10.0.3.62。Service2 是 ngin1,ClusterIP 是 192.
155、168.2.253 ExternalIP 是 10.0.3.63。内核路由内核路由内核路由部分已经在 2.2 和 2.3 小结中详细说明,这里不再进行过多阐述。源端源端 ECSECS 上的的上的的 IPVSIPVS 规则规则根据 2.2 小结中的源端 ECS 上的 IPVS 规则,我们可以得到:无论在哪种 SVCSVC 模式下模式下,对于对于 ClusterIPClusterIP 来说,会把所有来说,会把所有 SVCSVC 后端后端 PodPod 都会加到该节点的都会加到该节点的 IPVSIPVS 转发规则转发规则。小结小结可以访问到目的端全景剖析阿里云容器网络数据链路100Conntrack
156、 表信息Service nginx 的 ExternalTrafficPolicy 是 LocalSVC nginx CLusterIP 是 192.168.2.115,ExternalIP 是 10.0.3.62。后端是 10.0.1.104和 10.0.3.58cn-hongkong.10.0.1.82源端 ECS 上 src 是源端 Pod 10.0.1.91,dstdst 是是 SVCSVC ClusterIPClusterIP 192.168.2.115192.168.2.115,dport是 SVC 中的 port。并且期望是 10.0.3.58 来回包给 10.0.1.91。cn
157、-hongkong.10.0.3.49目的端 ECS 上 src 是源端 Pod 10.0.1.91,dstdst 是是 PodPod 的的 IPIP 10.0.3.5810.0.3.58,port 是 pod 的port。并且期望此 pod 来回包给 10.0.1.91。Service nginx1 的 ExternalTrafficPolicy 是 ClusterCluster。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
158、源端 ECS 上 src 是源端 Pod 10.0.1.91,dstdst 是是 SVCSVC ClusterIPClusterIP 192.168.2.115192.168.2.115,dport是 SVC 中的 port。并且期望是 10.0.3.58 来回包给 10.0.1.91。全景剖析阿里云容器网络数据链路101cn-hongkong.10.0.3.49目的端 ECS 上 src 是源端 Pod 10.0.1.91,dstdst 是是 PodPod 的的 IPIP 10.0.3.5810.0.3.58,dport 是 pod的 port。并且期望此 pod 来回包给 10.0.1.9
159、1。对于 ClusterIP 来说,源端 ECS 会把所有 SVC 后端 Pod 都会加到该节点的 IPVS 转发规则,目的端 ECS 是捕获不到任何 SVC ClusterIP 信息的,只能捕获到源端 Pod 的 IP,所以回包的时候会回到源端 Pod 的附属网卡上。数据链路转发示意图:数据链路转发示意图:会经过calicao网卡,每个非hostnetwork的pod会和calicao网卡形成veth pair,用于和其他 pod 或 node 进行通信;整个链路请求会经过 pod 所分配的 ENI,直接在 OS 的 ns 中命中 Ip rule 被转发;出 ECS 后,根据要访问的 pod
160、 和该 pod ENI 所属 vswitch,命中 VPC 路由规则或者直接 VSW 上的二层转发;整个请求链路是去方向:ECS1 Pod1 eth0-ECS1 Pod1 calixxxxxx-ECS1 主网卡 eth0-vpc route全景剖析阿里云容器网络数据链路102rule(如有)-ECS2 附属网卡 ethx-ECS2 Pod2 calixxxxx-ECS2 Pod2 eth0;回方向:ECS2 Pod2 eth0-ECS2 Pod2 calixxxxx-ECS2 附属网卡 ethx-vpc routerule(如有)-ECS1 附属网卡 eth1-ECS1 Pod1 calixx
161、xxxx-ECS1 Pod1 eth0;对于 ClusterIP 来说,源端 ECS 会把所有 SVC 后端 Pod 都会加到该节点的 IPVS 转发规则,目的端 ECS 是捕获不到任何 SVC ClusterIP 信息的,只能捕获到源端 Pod的 IP,所以回包的时候会回到源端 Pod 的附属网卡上;数据链路要经过四次内核协议栈,Pod1 协议栈、ECS1 协议栈、Pod2 协议栈、ECS2协议栈;6 6)场景五:场景五:ClusterCluster 模式,集群内非模式,集群内非 SVCSVC 后端后端 podpod 所在节点访问所在节点访问 SVCSVCExternalExternal I
162、PIP环境环境cn-hongkong.10.0.3.49 节点上存在 nginx-7d6877d777-h4jtf 和 10.0.3.58cn-hongkong.10.0.1.82 节点上存在 centos-67756b6dc8-h5wnp 和 10.0.1.91Service2 是 ngin1,ClusterIP 是 192.168.2.253 ExternalIP 是 10.0.3.63。内核路由内核路由内核路由部分已经在 2.2 和 2.3 小结中详细说明,这里不再进行过多阐述。全景剖析阿里云容器网络数据链路103源端源端 ECSECS 上的上的 IPVSIPVS 规则规则根据 2.2
163、小结中的源端 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源端 E
164、CS 上 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目的端 ECS 上 src 是源端 Pod 所在的 ECS 地址 10.0.1.82,dst 是 Pod 的 IP 10.0.3.58,dport 是 pod 的 port。并且期望此 pod 来回包给源端 ECS 的地址 10.0.1.82。全景剖析阿里云容器网络数据链路104在在 ExternalTrafficPol
165、icyExternalTrafficPolicy 为为 ClusterCluster 下,对于下,对于 ExternalIPExternalIP 来说,源端来说,源端 ECSECS 会把所会把所有有SVCSVC 后端后端 PodPod 都会加到该节点的都会加到该节点的 IPVSIPVS 转发规则,目的端转发规则,目的端 ECSECS 是捕获不到任何是捕获不到任何 SVCSVCExternalIPExternalIP 信息的信息的,只能捕获到源端只能捕获到源端 PodPod 所在的所在的 ECSECS 的的 IPIP,所以回包的时候会回到源所以回包的时候会回到源端端 PodPod 所在的所在的
166、ECSECS 的主网卡上,这一点明显和的主网卡上,这一点明显和 2.42.4 小结中访问小结中访问 CusterIPCusterIP 有很明显区有很明显区别。别。数据链路转发示意图:数据链路转发示意图:会经过calicao网卡,每个非hostnetwork的pod会和calicao网卡形成veth pair,用于和其他 pod 或 node 进行通信;整个链路请求会经过 pod 所分配的 ENI,直接在 OS 的 ns 中命中 Ip rule 被转发;出 ECS 后,根据要访问的 pod 和该 pod ENI 所属 vswitch,命中 VPC 路由规则或者直接 VSW 上的二层转发;整个请求
后浪研究所:2022年轻人小快乐报告(15页).pdf
赛迪顾问:2022中国数字经济发展研究报告(49页).pdf
2022企业私域体系化建设的思考与实践(19页).pdf
方正证券:2022证券行业行为数据根基建设白皮书(40页).pdf
东方财富:2022全球锂资源十年周期全面复盘和未来展望报告(41页).pdf
MCU行业深度:技术趋势、市场现状、产业链及相关公司深度梳理-230110(27页).pdf
博威合金-公司首次覆盖报告:高端铜合金长坡厚雪行业先锋厚积薄发-230110(40页).pdf
安彩高科-公司研究报告-打造“玻璃+天然气”业务协同走出光伏+光热玻璃差异化优势-230110(37页).pdf
华锐精密-公司深度报告:硬质合金数控刀片先进制造商产品升级促业绩增长-230109(29页).pdf
电气设备行业:锂电新技术大圆柱虽迟但到产业链或乘风起-230110(28页).pdf
巨子生物 -公司研究报告-乘重组胶原蛋白东风破美丽健康之浪-230110(39页).pdf
建筑材料行业报告:房地产需求端政策放松消费建材基本面回暖可期-230110(15页).pdf
中国BI商业智能行业报告(50页).pdf
2020“618”年中大促盘点(25页).pdf
See Data:密码行业系列深度报告(32页).pdf
SeeData:瓷砖行业专题分析(20页).pdf
2020中国社会化媒体营销市场分析报告(42页)(1).pdf
大学生行为分析专题报告2019(25页).pdf
Smaato:2019上半年全球应用内广告趋势报告(英文版)(24页).pdf
三茅:2019HR生存发展白皮书(116页).pdf
纷析智库:2019年中国市场八大主流数字营销与运营分析工具评测报告(55页).pdf
【研报】信创行业专题报告:信创必由之路发展时不我待-20200708[28页].pdf
链塔智库:2019数字钱包研究报告(15页).pdf
Social Media Examiner:2019年社交媒体营销行业报告(英文版).pdf
云服务器可观测能力的探索与实践-云上运维最佳实践论坛(19页).pdf
高洪涛-云原生的可观测性与 Apache SkyWalking_(GOTC深圳会场)(31页).pdf
阿里云企业级自治数据库RDS 详解-企业级云原生数据库最佳实践分论坛(31页).pdf
数据库游戏行业最佳实践-企业级云原生数据库最佳实践分论坛(19页).pdf
基于云原生数据仓库AnalyticDB PG 的最佳实践(19页).pdf
云原生开源数据湖最佳实践-开源大数据与AI行业实践论坛(16页).pdf
深度解析云原生数据库技术趋势与最佳实践-云原生分布式数据库PolarDB技术与实践论坛(27页).pdf
云原生数据库解决方案-加速企业国产化升级-企业级云原生数据库最佳实践分论坛(14页).pdf
精品游戏兴起阿里云上DDoS最佳实践-原生一体化云安全论坛(22页).pdf
传统数据库上云最佳实践-友邦保险-云原生分布式数据库PolarDB技术与实践论坛(15页).pdf
蜜雪冰城招股说明书-连锁茶饮第一股(724页).pdf
线上健身第一股-keep招股说明书(463页).pdf
麦肯锡:2023中国消费者报告:韧性时代(33页).pdf
罗振宇2023“时间的朋友”跨年演讲完整PDF.pdf
QuestMobile:2022新中产人群洞察报告(37页).pdf
QuestMobile:2022年中国短视频直播电商发展洞察报告(30页).pdf
町芒:2022现制茶饮行业研究报告(47页).pdf
小红书:2023年度生活趋势报告(34页).pdf
QuestMobile:2021新中产人群洞察报告(30页).pdf
锐仕方达&薪智:2022年薪酬白皮书(105页).pdf