刘伟 360云计算 html
咱们发现公司的服务器cpu, memory等资源利用并不充分;若是可以充分利用这些机器上的空闲资源同时又能保证业务服务的正常运行,将会节省很多的机器资源;因此咱们研究了Mesos来构建多任务调度系统。接下来就为你们介绍下咱们的Mesos系统。
PS:丰富的一线技术、多元化的表现形式,尽在“HULK一线技术杂谈”,点关注哦!java
公司内部的云平台为各个业务线提供了大量的实体机和虚拟机来运行业务的服务,通过统计发现,这些分配给业务的机器cpu, memory等资源利用并不充分;node
若是可以充分利用这些机器上的空闲资源同时又能保证业务服务的正常运行,将会节省很多的机器资源;python
一提到多任务运行和调度,大部分人可能首先都会想到Kubernetes(k8s) + Docker, 跑起来如清风拂面, 顺畅无比。然而咱们的业务机器大部分为centos 6.2, linux kernel 2.6的环境,而docker的运行须要Linux kernel的版本是 3.10+
(可参考: https://docs.docker.com/engine/faq/#how-do-i-connect-docker-containers)
由于想利用业务正在使用的机器,又不能影响现有已在跑的服务, 因此不能升级内核, 不能重启机器,显然k8s这条路走不通;linux
还好,这个世界老是提供给咱们多样的选择,除了Kubernetes(k8s) + Docker, 咱们还有mesos;c++
先放上官方网站, 上面有很详细的说明;
http://mesos.apache.org/
简单来讲,Mesos就是用于整个计算中心的操做系统,它统一管理计算中心全部机器的cpu, memory, disk, network等计算资源,按任务所需分配资源,调度任务,支持故障转移等等;docker
上面架构图的简要说明以下:apache
- 各个Agent上报自已的计算资源给Master;
- Master给各个二级调度框架Framework发送resource offer;
- Framework将其上等待调度的task与收到的resource offer做匹配,反馈给Master;
- Master将相应Framework反馈的task和resource offer发送到对应的Agent;
- Agent使用Executor来运行task, 并限定资源使用;
在Mesos上能够运行Spark, Storm, Hadoop, Marathon等多种Framework;json
官方文档:
http://mesos.apache.org/documentation/latest/architecture/;
针对任务隔离这块, Mesos除了支持docker容器技术,还提供了它本身的Mesos Containerizer, 这正是咱们所须要的.其实Mesos Containerizer目前也是利用Linux Cgroup做资源限制, 用Linux namespace做资源隔离.
Mesos Containerizer:
http://mesos.apache.org/documentation/latest/mesos-containerizer/centos
咱们的多任务调度系统须要解决的几个问题
各组件简介:
1.1 主体仍是Mesos master + Mesos agent;
1.2 二级调度框架使用的是Marathon;
1.3 在部署了Mesos agent的机器上同时部署monitor用于实时监控和调整Agent的可用计算资源;
咱们采用的是Mesos 1.4.1版本,用C++11编写,Mesos项目自己很是庞大,依赖库必然也不少,解决这些运行依赖问题首当其冲;
部署原则就是不改变,不污染所部署的机器环境,针对libstdc++和其余一些so, 咱们不会将其安装到例如/usr/local/lib这样的系统目录, 而是在打包时采用动态更改可执行程序的rpath的方法,使其运行时从咱们的安装目录加载相应的so库, 具体做法就是
- 咱们将mesos运行所须要的全部lib文件都集中放在libs目录下;
- 编译出来的mesos可执行文件,使用patchelf来更新rpath路径,指向咱们自已的libs目录便可;
- patchelf这个工具能够在不影响可执行文件运行的前提下,修改其elf文件结构中的某些属性值,具体可参考:https://nixos.org/patchelf.html
这样部署完,Mesos agent只是一个单独的目录,卸载只须要停掉进程,删除目录就好;
说一下编译过程,虽然官网上已经介绍得比较详细,但在编译过程当中仍是会遇到一些问题:
自行开发了Monitor程序,和Agent一同部署在业务机器上,周期性的监测机器上可用资源和Agent自己所用资源;
Mesos为咱们提供了动态资源保留这个超实用的功能,能够限制Agent当前针对某个Role可使用的计算资源:
Monitor的监控评估结果就是当前Agent可使用的计算资源;
本想着到这里这个问题就结束了,测试时发现Agent并不能在线实时调整这个动态资源保留,须要在配置文件时更新好当前可以使用的动态资源,而后重启Agent;
重启Agent是咱们不能忍受的,所以咱们修改了源码,经过http接口在线调整动态资源保留, 这部分其实不难,mesos http接口定义十分清晰,依葫芦画瓢就行了.
task的部署目前咱们采用Marathon,上手简单,功可以用; 若是须要更灵活的调整策略,可能就须要本身开采框架或基于某一框架二次开发了;
task实际上是有重要,紧急之分,占用资源也不尽相同。对于重要紧急任务,为了保障任务的更好运行,咱们会利用Mesos attribute,在调度任务时让特定任务只跑在具备特定attributes的agent上, 这就须要为每一个mesos agent设置相应的attributes;
遇到了一样的问题,mesos不能在线动态调整attributes :-(, 其实也比较简单,稍微梳理下mesos源码结构,改起来不难;
还有一个问题,attributes是动态调整的,agent若是重启了怎么办?咱们为此部署了etcd集群来管理,每台agent都是etcd上的一个node, 经过etcd提供的http接口更新其attribrtes, agent会周期性的从etcd上同步;同时各agent 上的attributes信息也很容易从etcd上得到;
直接操做etcd, 删除某台agent上的attribute, 那依赖于这种attribute部署的任务会自动别调度走,再也不在这台agent上运行;
task隔离问题,针对cpu和memory,mesos都是经过cgroup来完成,对于cpu的限制, 咱们使用cfs方式,前提是须要判断当前kernel是否支持.对于disk的限制,目前mesos使用的是du命令周期性检测的方式;
对于cpu的限制,mesos有两种方式:
- cpu shared方式:这种方式对 cpu 没有严格限制,机器上的任何task均可以访问机器上全部cpu资源,好比你限定的cpu使用资源是2, 这种方式可能使用到4,6或更高;
- cpu CFS方式: 至关于配置了独占 cpu, 好比cpu配置为1,那么这个任务的 cpu 使用率就不会超过 100%, 至关于设定了一个hard limit;
在咱们的大部分环境中,受限于kernel版本,mount namespace不支持,所以咱们采用rootfs + chroot的方式来做简单的资源隔离;
咱们定制了若干版本的rootfs, 任务打包就是将任务自己的依赖和相应rootfs结合的过程, 打包好能够放到s3等存储上,供marathon部署任务时调用。
这里咱们结合marathon的一个任务部署的json配置来说一下, 先看一个这个配置, 我将说明直接写在里面
关于chroot, 你们能够参考下面的网址内容,简单讲就是构造了一个沙箱,和已有的文件系统隔离;
https://www.ibm.com/developerworks/cn/linux/l-cn-chroot/
机器自己的基础监控通常公司还有本身的统一监控, 这部分不用投入精力;
咱们主要关注task的调度运行状况,目前的方案是mesos-exporter和mesos-agent(或mesos-master)一块儿部署,上报监控信息到prometheus,使用grafana来展现;
mesos自己为咱们提供了很丰富的http api来获取当前集群的属性,状态,Framework状况,task的运行状态等等,结合这些咱们本身来做监控其实也不是难事,能够参考这里:
http://mesos.apache.org/documentation/latest/operator-http-api
打包task没有实现自动化, 咱们虽然定制了若干种不一样的rootfs, 好比c++11环境的, python环境的, java环境的等等, 可是想要运行的task依赖千差万别, 如今都是结合rootfs和业务的程序,手动合成专用的rootfs, 基本上每一个task都要走这个手动流程,烦锁,耗时,容易出错;
目前只引用了marathon一种调度框架,适用于长期运行的task, 对于须要定时运行的task目前没法支持;
到此咱们利用Mesos构建的多任务调度系统就简单介绍完成,其中还有不少不完善的地方,有兴趣的同窗能够一块儿讨论,互相学习~~~