虚拟网络排查问题困难,传统的traceroute等工具很难起到太大作用,大部分情况下都需要到宿主机、混合云网关上抓包来troubleshooting,耗时又费力。有些场景中包的传送路径比较长(如跨域、混合云等),可能丢包的地方比较多,更增加了故障排查的难度。
为此,我们设计了一款支持全链路大规模的网络连通性内部检测系统BigBrother。基于TCP报文的染色可将检测报文和用户流量区分开,能支持物理云和跨地域的复杂场景,还打造了完整的检测框架,帮助运维同事直接定位故障点,或一键判断虚拟网络是否存在问题。
BigBrother上线后即用于云主机迁移前后的连通性验证,保证出现异常后可以及时告警回滚。从8月初至今历时两个月,共迁移2000多台主机,及时发现迁移异常近10起。
在设计BigBrother这前,我们也有第一代的网络连通性检查工具,原理就是通过SSH跳转到目标宿主机上,利用ovs的packet out命令将构造的报文发出去,最后在对端的宿主机上tcpdump该报文,从而验证两端的连通性。但是从它的原理就不难看出,这种检测方式有着很大的缺点:
因此做一款支持全链路大规模的连通性检测系统是非常有必要的,我们的目标就是让运维、NOC的同学能够迅速发现并解决网络不通的问题,同时为我们的虚拟网络服务变更保驾护航。
BigBrother(下文简称BB)一词源自乔治奥威尔的小说《1984》,将此检测系统命名为BigBrother寓意就是可以将全网资源连通情况都实时监控起来。整个BB检测系统由若干个组件配合完成,mafia提供console进行创建及展示task的结果,minitrue用于将用户传入的参数转化为注包的范围,telescreen用于构造报文及收发报文。
在具体介绍BB的原理前,我们先来看两个概念。在我们的虚拟网络中,每个实例(uhost、umem、udb等)都是通过接入点来接入虚拟网络,接入点由两部分组成:
例如在公有云场景中,entrypoint和endpoint都是openvswitch,而在物理云场景中,entrypoint是我们的物理云转发网关(vpcgw、hybridgw),endpoint则是物理云主机的上联ToR。
场景 | Entrypoint | Endpoint |
---|---|---|
公有云 | ovs | ovs |
物理云 | vpcgw、hybridgw | ToR |
托管云 | hcgw、cloudgw | PE |
跨域网关 | sdngw | ovs |
公共服务 | ovs | ovs |
CNAT | ovs | ovs |
托管云(UXR) | UXR | PE |
跨域网关(UXR) | UXR | ovs |
CNAT(UXR) | UXR | ovs |
以上就是各种场景中的接入点说明,之所以要明确这两个概念,是因为在BB系统中,我们将Entrypoint作为注包点,向其发送GRE探测报文,同时将Endpoint作为采样点,Endpoint会识别并镜像特殊的探测报文至BB。
检测方案如图所示,可分为两部分组成,在图中的流向分为橙色和紫色。
以橙色流向部分为例(SRC->DST):
1)BigBrother模拟DST向Endpoint发送探测报文;
2)SRC端Entrypoint收到该探测报文后转发给Endpoint;
3)Endpoint将该报文镜像至BigBrother;
4)Endpoint将报文正常转发至实例;
5)实例回复报文给Endpoint;
6)Endpoint收到该回复报文后进行GRE封装,然后镜像至BigBrother;
7)Endpoint将报文正常转发至Entrypoint;
8)SRC Entrypoint将回复报文发送至DST Entrypoint;
9)DST Entrypoint收到回复报文后发送给Endpoint;
10)DST Endpoint将回复报文镜像至Bigbrother。
至此,单边的检测结束。在检测过程中,BigBrother发送了1个探测报文,共收到了3个采样报文,通过分析这3个采样点可以确认SRC->DST方向是否通信正常。
反之亦然,紫色部分原理相同。全部检测结束后,BigBrother共可以收到6个探测报文,如果6个报文均收到则表示连通性正常。
上文中介绍了BB的检测流程,下面我们再来看下探测报文及转发面的设计实现。公有云和混合云的设计存在很多不同。公有云转发面需要在全局hook点(table_1),分别hook探测报文的request和response,然后进行染色、镜像至BB等步骤。而混合云转发面则需要ToR、PE交换机开启ERSPAN功能,将染色的报文镜像至BB即可。
整体数据包交互如下图所示:
而一个合格的探测报文首先应该具备以下特征:
因此我们详细比较了如下两种候选方案。
1)icmp + tos方案
第一种方案以icmp报文为载体,使用tos对icmp_request进行染色,采集时将此tos的icmp报文镜像至BB即可。
cookie=0x20008,table=1,priority=40000,metadata=0x1,icmp,icmp_type=8,icmp_code=0,nw_tos=0x40 actions=Send_BB(),Learn(),Back_0()
对于hook icmp_request的flow可以简化为如下逻辑:action部分主要由三部分组成:
# 1. ????????REG3 ????64200
# (global hook) reg3 load:64200->NXM_NX_REG3[],
# 2. learn action learn(table=31,idle_timeout=2,hard_timeout=4,priority=30000,dl_type=0x0800,ip_proto=1,icmp_type=0,icmp_code=0,NXM_OF_IP_SRC[]=NXM_OF_IP_DST[],NXM_OF_IP_DST[ ]=NXM_OF_IP_SRC[],Stain(),Send_BB()),
# 3. REG3 0
load:0->NXM_NX_REG3[]
对于hook icmp_reply的flow可以简化为如下逻辑:
cookie=0x20008,table=1,priority=40000,metadata=0x1,icmp,icmp_type=0,icmp_code=0,nw_tos=0x40
action部分主要由四部分组成:
以上讨论的是公有云侧ovs的染色及镜像方法,而混合云侧就需要交换机ERSPAN来进行支持,为了使ERSPAN规则可以镜像tos染色报文,需要GRE外层Ip Header中的tos继承overlay Ip Header中标记的tos,所以需要全网对GRE隧道设置继承内层tos的隧道属性,执行命令如下:
ovs-vsctl set in <gre_iface_name> options:tos=inherit
此种方案虽然可以实现染色及镜像的功能,但是hook点预埋的flow过于复杂,不容易维护,最关键的一点在于,混合云网络中,该方案无法支持 learn flow,所以无法对反向的流量进行染色。
2)tcp方案
第二种方案以tcp报文为载体,使用特定的端口作为染色条件,采集时将此源目端口的tcp报文镜像至BB即可。
cookie=0x20008,table=1,priority=40000,tcp,metadata=0x1,tp_src=[port],tp_dst=[port]
actions=Send_BB(),Back_0()
对于hook tcp_request的flow可以简化为如下逻辑:
action部分主要由两部分组成:
以上两种方案进行对比不难看出,第一种方案依赖较多并且适用场景受限,所以BB采用的是第二种方案。但是tcp方案也有一定的缺陷,如何选择染色的port并且要与用户的流量区分开来,这是一个难点。经过我们几次踩坑后分析,最后决定使用tcp源目port=11来进行染色(目前已告知用户会使用TCP 端口11进行扫描,详见文档),报文如下图所示。
BB被设计为支持多种网络场景,能应对物理云和跨域互通的网络复杂性。这章节我们以探测物理云和跨域为例,详细分析下BB探测报文的生命周期。
公有云互通物理云场景下,探测报文生命周期如下:
公有云—> 物理云
1)BigBrother向公有云宿主机发送探测报文
2)ovs收到报文后镜像至BigBrother
3)ovs将报文送至实例
4)实例回应报文
5)ovs将回应报文镜像至BigBrother
6)物理云核心交换机收到报文,并发送给汇聚交换机
7)8)9)10)物理云汇聚交换机发送报文给vpcgw,vpcgw处理报文后回送至汇聚交换机
11)在物理云汇聚交换机配置ERSPAN,将报文镜像至BigBrother。
物理云—> 公有云
1)BigBrother向vpcgw发送探测报文
2)3)vpcgw处理报文后回送至汇聚交换机
4)在物理云汇聚交换机配置ERSPAN,将报文镜像至BigBrother
5)汇聚交换机将报文送至phost的上联Tor
6)Tor将报文送至phost
7)phost回应报文
8)在phost的上联Tor配置ERSPAN,将报文镜像至BigBrother
9)报文送至公有云宿主机ovs
10)ovs收到报文后镜像至BigBrother
公有云跨域互通场景下,探测报文生命周期如下:
本地域—> 地域B
1)BigBrother 向本域主机发送探测报文
2)ovs收到报文后镜像至BigBrother
3)ovs将报文送至实例
4)实例回应报文
5)ovs将回应报文镜像至BigBrother
6)ovs将报文送至sdngw
7)sdngw将报文镜像至BigBrother
地域B—> 本地域
1)BigBrother 向本域sdngw发送探测报文
2)sdngw收到报文后镜像至BigBrother
3)sdngw将报文送至对端sdngw进行转发
4)本域sdngw收到对端回应报文
5)sdngw将回应报文镜像至BigBrother
6)sdngw将报文送至本地域宿主机
7)ovs将报文镜像至BigBrother
整个BB检测系统由若干个组件配合完成,minitrue用于将用户传入的参数转化为注包的范围,telescreen用于构造报文及收发报文。
API: FE服务对外提供的HTTP接口,用于创建任务和查询任务进度;
Logic:业务处理层,⽤于分析⼊参并将其转换为若干源⽬主机对放入Disruptor中;
Disruptor:此组件为开源高性能队列;
Sender:将Disruptor中pop的数据组装成GRE packet,并发送给EntryPoint;
Receiver:接收从EndPoint上报的GRE packet;
Analysis:将接收的报⽂存入内存中,同时对报文进⾏分析。
1)task
上文中我们详细介绍了BB探测报文的设计和生命周期,但是我们还有一个问题需要解决:提高BB的并发能力。按照上文的介绍,每次BB只能执行一次探测,顺序执行才能保证检测结果的准确性,所以我们设计利用TCP报头中的序列号来提高并发。
以下是一个TCP报文的首部结构:
其中32位的Seq序列号就是我们要利用的,在BB探测过程中每个Seq序列号都唯⼀标识⼀个pair对,然后我们将Seq序列号分成了两部分:
因此,我们可以将BB并发的任务数提高到了32个,而每个任务支持最大的检测pair对数可以达到2的27次方,相当于每个任务都可以支持一个容量为10000台云主机的VPC进行Full Mesh检测,足以覆盖现有用户的网络规模。
2)task的执行
当运维同学在mafia(任务控制台)上点击创建一个BB task进行连通性检查时,会经历以下几个过程:
3)task的结果分析
task执行结束后,运维同学可以在mafia查看到最后的检测报告,包括发送的总pair数、收到的pair数、成功以及失败的数量。同时,检测失败的源目详细信息也会展示出来,最终以bitmap的方式呈现出来,0表示没有收到报文,1表示收到报文。
我们以下图的结果为例,解释其含义。图中是检测ip pair(10.9.88.160<—>10.8.17.169)的双向连通性。
我们再回顾下第二章中BigBrother检测的流程图,首先BigBrother会模拟10.9.88.160向10.8.17.169的宿主机上发送探测报文,报文的内容为<flag=SYN, nw_src=10.9.88.160, nw_dst=10.8.17.169>。如果10.8.17.169 —>10.9.88.160 单向连通性正常的话,BigBrother最终会收到3个报文:
(1)<flag=SYN, nw_src=10.9.88.160,
nw_dst=10.8.17.169>
(2)<flag=ACK, nw_src=10.8.17.169,
nw_dst=10.9.88.160>
(3)<flag=ACK, nw_src=10.8.17.169,
nw_dst=10.9.88.160>
上图bitmap后三位的结果为111,表示这3个报文都收到了,即10.8.17.169 —>10.9.88.160 单向的连通性正常。
反之亦然,前三位则表示10.9.88.160 —> 10.8.17.169单向的连通性情况,结果为100,(2)(3)报文没有收到,即表示 10.9.88.160 —> 10.8.17.169单向的连通性异常,虚机10.9.88.160没有回复报文,可以断定虚机内部异常或虚机内部存在iptables规则将探测报文过滤。
上文我们提到,运维同学可以在mafia上创建BB task来进行连通性的检查,通过传入mac、子网id、VPC id来确定检测的范围,进而进行全量验证。但是大多数场景中,我们不需要进行全互联检查,这样不仅浪费时间而且还会对控制面造成一定的压力。我们仅需要针对指定范围内的活跃flow验证连通性即可,所以我们又引入了活跃flow检测的服务——river。river是虚拟网络亿级别活跃流的分析系统,借助这个系统BB可以拿到用户的活跃通信源目,类似于缓存里的热点数据,这样可以让BB快速精准验证变更。
与上文全量BB探测的区别在于,minitrue无须自己计算源、目节点列表,只需指定范围后向river获取活跃列表,然后通过常规的检测流程将列表传送给telescreen进行发包即可。
BigBrother上线后就参与到了资源整合项目中,用于云主机迁移前后的连通性验证,保证出现异常后可以及时告警回滚。从8月初至今历时两个月,共迁移2000多台主机,及时发现迁移异常近10起。
同时,我们对BigBrother后续版本也有着一定的规划,例如:
本文转载自公众号(ID:UCloud技术)。
领取专属 10元无门槛券
私享最新 技术干货