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

智数映风鹤
• 阅读 5499

微服务是什么?

此话题不是本文重点,如你还不知道。请谷歌一波,会有遍地的解释。引用下图说明下微服务可能呈现的形态:
基于网络抓包实现kubernetes中微服务的应用级监控

微服务监控的挑战

监控的目的是为了让集群中所有的服务组件,不管是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端完成分析,存储然后形成连续的实时的监控数据。下图展现个简要的整体架构图:

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

当然,上文已经说了,我们采取此方案主要就是为了能够监控各种应用,只是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

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
徐小夕 徐小夕
4年前
微前端架构初探以及我的前端技术盘点
前言最近几年微前端一直是前端界的热门议题,它类似于微服务架构,主要面向于浏览器端,能将一个复杂而庞大的单体应用拆分为多个功能模块清晰且独立的子应用,且共同服于务同一个主应用。各个子应用可以独立运行、独立开发和独立部署。微前端架构概念的诞生及应用对于提供复杂应用服务的企业来说显然是一种机遇,同样也是一种挑战.本文主要就微前端架构的概念和实现方案做一
Stella981 Stella981
3年前
Nebula Graph 在微众银行的实践
本文为微众银行大数据平台工程师——周可在nMeetup深圳场的演讲文字稿,演讲视频参见:B站(戳「阅读原文」观看)!(https://oscimg.oschina.net/oscnet/884d81502c744b76be00eb2a1b07d3c7.png)自我介绍下,我是微众银行大数据平台的工程
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Stella981 Stella981
3年前
Spring Cloud与微服务构建:Spring Cloud简介
SpringCloud简介<fontsize4微服务因该具备的功能</font微服务可以拆分为"微"和"服务"二字。"微"即小的意思,那到底多小才算"微"呢?可能不同的团队有不同的答案。从参与微服务的人数来讲,单个微服务从架构设计、代码开发、测试、运维人数加起来是8~10人才算"微"。那么何为"服务"呢?按照"微服务"概念
Stella981 Stella981
3年前
DevOps的支撑服务:K8s容器管理与应用部署
本文为云计算架构设计群的微课堂原创分享,转载需注明出处:EAII企业架构创新研究院。如需加入微信群参与微课堂、架构设计与讨论直播请直接回复此公众号:“加群姓名公司职位微信号”。大家好,本期微课堂介绍在新一代数字化企业云平台中对于Kubernetes的学习以及使用的总结。
Wesley13 Wesley13
3年前
10分钟上线
_摘要:_ 阿里云函数计算是一个事件驱动的全托管计算服务。通过函数计算,您无需管理服务器等基础设施,只需编写代码并上传。微信小程序是一种不需要下载安装即可使用的应用,它可以在微信内被便捷地获取和传播。当微信小程序遇见serverless,他们会产生奇妙火花,利用函数计算可以快速搭建微信小程序的serverle.点此查看原文:http://clic
Wesley13 Wesley13
3年前
MySQL为Null会导致5个问题,个个致命!
!(https://oscimg.oschina.net/oscnet/fa2b44bdaa7047cca0929dd7bb6cb752.jpg)作者|王磊来源|Java中文社群(ID:javacn666)转载请联系授权(微信ID:GG\_Stone)正式开始之前,我们先来看下MySQL服务器的配置和版本号信息,如下图
Stella981 Stella981
3年前
Devops下的分布式监控方案
_1基础监控的设计需求__现在devops,云计算,微服务,容器,大数据等理念正在逐步落地和大力发展,企业的服务器越来越多,架构越来越复杂,相应的应用运行基础环境越来越多样化,服务越来越微化,带来的监控压力也越来越大;_!(http://www.lvkaineng.com/wpcontent/u
少湖说 少湖说
9个月前
鸿蒙原生开发手记:01-元服务开发
简介元服务是鸿蒙中的一种轻量应用形态,无需下载,直接运行。类似于微信小程序,但与小程序不同的是,元服务更加轻量。元服务使用原生开发,是系统级提供的,无论从易用性、性能、体验上,都要比小程序好。创建元服务使用DevEco,点击Create,左侧模板选择Ato
智数映风鹤
智数映风鹤
Lv1
男人要豪爽,喝酒要喝双。
文章
5
粉丝
0
获赞
0