【演讲实录】云原生视角下的网络性能监控实践

SDN in China

2020年6月19日

技术探讨

注:如需获取演讲者完整PPT讲义,可通过扫描文末二维码,在您填写完基本信息后,将以邮件形式发送到您的邮箱。

本文是北京云杉世纪网络科技有限公司(以下简称“云杉网络”)与多家容器厂商完成产品兼容认证后,携手北京凌云雀科技有限公司(以下简称:“灵雀云”)联合承办的题为《“看清”云原生视角下的网络》的线上沙龙演讲实录之一。

在《云原生视角下的网络性能监控实践》的分享中,云杉网络研发总监向阳以容器网络为出发点,阐述容器网络有什么特点?如何应对容器网络监控挑战?并从监控的角度,分享一个典型的容器网络分布式系统有哪些可以借鉴和指导的理论思想。最后,向阳介绍了在混合云网络运行云原生应用时,如何进行网络监控。

企业上云与应用部署方式的变迁

今天和大家一起去探讨,云原生视角下网络建设、网络监控的问题。首先,用一张简单的PPT来介绍应用部署方式经历的变化。几年前我们谈论更多的是OpenStack、资源编排和分配,而现在从谷歌搜索的趋势看有非常明显的变化,对于Kubernetes的关注已经远远超过了OpenStack;在百度搜索趋势我们也看到K8s和Kubernetes加起来是OpenStack的两倍——我们中国人爱搜K8s这个关键词。

1

容器网络的特点

首先,我们来看容器网络本身拥有什么特点?

第一个特点:容器环境下以东西向的通信为主

容器的特点是弹性伸缩,支撑弹性伸缩最主要的两个特征分别是分布式和负载均衡。由于容器环境中的应用都是以标准化的POD形式部署,因此能做到环境的隔离、可移植性。在这两个特性支撑下,容器可以在业务压力过大时做到弹性伸缩,业务以POD单位进行弹性扩充。在容器里,大家谈论非常多的是Ingress和Service,实际上它们都是负载均衡,将负载均衡到后端的POD上面,由Workload完成实际工作。对应用的部署和业务的编写人员来讲,最关注的是业务的逻辑,不用再去考虑OpenStack环境中,底层资源的管理等一些情况。

一个容器的Node大概率情况下可能是虚拟机,但也有可能是直接跑在物理机里面。大家对外层网络的需求是什么?是一个三层、可连通的网络,使得所有的K8s和Node之间可以通过IP进行交互;这样的节点是以扁平网络的方式组织,但这里面也可能会出现多租户的叠加网络。在客户实际的容器网络中,我们看到的比较多的是Flannel和Calico这样的扁平网络,扁平网络通常一个Node是/24的CIDR网段,整个容器集群可能是/16的网段。

刚才也提到容器网络的一大特点就是有非常多的负载均衡,如果在一个容器环境下或者一个微服务环境下,大家就能看到N个负载均衡——N的数量基本上就等于节点的数量,这就是我们通常说的Service至少能生成一个负载均衡,因为在每个节点上都会有一个Service,所以这就是一个实际的负载均衡的表现。如果是在服务网格的场景下,这样的负载均衡数量会更多,可能达N乘以P(P就是POD的数量),这时每一个POD都伴生一个Sidecar负责做网络层面的负载均衡和不同POD之间沟通的纽带。通过负载均衡任何POD之间都安全可达。

本质上来讲,一个容器集群实际上是在一个大的三层网络里面,只不过是用更细粒度的子网,将不同的节点隔离,使得广播域不至于太大;但是从可达性来看,任何两个POD间都是可达的,而且外部也可以通过Ingress的方式、LB的方式来访问容器集群里面任意的POD,只要这个POD是通过Service的方式、Ingress的方式将服务透传出去。

这带来一个问题,由于服务之间的沟通变多了,东西向流量成为了容器环境下的主体流量。这个流量,传统的流量采集方式无法全部覆盖。因为传统的流量采集方式是通过物理交换机的镜像、分光等方式,在容器网络环境下,容器间的通信可能在K8s的Node之内或者一个VM的Hypervisor就终结了,很难去到达物理的交换机层面。另外一个方面,即使容器、POD之间的流量能到达物理交换机,但随着容器规模的扩张,交换机模式要想全覆盖投入的用于流量采集的成本会急剧增长。

第二个特点:端到端路径的复杂

上面讲到容器以东西向的通信为主,隐含意思是网络的通过很平坦,但实际上网络通过得并不平坦。容器的环境下有大量的LB,LB所做的工作无外乎就是地址映射,包括源端地址、目的端地址的映射。在诸如Node-POD的Service、Ingress或外界有LB设备提供负载均衡等复杂的场景下SNAT和DNAT会多次发生,每一次发生地址转换就意味着可能会产生网络的性能问题。

另外,虽然两个POD之间是三层可达,实际上这两个POD的End to End的通信路径上可能会跨越物理服务器的机架,意味着跨越接入交换机,也可能会跨越物理网元,比如说物理防火墙;也可能会跨越两个公有云的AZ,或者是公有云的区域,甚至会跨越不同的云,比如说VMware上面的容器环境和OpenStack上面的容器环境;甚至是在私有云和公有云之间通信。

另外一个方面,容器默认负载均衡的方式并不关心Node上的POD不均衡的情况。Service会在每个Node上将策略实例化,但Service后端的POD可能在某些Node上有三个、在某些Node上有两个、某些Node上可能没有。现在K8s最新的版本支持对服务拓扑的感知,它能感受到一些条件但十分有限。但这种感知不是以实际的网络质量测量的角度来感知的,只是一个估计。我们认为,跨AZ的链路会差一点,跨Region的链路会差一点,但没有实际数据的支撑。这是容器网络的第二个特点,端到端路径的复杂。

我们模拟访问一个POD、一个Service过程经历的多跳,从POD到Root Namespace,然后做NAT转换,然后另外一侧做NAT的还原,再到最终的POD。可以得知任何两个POD之间的访问,通过service的访问都可能会有解析的问题、DNS性能的问题以及负载均衡的问题。

当前容器环境下的默认的LB一般是用IP Tables实现。关于IP Tables会产生什么问题,大家可以随便在微信、微博上搜一搜都能看到大量的容器环境下负载均衡翻车的场景。比如Kernel的参数设置不合理导致TCP的建连有问题,或者POD的起停时间,在探测的时间之后和之前导致的一些问题,这里面大多数都是由DNS和负载均衡来带来的。

第三个特点:业务的拓扑的动态性强

第三个特点是业务的拓扑的动态性增高了。在传统网络环境下,我们可以认为服务器和虚拟机的IP地址是很少发生变化的,对业务的梳理其实等同于对IP地址身份信息的梳理。我们可以用一个表格,比如CMDB,来记录哪个IP用于什么样的业务场景。但在容器环境下,对业务的梳理已不能按这种方式操作。首先容器用DNS解析IP,IP实际上是被POD在使用,由于POD的生命周期非常短暂,因此IP可能会在不同的时间属于不同的POD,也就是说用于不同的业务。

在混合云的环境下,我们对IP身份的识别是非常困难的,因为这里面可能存在IP重叠、也可能存在IP对应的资源身份在不断地变化,我们需要感知IP对应的VPC、子网、POD和服务实时对应的具体资源的变化。此外,我们还要去处理一些复杂的情况,例如在云企业网这样复杂的两个VPC之间有对应的连接,那么我们采集到的流量,应该能将源IP和目的IP的通路正确地映射到两个VPC及其所在资源池里。

第四个特点:容器网络规模超级大

最后,是容器网络规模超大性的特点。一般来情况下,一个物理机上可以运行10个虚拟机、一个虚拟机上可以运行10个POD。这样下来,基本上可以认为容器网络的环境,IP的数量有100倍的增长。而IP数量的增长,会导致网络监控的数据至少有100倍的增长——这正是网络监控数据的一个特性。

2

如果去监控计算资源、存储资源,基本上有多少台机器我们得到的监控数据就是多少个,他是O(N)的关系。但是对于网络监控而言,极限情况下数据是O(N^2)方的量级,因为网络监控的本质是一个端到端的信息。极端情况下,容器里所有的POD都会产生通信,也就意味着有O(N^2)的通信需要被监控。

以上这些特点都会导致我们对容器网络的监控面临一些挑战。

对于以东西向流量为主的容器环境,如何去实现端到端的监控和诊断?对于端到端路径复杂的特点,我们需要去覆盖端到端经过的每一跳,包括源端的POD、虚拟机,目的端的POD、虚拟机,也包括了中间经历的物理链路。特别是非常重点的比如硬件的物理防火墙、物理的负载均衡以及虚拟化的NAT网关资源池、LB的资源池等等这些关键位置,这些环节可能会导致网络性能的损耗,经常是我们在网络故障排查时遇到的问题,因此我们必须完整覆盖。

对于业务拓扑的高动态性的特点,我们需要将流量的源、目的映射到具体的资源,才能实现容器网络的业务画像;然后,我们要面对网络规模的100倍增长,要做到网络监控系统的智能化、高性能、弹性可扩展。智能化意味着,当面临的IP数量以100倍扩大的时候,任何人工的排查都将是徒劳,监控系统必须具备发现问题的能力;高性能意味着监控系统包括流量采集既要覆盖全网,又不能对业务运行的环境产生过大的干扰;弹性可扩展是指随着云的伸缩,监控系统也能随之相应地变化。唯有如此,才能去应对100倍体量的云原生网络的监控诊断。

分布式系统的可观测性

下面我讲讲,我们做混合云网络环境性能监控体系的理论支撑。这张图描述的是分布式系统的可观测性。

3

参见:https://peter.bourgon.org/blog/2017/02/21/metrics-tracing-and-logging.html

我们需要去集中解决3个类型的监控数据,即Metrics、Tracing和 Logging。分别代表的是我们常用的Prometheus监控的指标数据,比如说CPU内存、流量大小等等,去画一些折线图、柱状图、饼图;第二个是Tracing数据,或者说服务调用栈的数据;第三类是日志数据,比如ELK里的日志分析,对日志我们常用Kibana和Elasticsearch。

后面两类数据关联度会大一些,是每一个请求或者每一条日志的数据;Metrics通常是我们实现分布式系统可观测性的第一步。Metrics是一个可聚合、可设置报警的面向大规模的监控数据做分析、做告警的判断依据。对于Tracing有很多开源的工具可用,能够做服务访问调用关系的分析,找出其中的热点。例如Grafana就能提供这样的图形化展现,通过Prometheus也能做数据收集。

4

针对Metrics我们通常会关注四个方面的指标量。

第一个方面是时延,它刻画的是当前的业务系统的访问是不是顺畅、耗费的时间是否在增加。例如说我们从四层网络的角度看,有三次握手的时延、协议栈响应的时延;从应用的角度看,有HTTP响应的时延、DNS响应的时延。

第二个方面是流量,更多的是刻画系统的吞吐。例如一个应用系统的BPS是多少、PPS是多少?新建连接数、新建连接速率是多少?HTTP的请求数是多少等?流量可以等同于吞吐量或者是速率这样的指标。

第三个方面是错误,错误可能发生在网络层,比如TCP的建连失败、TCP的重置、TCP的重传、TCP的零窗口,还可能会发生在应用层,比如HTTP的400、500等错误或者是DNS解析失败。

第四个方面是负载,一般来讲是对计算和存储资源的描绘,在虚拟网络情情况下也可以描述虚拟交换机的负载。网络层面的负载主要体现在并发连接数、当前正在活跃的用户数等指标。我们对网络的指标监控通常要考虑以上四个方面,这四个方面能够覆盖一个分布式系统所有的角落,最终实现分布式系统的可观测。

下面讲一下,我们为什么能够通过流量采集就能够实现分布式系统的可观测性。这涉及指标量的采集、日志的采集、Tracing访问路径的采集。以往部署应用并对其进行监控,我们通常会采用NPM工具,通过交换机镜像流量来获取物理服务器和外部通信的流量,做外部通信的监控;我们也会在应用程序内部插入很多NPM插件,从应用逻辑地角度对应用做性能的监控。随着虚拟化以及现在的容器化,服务从宏服务过渡到了微服务,这时NPM和APM有了非常明显的融合趋势。以往我们能覆盖到应用间的调用,现在需要覆盖到POD的级别,实现进程间通信这个粒度的覆盖。

例如,我们去监测应用的性能时会考虑函数的调用栈,某一个函数的耗时是否会产生服务调用最终的时间损耗。在微服务场景下,我们更多考虑的是服务和服务之间的调用关系,考虑服务之间的Tracing,相当于调用栈的追踪。由于服务和服务之间实际上是POD和POD之间的访问,在网络层面直接能看到它们互访的流量。因此,服务的调用栈能直接通过网络流量获取到。这其实也回答了,我们为什么可以通过流量采集来解决容器网络的可观测性难题。

那么为什么需要通过流量采集来解决这个问题呢?其实有两个方面的原因。

第一个方面是从应用的层面无法解决问题。从日志或代码插件的层面很难去感知到网络方面的问题。比如说,有一个访问消耗了500毫秒,在网络层面是由于建连导致的时延的问题、还是协议栈时延导致的问题、抑或重传和零窗口导致的问题?其实应用层并不清楚,只知道最终这个请求消耗了500毫秒。

另外,诸如TCP建连不成功的问题也不会体现在日志中,因为这时网络层的建连还没有完成,应用层的日志是不会去对其做任何的记录。第二个方面是网络层的信息能提供更精确的数据。以Nginx日志为例,当一个请求所发送的数据已在内核缓冲区里,Nginx认为已经实现了请求的完整回复,而记录了一个时延。但是如果说我们能从网络流量的角度去监测,会发现在实际的环境中对于这样的场景会有3~10倍时延的误差。这说明,从网络层面去分析应用的质量、性能是必要的。

在容器网络环境下我们通常可以看到一些其他的数据,包括Service之间访问的追踪关系,在负载均衡器前后、Service前后IP的变化关系,真实源IP与SNAT和DNAT后的变化关系。这都是为了实现整个业务的监控应该去采集的数据。通过这些数据,我们可以去做各个纬度的可视化,比如说我们可以去刻画监控数据的分布,监控数据和网络逻辑拓扑的关联,对历史的交互数据进行回溯分析,去比较监控数据在不同的时间段以及对于不同的资源的排名等等。现在有一些开源系统,比如说Grafana等,也能这些监控数据做很好的展现,最终支撑业务性能的排查。但开源系统通常很难将监控数据和业务信息、资源信息进行关联。

混合云网络监控的实践

下面以容器环境下的流量采集为例讲下云杉网络DeepFlow®在混合云网络监控的实践。我们可以通过Prometheus、Telegraf等方式获取计算、存储的监控数据。但是我们怎么能让任意两个POD之间的数据都能被采集?这里要提一下DeepFlow®的核心组件采集器,DeepFlow®采集器以进程的方式运行,在容器环境下实际上就是以容器的DaemonSet的方式部署在所有的容器节点上,对任何POD的虚接口流量进行采集。能实现容器网络环境下、虚拟网络环境下东西向流量的全网采集,并且对于运行环境是无扰的。

容器网络流量的采集

实际上DeepFlow®的采集器不会对CNI有任何的交互,不需要做任何适配,对于Flannel、Calico、Kube-OVN等环境都可以直接部署。同时在容器环境下DeepFlow®也实现了集群化管理,如果面临的POD是10万量级,我们的采集器完全可以部署在10万量级的环境下,我们有一个分布式的控制器集群,可以对采集器实现自动化的管理。

性能方面,DeepFlow®采集器不是直接对流量进行TCP Dump抓取然后发出去,这在分布式环境下对网络带宽消耗不可接受。DeepFlow®采集器在本地有很多的计算能力,将计算之后的遥测数据、包数据、流日志最终推送到远方。从性能的角度看,在Kernel模式下,DeepFlow®采集器可以达到十倍TCP Dump的性能,并且消耗的CPU和内存通常是其运行环境的1%;由于只将最终的遥测数据发送到远端,带宽的开销基本上可以忽略不计,是在万分之一的水平。

用于网络监控的时序数据库

刚才讲的是容器环境的流量采集,下面将采集后数据的存储。这样的存储量需要一个特殊类型的数据库来支撑。这和刚才谈到的容器网络的特性相关,有100倍的IP增长、还要去考虑到IP和IP之间端到端的通信。传统的数据库(一般的KV数据库)面临的是读多写少的场景,主要做高频查询。但实际上在监控数据的特点是读少写多——几乎每一秒都在写入监控数据。监控数据要写的足够精细才能支撑故障的排查,读取监控数据的场景比较低频——最高频的读取是实时告警的触发。这是用于监控的数据库和其它的用于业务的数据库的本质区别。

所以我们用时序数据库来应用于监控场景,但网络的时序数据库需要通用时序数据库十倍的性能。网络数据有一些显著的特点,第一个特点是高基数,例如1000台服务器是1000个监控量,1000乘以k的系数其规模并不大;但在网络场景下,1000台服务器可能是1000*1000的监控量,如果再加上协议、端口、域名等不同的维度,技术难度会呈持续的数量级增长。第二个特点是,网络监控有很多长尾数据,比如公网上的流量有伪造IP的扫描、端口的扫描,在这样的条件下数据的基数非常高、长尾的特征非常明显,但这样的数据我们也要存储。

在通用时序数据库的场景下,长尾的数据因为要建索引、对内存的消耗会非常显著。第三个特点是时间精度要求非常高。我们在做故障排查时,常常要看秒级别的数据或者是亚秒级的数据,这要求在时序数据需要支持相当高的精度。

另外从网络产品的角度上,除了要去做常规的基于Label的查询,我们可能还要去查IP、IP段、CIDR的网段,去查一些端口的范围,这都不是传统的、开源的时序数据库能解决的。当看到上述需求的时候,我们往往会想,能否用日志系统比如Splunk和Elasticsearch去解决网络监控的问题?Splunk和Elasticsearch遵循的也是刚才谈论到的传统数据库的设计——会对所有的数据、字段建立索引,目标是让查询更快,但是在网络监控的场景下主要的目标是让写入更快,而且让高频写入所需的资源消耗最低。所以日志系统也不适用于网络监控场景。

有一些开源的时序数据库的性能的比较,但我们发现在实际的生产中所需的时序数据库的性能是开源数据库的十倍量级。Prometheus和Influx DB是常见的时序数据库,Prometheus更多的是一个监控系统。云杉网络DeepFlow®的时序数据库是基于Influx DB的查询引擎构建的,我们做了非常多的、深度的二次开发,支持了水平扩展和数据的高可用。最终的结果是,现在读写性能有10倍提升、内存消耗有10倍的降低,单机的写入速率能达到一百万点每秒。这样才能支撑我们刚才谈论到的对一个大规模云网络做网络的监控。

混合云环境下的网络监控

实际上,除了容器网络环境下, DeepFlow®采集器还可以运行于虚拟化环境下,KVM宿主机上运行一个轻量级的进程,这个进程以无依赖、无侵扰的方式部署在宿主机下,对于环境以及vSwitch本身不用做任何的配置。采集器的安装包是一个简单的二进制包,没有任何环境依赖,这也使得DeepFlow®采集器可以运行在公有云或者专有云的虚机、物理机的环境中,也可以运行在一个专用的物理服务器上,去接收物理网元的镜像流量。这样我们可以对网络的所有关键位置全覆盖,可以对容器环境、云环境,还有物理链路做全网的流量采集和监控。

采集到的流量,我们可以通过过滤、去重、截短、标记等处理后给到后端的安全的、网络性能的、DPI的分析工具;同时也可以给DeepFlow®自身的数据节点,数据序节点通过对采集器本地计算的遥测数据和流日志的存储和查询展现,实现我们后面会提到的全景图和流量回溯的功能,最终实现对混合云网络的监控和性能诊断。

下面讲两个客户的案例。第一个是银行的混合云场景,在一期建设的阶段,我们覆盖了KVM资源池,里面大概有1000台虚拟机。由于DeepFlow®所有的组件,包括控制器和采集器都是可以弹性扩展的,因此在二期建设过程中,直接覆盖了另一个KVM资源池,有将近2000台虚拟机。过渡到二期的时候,实际上仍然是一套DeepFlow®环境——由主控制器和从控制器构成的集群,对两个资源进行统一监控。在三期建设的时候扩展到了容器资源池,容器资源池中有近50个节点、约1万个容器POD也直接纳入到了整个流量监控平台。最终实现了对流量采集并分发到后端的交易分析、网络性能分析、根因分析以及安全态势等流量消费端、大数据分析平台。

5

第二个案例是集团企业。客户使用了一个复杂异构的云环境,用了华为的私有云、华为的公有云、VMware的资源池、微软的公有云(包括公有云上的AKS环境)以及阿里的公有云。DeepFlow®在公有云侧以及数据中心侧,包括用户的分支机构统一部署,实现在异构的、混合云环境下的全网流量的采集和监控诊断。

总结

总结一下,DeepFlow®通过数据的采集,到时序数据库的分布式存储,到各个维度的流量知识图谱的展现,从网络、资源池、虚拟化、容器再到数据的各个维度,分布的维度、关联的维度、对比和回溯的维度,最终实现了通过对指标量的监控,实现对网络环境和业务问题的诊断。

以容器环境为例,我们首先会通过API的方式获取到容器环境下的所有资源,基于IP的资源属性,通过业务画像的方式将业务的组成,包括物理部分和虚拟部分进行梳理。再下一步,通过采集业务环境中所有的流量数据,呈现出业务端到端路径逐跳的性能数据。基于这个性能数据,我们能在不同的维度(资源组维度、POD维度、分析维度)做层层的钻取来最终定位业务的性能问题,并进行证据的留存。同时,我们也可以通过对逻辑层面的拓扑的展现,包括配置的校验和连通性的检查,以及虚拟层面拓扑的展现,获取到最终诊断到的具体位置和证据数据的收集,通过流日志回溯,最终来提供故障定位的诊断依据。

%e8%8e%b7%e5%8f%96ppt%e8%a1%a8%e5%8d%95%e4%ba%8c%e7%bb%b4%e7%a0%81

填写邮箱信息,立即获得PPT讲义

%e5%85%a5%e7%be%a4%e4%ba%8c%e7%bb%b4%e7%a0%81

Related Posts

「直播回看」高清云网可观测之全链路追踪实战

“云原生可观测性分享会”第七期《高清云网可观测之全链路追踪实战》由云杉网络 高级产品经理 李倩分享,针对云网络的全链路追踪问题,用「实战」带领大家一步一步破解“网络谜案”。

Read More

「直播回看」MetaFlow:开源的高度自动化可观测性平台

今天非常高兴能给大家带来一个好消息,云杉网络正式宣布开源MetaFlow,一个高度自动化的可观测性平台。这是云杉网络从2016年以来,商业化产品DeepFlow从云网络发展到云原生应用持续积累的结果。MetaFlow包含了我们在可观测性建设中核心的关键技术,今天正式开源并共享给社区,为可观测性发展共同建设出一份力,同时也向世界领先的目标往前迈进一步。

Read More