亚马逊AWS官方博客

上云也挺难?我们如何对数十个云账号、数百个子网做好状态监控

云服务是指由第三方提供商托管的基础架构、平台或软件,可通过互联网提供给用户的服务拥有弹性化、安全、节约成本等诸多优势。

与各个企业一样,近几年来,FreeWheel 内部各个团队也将大量的服务从On-prem机房迁移到了云端,并选择了AWS作为云服务提供商。在使用AWS提供的计算、网络和存储资源的同时也采用了了众多的云原生服务来降低迁移与维护成本,但在对网络状况的监控时却遇到了很多问题,大致包括三点:

  1. 复杂的网络连通性管理;
  2. 不可控的网络质量;
  3. 大量人工维护的监控配置;

复杂的网络连通性管理

大多数情况下,网络架构对应用程序和用户应该是透明的。用户关注的是他们的请求可以稳定快速地从源头传递到目的地。

FreeWheel 传统的服务部署方式,服务都是部署在各地的机房。此时各机房到公网的连通性、以及各机房间的网络连通性,是被网络工程师完全掌握的。因此在发生网络故障时,工程师可以迅速的定位问题,并提出相应的解决方案。

但是,随着服务迁移到AWS,FreeWheel 内部网络架构的复杂性呈几何倍数增长。

公司内的各种服务的部署环境和网络访问非常复杂,这些服务经常会涉及到,跨越数十个AWS账号,数百个子网、 VPC Peering和TGW rules,以及数千个Route table规则和Security Group 配置的网络访问。这意味着,用户各种服务的数据包,将经过各种AWS的服务和数据连接才能被传输到目标。

如此复杂的网络连通性管理下,当用户需要访问某个部署在AWS的服务时,要检查以上所有环节的配置是否正确;当网络传输出现问题的时候,也要检查以上所有环节是否正常工作。因此在如此复杂的网络传输过程中进行问题定位就成了一个非常困难的任务。

图1,复杂的AWS网络环境。

不可控的网络质量

由于AWS上复杂的网络结构,任何一个环节的故障,都有可能大范围的影响网络质量。

同时,在某个环节出现故障的时候,工程师也很难快速判断影响的范围。不同影响范围的问题,其快速止血和修复的方案都不尽相同。但是由于网络结构的复杂性,以及网络质量的不可控,用户和他们的服务经常会面对一个未知的网络状态黑盒。因此当线上出现问题时,用户通常需要更长的时间来做出判断。所以,网络状态的监控就成了保证服务正常运行的必要前提。

大量人工维护的监控配置

传统的网络监控配置,需要用户提出需求,再根据需求部署相应的监控Agent,添加采集配置。监控指标采集后,用户还要自行建立图表展示监控数据。每次添加和升级配置需要遵循Release规范。整个流程的各个环节需要多个工程师参与,手工添加和维护各种配置、部署各种服务,复杂而冗长。

因此我们需要一个用户可以自行按需配置的网络监测工具,在子网级别监控端到端的网络连通性,同时提供详细的监控指标和图表,以方便用户监控其服务所涉及的网络的状态。并且,需要支持根据监控指标来设置报警,当网络传输发生异常的时候,能及时通知到用户并且尽快定位并解决问题。

架构设计

基于以上的需求,我们开始设计网络监控服务的架构。对于一个新的产品,首当其冲的要求是新产品要能和目前已有的服务和平台相结合。因此,我们选择在FreeWheel内部现有的FOC和PQM平台上构建新的网络监控服务。

FOC(FreeWheel Operation Center)是FreeWheel内部的集中化运维管理平台,提供了包括AWS资源的管理与审计,K8S资源的管理以及运维自动化相关的功能。在此项目中,FOC支持让用户可以一站式的配置并启用自己的监控项,选择需要监控的AWS 子网或数据中心,目标地址以及监控所使用的网络协议。FOC会完成监控agent的部署与启动并将用户的配置信息注册到监控平台,并支持用户对所配置监控项的管理与维护。

PQM(Product Quality Management)是FreeWheel内部的服务监控指标、日志收集和报警平台。PQM基于Prometheus和ELK技术栈,提供了监控和指标的采集、存储、分析等服务,并在此基础上自行研发了报警平台,为公司各项服务提供基础监控和报警服务。在网络状态监控的项目中,PQM根据现有的监控系统技术栈选择了blackbox exporter作为网络状态监控的Agent;并提供了服务自动发现的能力,根据用户的配置自动在Prometheus中更新监控指标的采集任务;为用户提供了网络状况监控指标的总览,以及详细信息的Dashboard。

图2,其架构图:

用户根据需要配置需要监控的网络连通性源的AWS Account,Region,子网等信息,以及目标的URL。提交后,FOC将用户提交的配置存储在RDS数据库中,并自动根据用户提交的配置,利用Terraform部署相应的API Gateway接收请求,利用Lambda部署blackbox exporter作为监控指标采集的Agent。PQM定期从RDS数据库中存储的用户配置更新至ETCD,根据ETCD中存储的配置自动更新Prometheus的监控采集配置,并将采集的数据写入中心存储Cortex。用户即可在Grafana中查看到已经配置好的网络检查的各种相关指标的信息。

当然,在确定自研前,我们也根据需求调研了业界其他网络状态监控的产品,如Catchpoint, Synthetic Monitoring等。目前已有的监控解决方案,最大的问题是无法支持子网级别的网络监控。它们通常是通过一些预先部署好的Agent进行网络监控,用户无法更细粒度的自定义配置。因此用户无法通过这些产品来监控具体的端到端的网络状态。与此同时,高昂的价格也是一个问题。业界的商业版监控服务价格非常高,不适合这种按需的轻量级的网络监控的需求。

子网级别的网络监控

目前已有的网络状态监控方案,通常只覆盖AWS各账号、Region间的网络连通性,一般不会覆盖到子网级别的网络状态。但是考虑到AWS网络结构的复杂性,以及跨子网的服务高可用的需要,对子网级别的网络状况监控的需求也随之而来。我们利用Lambda实现在子网级别快速部署网络监控Agent,从而实现了子网级别的网络状态监控,完善了网络监控的覆盖面。

轻量级,低成本

这套网络状态监控方案的各个模块,包括监控服务采集和部署、图表展示等,都是由目前业界流行的技术栈、成熟的开源工具、云原生服务等构成的。因此具有极强的可移植性,任何人都可以快速的利用该方案搭建相同的监控系统。这样在系统的搭建以及后期维护上都非常有优势。

另外,与业界其他功能类似的网络状态监控系统高昂的价格相比较,该系统运行成本更低。用API Gateway + Lambda的方案部署采集Agent,使得采集成本仅由访问采集API的次数决定。对于单个子网的网络监测需求,每年成本不到30美元。

终极解决方案

为了实现网络监控服务的子网级别监控和轻量级、低成本的两个创新点,我们在监控Agent的选择和部署,监控配置的自动发现和管理,以及监控指标Dashboard的设计等几方面做了很多的工作。

网络监控Agent的选择

Prometheus是一个开源的监控和报警系统,是CNCF继K8S后第二个托管的项目,目前已经成为指标监控系统的事实标准和主流选择。目前FreeWheel的指标监控系统是在Prometheus技术栈的基础上构建的。因此,要监控端到端的网络状态,需要在同样的技术栈上选择解决方案,方便与目前现有的系统相结合。

blackbox exporter是Prometheus官方提供的黑盒网络连通性监测解决方案。它支持通过TCP,HTTP,ICMP等多种协议对网络连通性进行探测,同时收集多种网络状态的监控指标,帮助分析问题。blackbox exporter广泛应用于各种网络状态监控的场景,其功能可以满足我们对网络状态监控的需求。因此,我们选择blackbox exporter作为网络状态监控的Agent。

网络监控Agent的部署

我们设计的目标是实现AWS 子网级别的网络监控。因此,理论上,我们需要在每个AWS账号的每个子网上都部署一个blackbox exporter实例。这样的部署方式主要存在两个问题:一是部署exporter到每个子网上,后续维护成本非常高,同时扩展性很差。如果我们在对某个账户某个区域的子网进行添加、删除、修改等操作时,也需要对应的调整exporter的部署。二是这种部署方式不经济。我们需要支持子网级别的网络监控,但是用户不一定需要监控每个账号的每个子网,其实很多exporter是闲置的,这导致了资源的浪费。

因此我们选择按照用户的需要动态部署exporter。这里我们选择AWS API Gateway 和Lambda解决exporter部署的问题。API Gateway可以接收网络请求,并转发给Lambda进行处理。这样,我们只需要根据用户的需要,在用户添加/修改了网络监控配置后,根据配置在对应的AWS账号和Region中以Lambda函数的形式部署exporter,并配置上对应的子网作为Agent。再通过API Gateway绑定触发Lambda函数的URL地址。这样,我们就实现了根据用户的配置动态启动exporter,既满足了用户的需要,又节约了资源。

不同于普通exporter在接收到http请求后直接返回监控指标,用Lambda来部署exporter,exporter要将采集的监控指标通过API Gateway返回。因此需要我们在blackbox exporter的基础上进行二次开发,以满足Lambda与API Gateway的交互的需求。Lambda与API Gateway的交互,主要是由”事件“来完成。API Gateway在接收到请求后,会发送给Lambda一个”事件“,Lambda解析收到的“事件”并完成相应的业务逻辑,并将结果以”事件“的形式返回给API Gateway。这里是一个简单的例子:

func Exporter(req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
    return events.APIGatewayProxyResponse{
        StatusCode: 201,
        Body:       "This is a test lambda",
    }, nil
}

当接收到访问的请求时,API Gateway会把请求的内容以结构体的形式传入handler,handler根据结构体的信息完成所需的逻辑,并将结果返回给API Gateway。因此,我们需要在handler函数中,将exporter采集到的监控指标,以response body的形式传回API Gateway。通常,exporter返回监控指标,都是通过Prometheus的官方库中封装的功能实现的。这里我们需要在body中以字符串的形式返回监控指标,就需要在exporter采集监控指标后,将指标信息以Prometheus官方的格式dump成字符串。这里我们使用如下的代码实现:

func Exporter(req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
    // Blackbox Exporter Collector采集相关监控指标
 
    // 处理监控指标
    buf := bytes.NewBuffer([]byte{})
    mfs, err := registry.Gather()   //获取注册到Prometheus的指标
    contentType := expfmt.FmtText
    enc := expfmt.NewEncoder(buf, contentType)
    for _, mf := range mfs {
        enc.Encode(mf)
    }
 
    return events.APIGatewayProxyResponse{
        StatusCode: 201,
        Body:       buf.String(),
    }, nil
}

这样我们就实现了blackbox exporter的Lambda化。

FOC 目前利用了Terraform来创建并管理AWS资源,在Agnet的部署上,我们使用了API Gateway+Lambda的Terraform Module去实现了部署的流程。当有用户发起了配置的请求之后,FOC会首先判断在当前Account是否有可以复用的Lambda function,避免重复创建资源造成浪费。部署完成后,FOC将API gateway的URL写入DB中,监控系统的采集任务将会利用这个URL去采集目标地址的网络数据。

由于FreeWheel目前采用的还是On-prem DC和AWS的混合部署方式,我们同时也在各个DC都部署了我们的监控Agent,这样能够更全面的覆盖公司内部复杂的网络结构,让用户对应用部署环境的网络状况有着更清晰的认识。

监控配置和自动发现

有了根据配置动态启动的exporter,我们还需要动态在Prometheus中添加相应的采集任务。采集任务中需要包括用户配置的网络监控的源和目标的位置,网络监控的类型,以及动态启动的blackbox exporter及其对应的API Gateway地址等信息。

我们使用ETCD+Confd实现采集服务的自动发现。ETCD是中心化的配置存储解决方案,Confd是轻量级的配置管理工具。两者相结合,通过Confd对ETCD指定的key进行watch来监测配置的变动,结合配置生成模板,实现保持本地配置保持最新的功能。这种中心化的配置存储+自动更新配置的方案,使得各模块可以无状态的运行,从而灵活的按需部署和扩缩容,非常适合需要灵活部署和更新的小型项目。

图3,监控配置项:

在根据用户的配置启动exporter后,FOC会将用户添加的网络监控配置存储到RDS数据库中,如图2。PQM定时检查RDS并将配置以json结构更新到ETCD中,并利用Confd对ETCD的配置记录进行Watch。当观测到记录的变化时,Confd会根据ETCD中存储的配置,自动按预先配置的模板,将用户的配置和blackbox exporter的地址等信息填写进指定的字段,生成对应的Prometheus采集配置,并通知Prometheus进行配置热更新。所有Prometheus采集的数据会存储到中心存储数据库Cortex中。所以指标展示页面不需要更改任何配置,就可以从中心存储数据库读取并展示最新的数据。

监控配置的管理

图4,监控配置管理页面:

目前,所有的监控项都存储在RDS数据库中,集中化的存储更方便我们对已配置的监控项进行更新和删除等操作。用户可以通过FOC来管理自己配置的监控项,后期当Agent需要更新时,管理员会通过部署新的Lambda和API Gateway的方式,集中更新每个监控项的Agent信息。这样就实现了对用户透明的升级方式。

监控指标的展示

采集了监控指标,我们需要给用户提供一个方便的界面来展示这些数据。我们使用Grafana进行指标的可视化图表的展示。因为我们的网络监控系统支持多种网络协议,为了方便用户的使用,我们给用户提供了“一站式”的可视化页面。我们对各种网络协议的不同监控指标进行了分类,将意义相同或者类似的指标放在同一个图表中进行展示。这样,我们就将多种网络协议的各种指标合并在同一个页面中展示。用户可以方便的在同一个页面中,通过配置切换需要查看的网络监控类型,监控任务,源和目标。极大的方便了用户的使用。

图5,监控指标总览Dashboard

图6,监控指标详细信息Dashboard

在监控状态总览页面上,用户可以获取当前网络监控信息的总览,方便的了解目前设置了哪些监控,这些网络监控的连通性和延迟的情况。对于目前处于故障的配置,或者是用户关心的配置,我们可以通过列表的链接直接跳转到详细的监控指标页面。在详情页面中,我们提供了具体的,随着时间变化的网络连通性状态指标,以及网络连接各个阶段耗时的统计等。这些指标有助于帮助用户快速定位和分析网络问题,回看历史网络状态等。

未来

作为监控服务,整个项目各个环节的可靠性也需要保证,以提供更可靠的网络监控服务。目前PQM已经拥有对K8s、AWS native service等各种服务状态的监控的能力,我们会将各环节的状态指标整合起来,加强整个网络监控服务的健壮性和可靠性。同时,在当前支持的HTTP、ICMP和TCP检查的基础上,未来我们会支持更多种网络监控的协议,以满足不同的团队对网络监控的需求。

本篇作者

王朝

FreeWheel 大数据基础架构团队工程师,主要负责公司监控平台Prometheus相关产品的开发与维护。

张群朋

FreeWheel 运维团队高级工程师,主要负责公司运维平台的开发与维护。