DockOne技术分享(二十一):Mesos在去哪儿网的应用


【编者的话】Mesos在Qunar DevOps团队内部的应用。

平台介绍

我们是在今年的5月份开始调研并尝试使用Mesos,第一个试点就是我们的日志平台,我们将日志分析全部托管在Mesos平台上。日志平台面向业务线开发、测试、运营人员,方便定位、追溯线上问题和运营报表。
平台结构.png

这个是我们平台的结构概览。

日志分析我们使用ELK(Elasticsearch、Logstash、Kibana),这三个应该说是目前非常常见的工具了。而且方案成熟,文档丰富,社区活跃(以上几点可以作为开源选型的重要参考点)。稍微定制了下Kibana和Logstash,主要是为了接入公司的监控和认证体系。

日志的入口有很多,如kernel、mail、cron、dmesg等日志通过rsyslog收集。业务日志通过flume收集,容器日志则使用mozilla的heka和fluentd收集。

这里稍稍给heka和fluentd打个广告,两者配合收集Mesos平台内的容器日志非常方便,可以直接利用MESOS_TASK_ID区分容器(此环境变量由Mesos启动容器时注入)。而且我们也有打算用heka替换logstash。

Mesos技术栈

下面主要分享一下Mesos这块,我们使用了两个框架:Marathon和Chronos,另外自己开发了一个监控框架Universe。

先说Marathon,eventSubscriptions是个好功能,通过它的httpcallback可以有很多玩法,群里经常提到的bamboo就是利用这个功能做的。利用好这个功能,做容器监控就非常简单了。

接着是Marathon的重启(更新),推荐设置一下minimumHealthCapacity,这样可以减少重启(更新)时的资源占用,防止同时PUT多个应用时耗光集群资源。

服务发现,Marathon提供了servicerouter.py导出haproxy配置,或者是bamboo,但是我们现在没有使用这两个。而是按协议分成了两部分,HTTP协议的服务是使用OpenResty开发了一个插件,动态加载Marathon(Mesos)内的应用信息,外部访问的时候proxy_pass到Mesos集群内的一个应用,支持upstream的配置。

非HTTP的应用,比如集群内部的statsd的UDP消息,我们就直接用Mesos DNS + 固定端口来做了。随即端口的应用依赖entrypoint拉取域名+端口动态替换。

带有UNIQUE attribute的应用,官方目前还无法做到自动扩容,从我们的使用情况来看,基于UNIQUE方式发布的应用全部是基础服务,比如statsd、heka(收集本机的Docker日志)、cAdvisor(监控容器)等,集群新加机器的时候Marathon不会自动scale UNIQUE实例的数量,这块功能社区正在考虑加进去。我们自己写了一个daemon,专门用来监控UNIQUE的服务,发现有新机器就自动scale,省的自己上去点了。
监控框架.png

另外一个问题,资源碎片化,Marathon只是个框架,关注点也不在这里。Mesos的UI里虽然有统计,但是很难反应真实的情况,于是我们就自己写了一个Mesos的框架,专门来计算资源碎片和真实的余量,模拟发布情况,这样我们发布新应用或者扩容的时候,就知道集群内真实的资源余量能否支持本次发布,这些数据会抄送一份给我们的监控/报警系统。Chronos我们主要是跑一些定时清理和监控的脚本。

Docker这块,我们没有做什么改动,网络都使用host模式。Docker的监控和日志上面也提到了,我们用的是cAdvisor和heka,很好很强大,美中不足的是cAdvisor接入我们自己的监控系统要做定制。

我们也捣鼓了一个Docker SSH Proxy,可能是我们更习惯用虚拟机的缘故吧,有时候还是喜欢进入到容器里去干点啥的(其实业务线对这个需求更强烈),就是第一张图里的octopus,模拟docker exec -it的工作原理,对接Mesos和Marathon抓取容器信息。这样开发人员在自己机器上就能SSH到容器内部debug了,也省去了申请机器账号的时间了。

应用方案

接着说说我们的日志平台。这个平台的日志解析部分全部跑在Mesos上,平台自身与业务线整合度比较深,对接了一些内部系统,主要是为了考虑兼容性和业务线资源复用的问题,我尽量省略与内部系统关联的部分,毕竟这块不是通用性的。

平台目前跑了有600+的容器,网络是Docker自带的host模式,每天给业务线处理51亿+日志,延时控制在60~100ms以内。

最先遇到的问题是镜像,是把镜像做成代码库,还是一个运行环境?或者更极端点,做一个通用的base image?结合Logstash、heka、statsd等应用特点后,我们发现运行环境更适合,这些应用变化最大的经常是配置文件。所以我们先剥离配置文件到GitLab,版本控制交给GitLab,镜像启动后再根据tag拉取。

另外,Logstash的监控比较少,能用的也就一个metrics filter,写Ruby代码调试不太方便。索性就直接改了Logstash源码,加了一些监控项进去,主要是监控两个Queue的状态,顺便也监控了下EPS和解析延时。

Kafka的partition lag统计跑在了Chronos上,配合我们每个机房专门用来引流的Logstash,监控业务线日志的流量变得轻松多了。
watcher系统.png

容器监控最开始是自己开发的,从Mesos的接口里获取的数据,后来发现hostname:UNIQUE的应用Mesos经常取不到数据,就转而使用cAdvisor了,对于Mesos/Marathon发布的应用,cAdvisor需要通过libcontainer读取容器的config.json文件,获取ENV列表,拿到MESOS_TASK_ID和MARATHON_APP_ID,根据这两个值做聚合后再发到statsd里(上面提到的定制思路)。

发布这块我们围绕这Jenkins做了一个串接。业务线的开发同学写filter并提交到GitLab,打tag就发布了。发布的时候会根据集群规划替换input和output,并验证配置,发布到线上。本地也提供了一个sandbox,模拟线上的环境给开发人员debug自己的filter用。
发布系统.png

同时发布过程中我们还会做一些小动作,比如Kibana索引的自动创建,Dashboard的导入导出,尽最大可能减少业务线配置Kibana的时间。每个应用都会启动独立的Kibana实例,这样不同业务线间的ACL也省略了,简单粗暴,方便管理。没人使用的时候自动回收Kibana容器,有访问了再重新发一个。

除了ELK,我们也在尝试Storm on Mesos,感觉这个坑还挺多的,正在努力的趟坑中。扫清后再与大家一起交流。

今天的内容就到这里,感谢大家。

Q&A

Q:Mesos和Yarn的区别在哪里?

A:Mesos的主要目标就是去帮助管理不同框架(或者应用栈)间的集群资源。比如说,有一个业务需要在同一个物理集群上同时运行Hadoop,Storm及Spark。这种情况下,现有的调度器是无法完成跨框架间的如此细粒度的资源共享的。Hadoop的YARN调度器是一个中央调度器,它可以允许多个框架运行在一个集群里。但是,要使用框架特定的算法或者调度策略的话就变得很难了,因为多个框架间只有一种调度算法。比如说,MPI使用的是组调度算法,而Spark用的是延迟调度。它们两个同时运行在一个集群上会导致供求关系的冲突。还有一个办法就是将集群物理拆分成多个小的集群,然后将不同的框架独立地运行在这些小集群上。再有一个方法就是为每个框架分配一组虚拟机。正如Regola和Ducom所说的,虚拟化被认为是一个性能瓶颈,尤其是在高性能计算(HPC)系统中。这正是Mesos适合的场景——它允许用户跨框架来管理集群资源。


Mesos是一个双层调度器。在第一层中,Mesos将一定的资源提供(以容器的形式)给对应的框架。框架在第二层接收到资源后,会运行自己的调度算法来将任务分配到Mesos所提供的这些资源上。和Hadoop YARN的这种中央调度器相比,或许它在集群资源使用方面并不是那么高效。但是它带来了灵活性——比如说,多个框架实例可以运行在一个集群里。这是现有的这些调度器都无法实现的。就算是Hadoop YARN也只是尽量争取在同一个集群上支持类似MPI这样的第三方框架而已。更重要的是,随着新框架的诞生,比如说Samza最近就被LinkedIn开源出来了——有了Mesos这些新框架可以试验性地部署到现有的集群上,和其它的框架和平共处。
Q:基础架构里面,数据持久化怎么做的?使用是么架构的存储?

A:持久化剥离在集群外部,Mesos 0.23提供了持久化的支持,但是没敢上到生产环境中。
Q:Storm on Mesos,快可用了吗?是否跟Spark on Mesos做过比较?

A:Storm on Mesos的代码在GitHub可以找到,说实话只是基础功能,许多资源的控制和attributes的东西都没有做,而且我们的测试发现storm on mesos的消息ack特别慢。不建议直接拿来就跑。
Q:发布用的业务镜像是怎么制作的,平台有相关功能支持吗?还是用户手工做好上传?

A:Jenkins build的镜像,可以用Jenkins on Mesos这个框架,安装Docker和mesos插件就可以开始用了。
Q:做这么个平台用多大规模的团队开发的?用了多久?

A:开始2个人,最多的时候5个人,现在保持在4个人。从5月份到现在一点一点测试,扩容慢慢堆出来的。
Q:镜像存储单机应该是不行的,你们是怎么管理镜像的?

A:镜像放swift里了。
Q:Docker采用host方式,是什么考虑或者限制,效果怎么样?

A:平台本身就是大吞吐量的,bridge模式性能测试都偏低,就选择了host模式跑了。
Q:Mesos的调度算法是怎样的?有没有做容器的高可用?

A:双层调度,底层offer一个资源列表给framework,framework根据CPU和内存去列表中过滤,选中合适的slave部署,framework层的调度可以随意实现。Marathon已经帮忙做了高可用。
Q:使用效果如何?600容器部在多少台机器上,CPU和内存使用率多少?有什么提升资源使用率的策略吗?

A:效果达到预想了,600台分部在了混合集群上,有VM和实体机,全部折算的话大概30台左右吧,目前资源还有富余,主要是预留buffer。不推荐跑虚拟机,Mesos的资源分配就是一刀切,即使没用也算的,所以虚拟机利用率会很低。
Q:mesos在哪一层面实施了paxos投票?

A:leader的选举,mesos其实是两套选举,即使zk挂了mesos master也可以自己选举leader。
Q:为什么选择heka,而不是fluend,然后logstash有什么问题?

A:fluent和heka我们都在用,都是收容器日志,heka可以从容器的ENV里读更多东西出来。换logstash主要看重了heka的监控,资源占用和处理速度。
Q:会涉及数据卷的迁移吗,有什么好解决方案?

A:目前平台里没有持久化的东西。这块不敢说用什么合适,我们也没开始尝试。
Q:镜像做成代码库和运行环境具体是什么意思,为什么运行环境方式合适?

A:镜像具体做成什么样要根据自己的应用来判断,我们用的logstash、statsd什么的,都是配置文件描述流程的,所以我们选择了运行环境的方式。
Q:镜方式像做成代码库和运行环境具体是什么意思?

A:代码库就是说你把你工程的代码,配置什么的都全部打成一个镜像。 运行环境就是有一些bin或者Java、PHP这些工具的,启动后才下载代码,配置。
Q:你们会不会遇到跨机房的MesOS问题啊,如果跨机房,怎么办?

A:有跨机房的情况,我们机房间有logstash专门转发日志流量,统一管控。
Q:比如数据库初始化的脚本,做在镜像里合适还是有其他方式比较好?

A:db的数据文件其实挺难脱离外层的应用单独说的,因为有业务线代码引起的schema变更,最好先解决db ci的问题,然后再考虑数据何时加载,可以映射上对应schema的时候,db文件可以先从swift等共享存储直接下载到本地使用,或者用脚本重新初始化也可以,我们的快速rebuild环境正在试验。业务线还不敢这么来。
Q:用运行环境方式,容器启动后再拉代码和配置,不符合Docker设计镜像的初衷吧,怎么做到一处打包到处运行,镜像不是完整可执行的?

A:主要是代码库版本和镜像的tag如何映射,为了简单点可以考虑启动后下载代码,如果代码已经编译好放到了共享存储里直接下载代码包也可以。我们目前没有考虑过把代码库版本和镜像tag映射这个问题。
Q:Mesos资源统计会出现与实际不符,你们的解决思路是什么?

A:要看是什么资源了,Mesos的划资源的格子属于一刀切的方式,即使你没用满也会被归入已使用的资源里,如果从这个角度看,实际运行的资源和Mesos内上报的资源确实不一致,但是考虑到计算资源的周期性,突发性,还是推荐以Mesos上报的资源为准。我们自己跑在Mesos上的监控framework本身也是这么做的。
Q:cAdvisor好像只能监控单机容器情况,那对于集群的容器监控,使用ca怎么处理呢?

A:我们目前是cAdvisor聚合好以后发给我们的公司的监控平台,由监控平台统一处理。最新版已经merge了许多storage-driver了,statsd值得试一下。
===========================
以上内容根据2015年9月15日晚微信群分享内容整理。分享人 徐磊,现任职于去哪儿网OpsDev团队,曾任职于红帽HSS部门。 DockOne每周都会组织定向的技术分享,欢迎感兴趣的同学加微信:liyingjiesx,进群参与,您有想听的话题可以给我们留言。

1 个评论

好文章

要回复文章请先登录注册