Mesos container在360广告系统的应用


背景简介


我是一名SRE工程师,我们负责管理与维护360商业广告平台,说起SRE工程师大家可能会想到谷歌公司,因为SRE毕竟是谷歌提出的概念。
作为SRE工程师我想说一下我们的自我修养。我们的主要工作是减少琐事,不断的扩大服务规模,同时我们还要保证整个系统的高可靠性和可维护性,不能随着业务规模的不断增大,招揽越来越多的人来维护业务是不合理的。
我们广告通过360搜索或者360手机端的应用进行展示,比如在360搜索输入“鲜花”会有广告展示,每天有数百亿次的投放与展示,手机端主要通过360的手机安全卫士,手机助手等等的一些应用进行广告的投放与展示。


Why Container?


说一下为什么要使用容器解决我们的问题,还有演讲的主题为什么不写Why Docker?
说到容器大家第一时间会想到Docker,它实现了一个容器引擎(Docker engine)。除了Docker,在容器生态圈还有一些公司他们实现了自己的容器引擎,比如CoreOS的RKT,比如我们使用的Mesos的容器引擎(Mesos containerizer),这些引擎不依赖于Docker本身,可以解决稳定性和扩展性的问题。
业务痛点
我先不说我们为什么用容器解决这些问题,说一下业务上我们有哪些痛点,并且这些问题可能大家都会碰到。
  1. 数据中心迁移,这个问题大家多数都会遇到,在迁移过程中要把之前的业务熟悉一遍,需要重新部署,测试还会遇到一些环境配置不一致的问题。


  2. 故障恢复,服务器宕机之后,传统业务都部署在物理服务器上,这样也需要重新部署,这样会带来很多麻烦。

  3. 操作系统不一致,现在我们很多不同的操作系统,比如CentOS 5、6、7都在用,迁移的时候很麻烦,还有一些系统内核的Bug需要去解决。

  4. 生产环境配置不一致,生产环境有一些服务器工程师都可以登录,如果改了一些配置导致线上出现问题的情况也是可能发生的。

  5. 测试环境不一致,可能每个人申请一台虚拟机专门做测试,导致测试结果也不一致。

  6. 服务的扩展性较低,传统业务扩容一般需要一台中控机或者有一套部署环境,每一次都需要重新添加一批服务器进行扩容。

  7. 服务器资源利用率问题,使用物理机部署服务,每一天都有服务的高峰低谷,由于采用静态资源划分的方式,资源利用率非常低会给公司造成很多资源上的浪费。


下面我来说一下我们为什么要用Docker来解决我们的问题。
Docker有一个隐喻叫“集装箱”。其实Docker的英文翻译是“码头工人”,这个隐喻给使用者很多暗示,告诉大家快来使用Docker吧,使用Docker就像使用集装箱一样,能够随时随地的,无拘无束的启动你的应用。像Docker官方的口号一样“build、ship、and Run Any APP Anywhere”,Docker为什么可以解决我们遇到的这些业务痛点呢?因为集装箱是有固定的标准,它的大小一致,这样货物在公路、铁路、海洋运输就不用考虑货物的尺寸等问题了,并且依赖大型机械化进行转运,等于是实现了一套标准的运输体系,可以给整个世界带来很大的商业潜力。
Docker的标准化怎么实现?
正如我上面说到的,Docker的实质化就是标准,Docker的标准化是怎么实现的呢?
首先,Docker有自己标准化的文档管理方式,它的标准化文档方式就是有自己的Dockerfile,可以定义一系列的软件系统版本。
第二点,Docker有对应用的统一操作方法,在物理环境不同的应用有不同的启动方法,如果你用Docker启动程序,可以通过docker run的方式来启动。在服务迁移过程中只要使用docker run命令来启动你的程序就可以了。
第三点,为了维护生产环境的一致性和配置变更的幂等性,Docker创造性的使用了类似Git管理代码的方式对环境镜像进行管理。每次都需要docker pull下载镜像,Docker container本身只有container layer这一层可写,你每次重新部署的时候这一层是会被删掉的,这样可以保证Docker实际环境每次都是幂等的。
在服务容器化过程中可能遇到的问题
在服务容器化过程当中,我们可能会遇到哪些问题?当大家使用物理机的时候,为了SSH登陆服务器,每台服务器都会开通SSH服务并且添加对应的账号。如果你使用Docker服务还要开通SSH服务的22端口,你需要考虑一下你的服务是否真的需要登录到容器中,或者你容器化的方式是否正确或者它是否适合你的业务。还有一些人这样使用Docker:在容器中开放rsync服务端口,甚至还有在Docker container里面部署puppet agent同步工具,这样做我觉得是完全没有必要的。我们都是不支持SSH或者类似的服务连接到Docker内部的。


如果你不让我登录到物理机上,不让我连到Docker内部,我怎么看我的日志呢?
我们有一套日志系统,后端对接的服务是Elasticsearch,会使用Docker的syslog模块通过UDP的方式写入Graylog里,Graylog或者Grafana都可以进行展示、查询,这样我们就可以及时的发现线上的问题。


Docker的网络性能


使用了Docker,大家可能会考虑,它的网络性能会怎么样,我们其实也做过一些调研。我们主要用的是Hostonly和Bridge这两种模式,如果用Hostonly基本和直接在物理服务器上运行程序的性能是差不多的,现在我们也有团队专门做Calico服务方面的研究,比如你有一些爬虫服务,可能希望有一些独立的外网IP,可以考虑使用Calico为一个container单独分配外网IP。
或者有网络隔离的需求的话,也可以使用Calico服务。由于我们主要针对是私有云,直接用hostonly模式多一些。
存储镜像
关于Docker仓库,大家可能会问服务容器化之后,主要用什么仓库存储镜像呢?哪种镜像仓库比较好?之前我们搭建过Docker官方的仓库,只有单节点不是高可用的,数据可靠性也不是非常好,我们是用的无认证模式。
现在我们使用了Harbor,用这个系统做了二次开发,后端存储用的S3存储系统,数据可靠性是非常高的,多机房之间可以进行数据同步,支持用户认证,大家根据自己的用户密码进行登录上传镜像等操作。之后我们还会做一个Docker仓库的CDN化,多机房直接访问CDN服务下载镜像。


怎样把数据写到本地
大家使用Docker可能会考虑数据怎么写到本地,我们使用Mesos+Docker之后,是不是所有服务都要需要无状态的呢?我们推荐无状态服务运行在Mesos+Docker之上。但是如果你有把日志落到本地的需求,我们现在也是可以支持的。


我列出的这些产品,比如CephFS、MySQL、Kafka、HDFS、Aerospike、Redis都是数据持久化的一种方式,比如流式数据一般用Kafka多一些,数据直接通过Kafka消费出来,通过一些计算模型后再重新写入Kafka,或者如果想数据落到本地的需求直接在Container中挂载CephFS也是可以的。
服务的注册和发现
关于服务的注册和发现,大家可能会有一些问题。比如我用了Mesos+Docker之后,我们的一些服务是在mesos-slave节点之间飘逸的,有可能因为一台物理机宕机了,你的服务会在另外一台mesos-slave节点上启动,我怎么知道我的服务启动到具体哪台IP或者具体哪台机器上呢?


我们服务发现主要用的是Mesos-DNS还有Marathon,底层数据依赖于ZooKeeper。还有一些公司可能用etcd或者Consul,我们也有在用不过比较少。
关于使用了Docker,服务如何进行调度?还有Docker服务如果对于本地数据有依赖的话需要如何加载?希望大家可以带着问题思考一下,一会儿我会详细说明。


Why Mesos?


为什么要用Mesos?
当前遇到的一个背景就是在当前互联网环境下,越来越多的分布式计算系统产生。


如果说维护一个大型业务团队需要部署的框架或者分布式系统非常多,但是市面上又没有一种系统能够把所有的应用框架都部署到一个集群里,这样就会导致我之前说的比如资源利用率会很低,可维护性很低。因为不同的集群有不同的配置,所以我们就想把这些多个应用布到一个大型的资源池里,这样可以更好的共享硬件资源。因为我们的服务都是支持动态扩缩容的,这样也可以简化一些部署上的逻辑,并且最大化的利用资源,最终实现服务可调度,数据可以共享。
使用Mesos的优点
1、资源利用率非常高
因为之前大家用物理服务器的时候,是静态资源划分的方式,这种方式资源浪费得比较多。因为服务每天都有高峰和低谷时段,如果你用Mesos的话,使用了动态服务扩缩容,比如白天广告展示的量会非常大,最高的时候每秒已经超过一百万,但是在晚上访问量非常低,你就可以把这批机器资源释放出来,供一些离线业务运行,比如Hadoop。可以达到最大化的资源利用率。


2、便捷性
Mesos本身支持对所有资源打标签,大家可以打固定的标签。这样在提交资源的时候,可以根据你想要的资源提出申请。比如你想要一个GPU的资源,比如你要1核的我就会分配给你一核的,像乘坐飞机一样,你想坐头等舱只要有资源就可以分配给你,Mesos也是这样,我们支持端口、CPU、内存、硬盘等等的划分。


3、可扩展性非常好
因为它本身的设计原理是两极调度框架,这样带来的好处是它非常的简单。因为Mesos本身只负责资源调度,把任务调度交给了运行在它之上的具体框架进行调度。所以如果你要横向扩展Mesos的话,非常方便。


4、模块化
因为Mesos支持在Mesos API之上定义各种各样的framework,大家可以自由添加framework,我们主要用的Marathon、Flink等官方与自定义framework,具体使用哪种框架,大家可以根据需要去设计。


Mesos的目标
Mesos的目标,其实主要就是给我们带来资源的高利用率,支持多种多样的自定义框架,包括当前支持的还有以后新产生的分布式计算框架等,都可以建立在Mesos之上。
  • 可扩展性。现在全球节点最大的是Twitter有45000个mesos-slave。

  • 可靠性。因为Mesos采用的是热备的方式,存在一个master节点,如果遇到主从节点切换的时候非常快,大概10秒钟就能完成。


Mesos的架构


Mesos的主要组成是由ZooKeeper实现master的高可用,还可以保证数据的一致性,保存所有的Mesos sleve节点和信息。Mesos master主要用于接收agent上报给Mesos master的资源,Mesos master会分配offer给具体给它之上运行的framework。
Framework是基于Mesos API定义的调度器,会根据调度需求分配具体的offer。
最底层是Mesos agent,用来接受和执行Mesos master发给它的命令,通过Mesos agent之上的executor启动task。
Mesos的实现

Mesos是用的两万行的C++代码编写而成,故障恢复使用的是ZooKeeper,框架都是可拓展的、可以自定义的,并且是模块化的。是Apache顶级的孵化项目,同时还是开源的,项目成立于2009年。
Mesos的结果
Mesos给我们带来的是更高的资源利用率与可靠性。
Mesos master的故障恢复机制
接下来说一下Mesos master的故障恢复机制。


因为Mesos master只有一个软体状态,只会列出它之上的framework以及mesos-slave的信息,在Mesos master需要进行切换的时候,通过ZooKeeper进行leader的重新选取,选取好新的leader后,只需要所有的framework和mesos-slave节点重新注册到新的Mesos master之上,时间就10秒钟左右。如有你有上万台机器,可能会同时连Mesos master会不会造成大量的链接导致master服务不可用,官方有这样的设置可以设定链接的比例来进行控制。
Mesos的生态圈有哪些框架
Marthon framework


  • 运行长任务。从应用框架字面的意思,任务就像跑长跑一样,这个框架其实就是运行长任务(long running job)的。


  • 服务发现。Marathon还可以实现服务发现,有比较好的API接口,比如我有一个APP id对应具体机器的IP是什么。


  • 健康检测&事件通知机制。Marathon支持对你所启动的任务进行健康检测,比如端口或者你自定义命令都可以,有事件通知机制,正因为有了事件通知机制才可以在马拉松之上建立一些实时的服务发现,知道哪些服务宕掉了,在哪些新节点启动了,可以保证我们的实时发现服务,重新指向新的服务器。


  • WebUI。Marathon有自己的Web UI,可以通过界面直接操作,非常方便。


  • 限定条件。你可以设定一大堆的限定条件,比如我之前说的像你选飞机的舱位一样,你设定了网卡必须是万兆的,Marathon会根据你设定的限定条件,帮你选择对应资源。


  • Labels。Labels标签也是我们常用的,随着资源利用率越来越大,可能有各种应用,大家可以加上各种的标签,方便的查询。


  • 数据持久化。数据持久化也是支持的,可以支持挂载本地卷。


  • 服务的预热。这个功能用得不是特别多,比如你在服务启动的时候会需要启动时间,这个时间健康检测是失败的,你可能需要设定一个预热时间,保证服务启动之后正常的健康检测才生效。


  • 优雅退出。优雅退出这个问题,大家可能都会遇到,比如像C++不涉及内存自动回收可能需要程序上设计优雅退出的问题,你可以通过Marathon设置一个退出时间,保证你的服务正常退出之后,才把以前的服务都退掉,新的服务启动。


  • 支持自定义的containerizer和GPU资源的调度。


Marathon-LB


Marathon-LB是我们用的一个实时发现的服务,Marathon-LB是基于Haproxy和Marathon eventbus机制设计的。其实除了Marathon-LB还有一些其他的服务实时发现,但是都是基于Marathon的事件通知机制设计的。因为Marathon有事件总线的实时更新,可以实时的改变服务后端的IP。如果有宕机或者有服务自动扩缩容的话,Marathon-LB可以实时改变Haproxy的配置,Marathon-LB主要是通过第四层IP加端口的方式进行服务代理,Marathon-LB支持TCP或者HTTP的代理方式。
Mesos-DNS


我们还使用了Mesos官方的Mesos-DNS服务,用于一些对实时性要求不高的服务,比如我们把STORM容器化以后Nimbus和Supervisor之间的通信可能就不是那么频繁,如果有Nimbus宕机的情况,只需要通过Mesos-DNS就可以重新发现AppID对应的新的Nimbus IP。你可以使用Mesos-DNS发现AppID对应的所有后端节点的IP,可以保证你的服务节点随时都可以访问到你想访问到的IP。Mesos-DNS有一定的延迟性,我们测试大概有十几秒。


Mesos VS YARN


我说一下在我们做技术选型的时候,我们也做过Mesos和YARN方面的调研。
Mesos主要是能调度各种样的资源,有CPU、内存、端口、硬盘;YARN主要是CPU和内存。
两者都是两极调度策略但是又有不同。
Mesos本身只做资源的调度,不负责具体任务的调度,把任务调度交给framework调度。
YARN全都是YARN本身进行资源调度,一个程序提交给它一个任务都由YARN来决定是否接受或者拒绝这个资源,而Mesos却不同。
Mesos因为是对物理资源进行管理与调度的,YARN主要基于Hadoop来做。根据需要,我们最后还是选择了Mesos来作我们的分布资源管理框架。


Mesos VS Kubernetes


说起Mesos可能很多同学觉得使用了Marathon提供了容器任务的管理能力,可能就需要跟Kubernetes系统进行比较一下。
本身来讲,Mesos和Kubernetes是两个东西,Mesos是一个分布式的资源管理框架,被称为分布式系统的内核。假如你有很多物理资源,你想把它整合成一个逻辑资源层面的物理资源池,那么你用Mesos是最合适不过的了。
Mesos解决问题的核心是如何把资源整合成一个大型的物理资源池,它上面运行什么,怎么跑它并不关注。
Kubernetes主要是一个自动化的容器操作平台,操作主要包括部署、调度还有节点集群间的扩容等等。
Kubernetes解决问题的核心主要是围绕容器来做的,这两个系统本身没有可比性。因为Mesos支持很多framework,比如Marathon可以实现容器的调度,所以大家就会把这两个平台进行比较。
如果你想搭建这样一个容器管理平台或者调度平台,从我个人来讲第一点从任务上来讲,Marathon只支持长任务型的,Kubernetes支持的比较广,比如支持长时间任务(long running job),节点后台支撑型(node-daemon)等等各种各样的任务。
说一下稳定性方面,Kubernetes是谷歌官方推出的,它的更新比较频繁,更新频繁可能带来的就不是特别稳定,大家可能理解我可以多做一些线下测试,但是事实确实是这样的,Kubernetes更新非常频繁。Mesos一般每半年更新一次,一年发布两个版本,会经过充分测试。Mesos产品设计因为是开源的,是Apache基金会下面的顶级项目,会在社区跟大家进行投票与沟通,决定未来我们的产品怎么做,我们会增加哪些功能。
第三种主要是从功能上来讲,Kubernetes是由谷歌做的,所以它的考虑会非常全面,它的生态非常全面,你想要的功能基本都有,包括网络Kubernetes其实也是有的,其实Kubernetes本身的网络做得不是特别好,很多用Kubernetes都是用Calico实现的。Mesos系统的设计思路则定义了任务调度和功能上整体依赖于调度器的设计,所以可以把Mesos看成一个大乐高底层的基础板。
对于这两个框架,选择哪一个都没有对与错,只有适合与否,选择一个适合你们的工具才是最重要的。


Mesos/Container在360的一些应用


我说一下Mesos/Container在360的一些应用。


我们从2015年开始,就对分布式的调度系统或者容器调度平台进行了调研,最后选择使用Mesos,因为我们想构建一个大型的物理资源池。在2016年业务正式上线,包括之后说的一些服务的容器化,2016年我们也使用了Chronos,可以运行一些物理机上运行的crontab任务,长时间支持服务在线运行。2017年我们已经实现了两个机房各部署了一个大型的资源池,节点达到了单集群最大1000个以上,任务达到5000个以上,10个以上的自定义framework。
解决的问题
部署,现在部署可能你只需要在Marathon上改变你的镜像(image)地址,或者只需要把instance数改大就可以扩容。
故障恢复,如果有一台mesos-slave宕掉了,会自动在其他的节点上启动。
服务降级,关于服务降级,我们的资源池服务器是有限的,1000台服务器如果资源快用满了,有些业务就需要做服务降级,不是所有业务都有动态扩缩容。我们主要处理广告业务,广告业务实时日志流比较多,在资源不够的时候,会让某些业务降级。平时每秒处理20万条,降级时让它每秒处理10万条或者5万条,有一定数据延迟也没有关系,因为数据不会丢只会慢慢处理完。
服务发现,关于服务发现,现在有了Mesos-DNS和Marathon-LB我们可以做到实时的服务发现,因为是动态资源划分,我们的任务就可能实时变化。
Storm集群的容器化


上图是原来通过物理级部署的,所有的Supervisor节点都是一台台物理机还要单独部署一个Nimbus,如果Nimbus节点宕掉非常麻烦,比如有些同学说我可能会用Keepalived做高可用,这确实是一种方案,但是如果你的集群需要频繁的扩容或者缩容就会非常麻烦,你要是不对资源进行动态管理的话,势必带来的就是资源的浪费,因为不可能一天24小时都满负荷运行。
把服务容器化之后,所有的Supervisor都运行在container(mesos-slave)中,Supervisor节点会通过Mesos-DNS发现Nimbus(master)的IP。现在集群资源都是动态利用的。


图片服务的容器化
重点说一下图片服务的容器化。


图片服务主要用的PHP 7来做的,我们也会面临像阿里一样在双十一的时候,因为广告展示与投放量非常大,每秒达到上百万次,因为给用户进行展示与投放的图片会根据用户的习惯去动态的缩放与拼接。如果我放着很多机器专门用来做图片服务,可能也可以达到你的需求,但是在空闲时间段比如夜里资源浪费得非常多,对资源的利用率不是非常好。
我们就制定了这样一套方案,首先把PHP服务容器化,之后我们根据亚马逊AWS的策略,做了自己的方案,跑一个long running job,根据Marathon的API获取你的图片服务具体是哪台机器,由于所有机器上的监控都用了二次开发,通过API接口能获取负载、CPU,内存等等信息。当图片服务器的负载上升了肯定是压力最大的时候,这样我们只需要设定一个阈值。
比如系统负载大于10超过10次,就进行一次扩容,扩容的倍数是1.5倍,原来我有10台机器,现在要扩容到15台。大家可能会问你这个最大能扩到多少?我一定要设定一个最大值不能无限的扩。比如我们设定一个36,最大扩到36台,在5分钟内可能判断10次,如果这个负载水平一直很高,就不进行缩容。
我肯定还会设定一个最低值,比如最低值是6台,可能到了夜里直接减为6台,每次都需要通过Marathon的API实时发现后端所有机器计算出一个平均值。服务的监控,我们对每台Mesos slave都有监控,具体的container我们做了异步,通过异步把日志写到Graylog中,监控日志传输通过UDP协议。如果发生网络中断的情况也不会有太大影响,因为UDP是可丢的不可靠的。
其他
我们还有其他服务的一些容器化,有Web service相关的,Aerospike服务,通过组播实现集群之间的通信部署起来比较方便,Marathon-LB也是完全的Docker化的,毕竟是代理层像LVS一样,可能会有服务瓶颈。Kafka MirrorMaker我们用来进行多机房之间的数据传输,原来直接部署在物理机上,这样虽然不会有太大问题,如果宕掉之后数据不能在多个集群当中进行同步,对实时性不能要求那么高。如果做了容器化之后是可调度的,都是可高可用的,我们会保证服务的可靠性。Redis也有做容器化,支持数据的落地和持久化,因为我们有CephFS还有更多的一些无状态的服务也运行在Mesos之上。


最后我要说一下我们的服务CI/CD是怎么做的,CI/CD主要是通过GitLab runner。我们会定义一个Gitlab-CI,可以直接把你提交的代码进行Docker build,把镜像自动提交到对应的仓库,通过API修改Marathon上面对应的地址,最后实现上线自动化。


未来计划


未来我们想做的,因为CephFS的量不是很大,CephFS之后想上一些写入量比较大的业务,看看效果如何。我们不是做公有云的对于Calico的需求不是那么急切,之前一直没有上这个服务。之后我们可能会做一些Calico相关的,比如一些爬虫的应用,如果用公司的Nat代理的话,可能遇到一些IP被封,导致整个代理IP都不能访问对应的网站就有一些问题了。
还有一些实时的机器学习,现在机器学习主要都基于离线业务来做,实时学习比较少,Marathon和Mesos本身是支持的。
本文转载自公众号:HULK一线技术杂谈, 点击查看原文


Kubernetes入门与进阶实战培训


本次培训内容包括:Docker基础、容器技术、Docker镜像、数据共享与持久化、Docker三驾马车、Docker实践、Kubernetes基础、Pod基础与进阶、常用对象操作、服务发现、Helm、Kubernetes核心组件原理分析、Kubernetes服务质量保证、调度详解与应用场景、网络、基于Kubernetes的CI/CD、基于Kubernetes的配置管理等, 点击了解具体培训内容

6月22日正式上课,点击阅读原文链接即可报名。

猜你喜欢

转载自blog.csdn.net/m2l0zgssvc7r69efdtj/article/details/80479184