背景
360在做容器化平台之前,有一个基于小米开源的Open-Falcon进行二次开发的老监控系(Wonder),这个系统承揽了公司所有的物理机和虚拟机的监控任务。随着容器技术的普及,以容器的方式在创建应用时,由于Kubernetes容器编排系统部署的服务具有弹性扩容的特性,而老的监控系统无法感知这些动态创建的服务,已经不适合容器化的场景,所以360团队就搭建了一套可以支持服务发现的新监控系统。
目前360一共有5个k8s线上集群,分布在北京上海和深圳,此外还有一些GPU集群。
容器平台构建以后带来了以下几个方面的好处:
- 节省资源。传统一台物理机只能部署一个实例,虚拟机能部署几个服务,而使用容器一台机器上能部署几十个服务。
- 提高效率。1. 缩短流程。老系统要增加机器需要提前申请,而使用Kubernetes容器平台只要整个资源池里有充足的资源,不用提交预算就可以直接使用。2. 弹性扩容。在流量高峰期,容器平台可以快速扩容;在流量不多的时段,空闲的资源可以处理其他离线任务,对资源的利用率高。
- 高可用。容器平台可以保证运行的服务数量总是能达到预期。
- 减轻运维负担。之前所有的部署上线活动都是运维来做。容器平台上线后,开发人员可以直接在程序完成之后将其制作成镜像,自己就可以进行部署。
当然任何事情不可能只有好的一面,容器平台也会带来相应的难度。容器平台对服务的调度具有动态性,这就需要监控系统能动态感知服务实例落在哪里,这是监控工作中的一个难点。
360容器平台的监控维度
360容器平台的监控系统对业务的技术指标进行监控,产品是从三个维度进行设计的:
- 容器: 这是最小的粒度。
- Pod: 一个Pod里面可以有多个容器。
- 应用: 一个应用里可能会有多个Pod。
除了这些技术指标监控,360容器平台的监控系统还支持自定义监控。有些业务可能需要在自己的程序里打点,比如要调第三方接口,查看延时和调用的次数等。大平台上不同业务对数据的需求不同,为了达到业务需求,支持自定义监控还是很必要的。新开发的业务可以在自己的程序里引入Prometheus相关的SDK进行打点,360的容器平台就会将这些metrics收集上来。
另外,没有使用Prometheus的老系统在开发时没有在程序里打点的功能,这时业务可以针对自己的需求以sidecar的方式在程序的边缘写exporter来采集该进程所有的监控数据,exporter以metrics的形式报告给Prometheus,Prometheus进行抓取。
监控系统设计
360容器平台监控系统架构图如下:
日志监控
360容器平台监控系统的日志监控使用的是ELK技术栈,但是进行了二次开发。团队自己写了 Log controller组件,该组件会实时地watch Kubernetes API Server的Deployment资源对象的状态变化。当业务在创建应用时,是以Kubernetes deployment 的资源对象来创建的。Log controller会感知到这个资源的创建,知道这个 deployment下有多少Pod已经处于Ready状态。当Log controller感知到新创建的Pod已经处于Ready状态以后,会根据用户在创建Pod时指定的真实日志收集路径拼接成它在物理机上的绝对路径,然后将组装好的配置并推送到360 自研的配置中心QConf中。
360 在Kubernetes集群的每个Node节点都会部署一个二次开发的Logstash,该Logstash会定期(每隔十秒或者五秒,时间可配置)去配置中心(Qconf)拉取最新的配置。拉取完配置之后,Logstash会根据最新的配置把相关的的日志收集到公司的Qbus(对Kafka进行包装的产品)中,也就是数据已经进入到Kafka了。之后用户可以在HULK私有云平台(内部的私有云平台)开通 ES服务,对日志进行检索分析或对其他日志指定数据进行监控。
数据面板
360容器平台监控系统的数据面板使用的是Grafana,并对其增加了LDAP用户认证。可以显示内存,访问量,SIO, GPU等监控数据指标。
应用级别基础监控指标:
Pod 级别基础监控指标:
容器级别基础监控指标:
Prometheus的基本原理是通过HTTP协议周期性抓取被监控组件的状态,任意组件只要提供对应的HTTP接口就可以接入监控。不需要任何SDK或者其他的集成过程。这样做非常适合做虚拟化环境监控系统,比如VM、Docker、Kubernetes等。输出被监控组件信息的HTTP接口被叫做exporter 。目前常用的组件大部分都有exporter可以直接使用,比如HAproxy、Nginx、MySQL、Linux系统信息(包括磁盘、内存、CPU、网络等等)。
报警
报警系统使用的是Prometheus自带的Alertmanager组件,但是对其进行二次开发,集成了360自己的报警系统(Qalram),并且可以通过360自己的即时通信工具(蓝信)实时接收报警信息,友好方便快捷。
360容器平台监控系统选型对比
在构建容器平台的过程中,360团队对监控系统的几种常用的开源方案进行过选型对比,主要调研了K8s社区的Heapster(K8s安装过程中默认安装的插件)和Prometheus。
Heapster+InlfuxDB+Heapster自带报警系统的方案有个缺点:它是针对K8s容器级别以及Code级别的技术指标监控,无法实现业务系统数据的监控,可扩展性不太友好,并且当未来数量级大时,不方便扩容。
最后团队选择了Prometheus 云原生监控方案。虽然Prometheus在持久化方面做的还不够好,但是Prometheus更适合云原生生态。因为容器是动态变化的,微服务架构下一个实例的多个副本也是动态变化的,Prometheus的Pull方式更适合动态变化的场景。
Prometheus的应用实践
高可用
现在由于每个机房的机器数量不算太多,当前的设计方式是在每个机房部署一套Prometheus实例用于抓取目标的监控数据,同时在每个机房的上一层会部署两套Prometheus来做高可用(HA). 这样上层的Prometheus只要去下层抓取关心的metrics就可以。这样做的好处:
- 过滤掉上层不关心的监控数据,减轻数据存储的压力。
- 对各个机房的数据进行聚合,并统一对外提供统一的报警,视图查询接口。
- 由于promethues实例运行在本地,本地的磁盘空间有限,默认只保留最近15天的监控数据,但是想查询最近一个月,或者半年的数据,这个需求是做不到的。所以将prometheus的数据又入到了远程存储InfluxDB一份,用于数据的查询使用。
报警
Prometheus的报警基于配置文件形式的。这种情况下,基础性指标可以产品化。360团队定制了配置模版,用户只需要填具体的监控值就可以了。
针对业务监控,用户需要学习Prometheus的promQL,这是由于不同的业务监控的需求不同,没有办法给业务统一的产品化服务,只能按业务自己制定报警规则去下发报警。
对于自定义业务,让业务自己写告警,统一的配置文件会上报到QConf。
运行在两台Prometheus机器上Agent会实时的watch配置中心(Qconf)是否有新的配置生成,如果存在则会Pull报警规则,并reload Prometheus实例。
为什么要使用开源系统
一般公司都有自研的监控系统,大多数监控系统都是基于开源项目开发的。为什么360要使用Prometheus?
- 在K8s大规模使用的今天,整个容器云的生态推荐使用Prometheus。
- 节省人力成本。公司开发一套监控系统需要投入人力,如果后期开发人员流失,后期的维护是个大问题。但是使用开源监控系统,在社区活跃的情况下项目也有保证,并且我们也会在使用过程中回馈社区。
360容器平台监控系统演进方向
目前的监控系统整体架构对于容器平台来说可扩展性比较好。未来随着集群规模不断扩大,单个集群只有一个Prometheus实例要处理的Job数量爆发时,Prometheus的性能就会变差。这个时候可以针对不同的任务类型,在一个集群里部署多个Prometheus,每一个Prometheus只关心自己的任务,可控性会大大提升,同时整个架构的横向扩展比较方便。
另外Prometheus存在持久化的问题,未来还需要对Prometheus进行数据远程存储(在上面的架构图中使用的虚线标注部分)。
除了数据,360也在探索AIOps,可以对监控系统收集到的数据进行处理,探索故障定位和根因分析等。
普通团队如何构建监控系统?
360监控团队认为,公司的监控系统要根据公司的规模和业务场景来定,不可能一套方案直接拿来就直接使用。
对于使用公有云并且规模较小的公司,公有云本身就有监控系统。如果公司自己有服务器,但是量不大,简单搭建一个小型HA的监控系统就完全可以满足监控的需求了。架构的演变是随着业务规模的增长而不断的演变改进的。这时就需要根据具体的情况,去选择适合自己平台的架构方案。
作者简介
王希刚,目前在360做运维开发工作,有着多年PaaS设计及开发经验,对Kubernetes,Docker等有较深入的研究。目前主要负责360 HULK容器云平台的研发工作。