基于网络抓包实现 kubernetes 中微服务的应用级监控 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Goodapp
V2EX    推广

基于网络抓包实现 kubernetes 中微服务的应用级监控

  •  1
     
  •   Goodapp 2016-12-30 11:35:26 +08:00 3314 次点击
    这是一个创建于 3283 天前的主题,其中的信息可能已经有所发展或是发生改变。

    微服务是什么?

    此话题不是本文重点,如你还不知道。请谷歌一波,会有遍地的解释。引用下图说明下微服务可能呈现的形态: 2016123064266service.png

    微服务监控的挑战

    监控的目的是为了让集群中所有的服务组件,不管是 HTTP 服务,数据库服务,还是中间件服务。都能够健康稳定得运行,能发现问题,遇到问题能找到原因。
    在过去,监控工具侧重于基础设施或单一软件组件以及衡量运营健康。这些工具在实现这一目标方面只取得了一定的成功,但是对于单一的,传统的应用程序和基础设施来说效果不错。微服务的出现暴露了工具中的弱点。
    现在,组件托管在位于私有云,公共云或两者的混合体之间的虚拟化机器或容器内。获悉我并不需要关心服务 cpu 用了多少,内存用了多少?确保这些服务相互通信以提供所需的结果需要从监控的角度重要看几件事情:

    1. 微服务集群中是否所有的服务的吞吐率,响应时间都正常?
    2. 服务调用线中哪些线负载过大,哪些线负载过小?
    3. 服务的错误率,例如 HTTP 500 错误。

    我们想要监控分析应用,从它的服务状态出发是否更直接呢?

    已有监控方案

    目前有些厂商提出了微服务的监控解决方案。

    • 从 APM 角度监控服务端到端状态。
    • 为每种类型服务开发 agent 收集应用状态信息。
      • 通过产生统一的应用日志分析监控方案
      • 其他方案

    每一种商业或开源方案都有它的优势所在。可以根据你的需求来进行选择。例如你的所有服务都是自己研发,日志标准一致 or 能够统一处理。所有访问信息都能打出日志,那么我认为日志分析可能是你最适合的方案。但是对于公有云平台,那就不同了。

    好雨云帮采用的方案

    好雨云帮提供了公有云和私有化的部署方式,平台内部署的服务各式各样。各种通信协议,各种日志标准。我们怎么实现对所有服务的应用状态监控?好雨云帮完善的租户网络,环境隔离,因此我们提供用户在自己环境下安装自己的监控组件,我们的基础数据收集是通过网络分析。下文详细讲解:

    kubernetes POD 共享机制

    kubernetes 中 pod 内容器共享网络空间,挂在卷等为我们监控 pod 内主服务容器提供方便。其实按照官方对 pod 的定义的使用面来说:

    * content management systems, file and data loaders, local cache managers, etc. * log and checkpoint backup, compression, rotation, snapshotting, etc. * data change watchers, log tailers, logging and monitoring adapters, event publishers, etc. * proxies, bridges, and adapters * controllers, managers, configurators, and updaters 

    pod 内除了主服务外我们可以部署一些附属服务。之前的文章我谈过使用 pod 的插件服务收集处理日志。今天我再谈使用 pod 的网络便利监控主服务应用级指标。

    通过共享的网卡抓包分析网络流量反应应用状况

    我们拿一个 http 服务为例,我们监控网络流量能拿到几乎所有访问和服务返回信息。例如 1 分钟内多少request,分别请求哪些path,多长时间服务返回了。返回状态码等等信息。
    要获得以上的数据,我们需要获取到网络包,解码网络包然后获得 http 协议数据。
    我们WatchData服务容器与应用容器在同 pod 中,经过应用容器eth0网卡的流量我们再WatchData容器中eth0网卡获取。通过解码网络包获取 http 报文头关键信息,每一个Response形成一个消息发送到 server 端完成分析,存储然后形成连续的实时的监控数据。下图展现个简要的整体架构图:

    2016123050718pod.jpeg

    当然,上文已经说了,我们采取此方案主要就是为了能够监控各种应用,只是http怎么行。不通的通信应用使用不同的通信协议,比如mysql的协议,mongodb的协议。TCP/IP网络协议栈分为应用层(Application)、传输层(Transport)、网络层(Network)和链路层(Link)四层。。我们抓取到的网络包信息也是四层模型。

    网络抓包 Golang 实现

    使用 golang 实现网络抓包非常容易。得益于谷歌的包:

    github.com/google/gopacket github.com/google/gopacket/layers github.com/google/gopacket/pcap 

    这里我举一个监听网卡的 Demo 主要代码

    //device 网卡名 if handle, err := pcap.OpenLive(device, int32(n.Option.Snaplen), true, n.Option.TimeOut); err != nil { log.With("error", err.Error()).Errorln("PCAP OpenLive Error.") return 1 } else if err := handle.SetBPFFilter(n.Option.Expr); err != nil { // optional log.With("error", err.Error()).Errorln("PCAP SetBPFFilter Error.", n.Option.Expr) return 1 } else { log.Infoln("Start listen the device ", device) packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) go func(close chan struct{}, h *pcap.Handle) { for { select { case packet := <-packetSource.Packets(): n.handlePacket(packet) // Do something with a packet here. case <-close: log.Infoln("stop listen the device.") h.Close() return } } }(n.Option.Close, handle) } 

    这段代码就是监听某个网卡,通过n.Option.Expr规则过滤点无用网络包,规则语法与 linux tcpdump 一样。参考:PCAP-FILTER 接收到网络包一般有多种类型: 2 层模型的包,和 4 层模型的包。如果你不关注 tcp 握手这种类型的包你只需要关注具有四层模型的网络包。 n.handlePacket(packet)处理网络包。

    app := packet.ApplicationLayer() if app != nil { //log.With("type", app.LayerType().String()).Infoln("Receive a application layer packet") //log.Infoln(packet.String()) go func() { sd := &SourceData{ Source: app.Payload(), ReceiveDate: packet.Metadata().Timestamp, } tran := packet.TransportLayer() if tran != nil { src, dst := tran.TransportFlow().Endpoints() sd.SourcePoint = &src sd.TargetPoint = &dst if tran.LayerType().Contains(layers.LayerTypeTCP) { tcp := &layers.TCP{} err := tcp.DecodeFromBytes(tran.LayerContents(), gopacket.NilDecodeFeedback) if err != nil { log.With("error", err.Error()).Errorln("Decode bytes to TCP error") } else { sd.TCP = tcp } } } netL := packet.NetworkLayer() if netL != nil { src, dst := packet.NetworkLayer().NetworkFlow().Endpoints() sd.SourceHost = &src sd.TargetHost = &dst } decode := FindDecode(n.Option.Protocol) if decode != nil { decode.Decode(sd) } else { log.Debugf("%s protol can not be supported \n", n.Option.Protocol) } 

    如上代码简单处理四层模型网络包。一般你可以从网络层获取双方 ip 地址,从传输层获取双方端口以及 tcp 包的相关信息。从应用层获取应用数据。 具体的怎么优化和实践就留给大家自己尝试吧。

    网络抓包监控的优缺点

    优点:

    1. 应用无关性,监控工具通用性强。
    2. 数据全面性,你可以获取很多直接和间接反应应用状态的数据。
    3. 不侵入代码,一般不影响网络。
    4. 高并发下不影响应用。

    缺点:

    1. 资源消耗,抓包分析包是一个物理资源消耗的过程。
    2. 需要自己开发。

    总之,就像上文说得一样。如果你的需求只是想监控一个应用。你就别考虑这个方案了。如果你想监控集群中所有应用,你可以尝试。

    云盟认证成员barnett

    目前尚无回复
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5208 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered b solitude
    VERSION: 3.9.8.5 29ms UTC 08:41 PVG 16:41 LAX 00:41 JFK 03:41
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86