利用Mesos构建多任务调度系统

背景
  • 公司内部的云平台为各个业务线提供了大量的实体机和虚拟机来运行业务的服务,经过统计发现,这些分配给业务的机器cpu, memory等资源利用并不充分;
  • 如果能够充分利用这些机器上的空闲资源同时又能保证业务服务的正常运行,将会节省不少的机器资源;
选型
  • 一提到多任务运行和调度,大部分人可能首先都会想到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这条路走不通;
  • 还好,这个世界总是提供给我们多样的选择,除了Kubernetes(k8s) + Docker, 我们还有mesos;
Mesos简介
  • 先放上官方网站, 上面有很详细的说明;
  • 简单来说,Mesos就是用于整个计算中心的操作系统,它统一管理计算中心所有机器的cpu, memory, disk, network等计算资源,按任务所需分配资源,调度任务,支持故障转移等等;
  • Mesos最大特点是两级资源调度, 如下图:
m2.png
  • 上面架构图的简要说明如下:
    1. 各个Agent上报自已的计算资源给Master;
    2. Master给各个二级调度框架Framework发送resource offer;
    3. Framework将其上等待调度的task与收到的resource offer作匹配,反馈给Master;
    4. Master将相应Framework反馈的taskresource offer发送到对应的Agent;
    5. Agent使用Executor来运行task, 并限定资源使用;
  • 在Mesos上可以运行Spark, Storm, Hadoop, Marathon等多种Framework;
  • Mesos系统架构:http://mesos.apache.org/documentation/latest/architecture/;
  • 针对任务隔离这块, Mesos除了支持docker容器技术,还提供了它自己的Mesos Containerizer, 这正是我们所需要的.其实Mesos Containerizer目前也是利用Linux Cgroup作资源限制, 用Linux namespace作资源隔离.
我们的多任务调度任务需要解决的几个问题
  • Mesos agent在业务机器上需要非侵入式地部署,不能污染所部署的机器的环境;
  • 实时监控和调整Mesos Agent所能使用的计算资源;
  • Task的快速部署和资源隔离;
  • 集群整体运行情况的监控;
多任务调度系统总体架构
  • 架构设计图:
mesos多任务调度.png
  1. 各组件简介:
    1.1 主体还是Mesos master + Mesos agent;
    1.2 二级调度框架使用的是Marathon;
    1.3 在部署了Mesos agent的机器上同时部署monitor用于实时监控和调整Agent的j可用计算资源;
  2. 系统运行流程,按上图中标号顺序
    2.1 Monitor实时监控组件收集所在机器上的可用资源;
    2.2 Monitor根据所在机器上的可用资源动态调整agent的保留资源;
    2.3 Agent动态实时的将自已的保留资源上报到Mesos master;
    2.4 Mesos Master在resource offer发到Marathon;
    2.5 Marathon根据收到的resource offer和需要运行的task作资源分配, 将分配结果反馈给Mesos Master;
    2.6 Mesos Mastertask分配到具体的Agent上执行;
解决问题 1: Mesos agent在业务机器上非侵入式部署
  • 我们采用的是Mesos 1.4.1版本,用C++11编写,Mesos项目本身非常庞大,依赖库必然也很多,解决这些运行依赖问题首当其冲;
  • 部署原则就是不改变,不污染所部署的机器环境,针对libstdc++和其他一些so, 我们不会将其安装到例如/usr/local/lib这样的系统目录, 而是在打包时采用动态更改可执行程序的rpath的方法,使其运行时从我们的安装目录加载相应的so库, 具体作法就是
    1. 我们将mesos运行所需要的所有lib文件都集中放在libs目录下;
    2. 编译出来的mesos可执行文件,使用patchelf来更新rpath路径,指向我们自已的libs目录即可;
    3. patchelf这个工具可以在不影响可执行文件运行的前提下,修改其elf文件结构中的某些属性值,具体可参考:https://nixos.org/patchelf.html
  • 这样部署完,Mesos agent只是一个单独的目录,卸载只需要停掉进程,删除目录就好;
  • 说一下编译过程,虽然官网上已经介绍得比较详细,但在编译过程中还是会遇到一些问题:
    1. 官网编译步骤: 请参考 http://mesos.apache.org/documentation/latest/building/;
    2. gcc官方要求是 4.8.1+, 我用了 gcc 5.4, 自己在 centos 6.2,linux 2.6.32上重新编译的;
    3. 编译默认是编译java语言的binding的, 但在 编译 "Build and attach javadoc"时缺 protobuffer的jar包,没编译过, 解决方案:修改 src/java/mesos.pom.in,先找到 ``, 在它下面的 <configuration>下添加 <skip>true</skip>,这样不会编译这个 javdoc, 但不影响 java binding的使用
解决问题 2:实时监控和调整Agent所能使用的计算资源
  • 自行开发了Monitor程序,和Agent一同部署在业务机器上,周期性的监测机器上可用资源和Agent本身所用资源;
  • Mesos为我们提供了动态资源保留这个超实用的功能,可以限制Agent当前针对某个Role可以使用的计算资源:
RESERVE_RESOURCES HTTP Request (JSON):
POST /api/v1  HTTP/1.1
Host: masterhost:5050
Content-Type: application/json
Accept: application/json
{
  "type": "RESERVE_RESOURCES",
  "reserve_resources": {
    "agent_id": {
      "value": "1557de7d-547c-48db-b5d3-6bef9c9640ef-S0"
    },
    "resources": [
      {
        "type": "SCALAR",
        "name": "cpus",
        "reservation": {
          "principal": "my-principal"
        },
        "role": "role",
        "scalar": {
          "value": 1.0
        }
      }
    ]
  }
}

RESERVE_RESOURCES HTTP Response:
HTTP/1.1 202 Accepted
  • Monitor的监控评估结果就是当前Agent可以使用的计算资源;
  • 本想着到这里这个问题就结束了,测试时发现Agent并不能在线实时调整这个动态资源保留,需要在配置文件时更新好当前能够使用的动态资源,然后重启Agent;
  • 重启Agent是我们不能忍受的,因此我们修改了源码,通过http接口在线调整动态资源保留, 这部分其实不难,mesos http接口定义十分清晰,依葫芦画瓢就好了.
解决问题 3:Task的快速部署和资源隔离
  • task的部署目前我们采用Marathon,上手简单,功能够用; 如果需要更灵活的调整策略,可能就需要自己开采框架或基于某一框架二次开发了;
  • task其实是有重要,紧急之分,占用资源也不尽相同。对于重要紧急任务,为了保障任务的更好运行,我们会利用Mesos attribute,在调度任务时让特定任务只跑在具有特定attributesagent上, 这就需要为每个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有两种方式:
    1. cpu shared方式:这种方式对 cpu 没有严格限制,机器上的任何task都可以访问机器上所有cpu资源,比如你限定的cpu使用资源是2, 这种方式可能使用到4,6或更高;
    2. cpu CFS方式: 相当于配置了独占 cpu, 比如cpu配置为1,那么这个任务的 cpu 使用率就不会超过 100%, 相当于设定了一个hard limit;
  • 在我们的大部分环境中,受限于kernel版本,mount namespace不支持,因此我们采用rootfs + chroot的方式来作简单的资源隔离;
  • 我们定制了若干版本的rootfs, 任务打包就是将任务本身的依赖和相应rootfs结合的过程, 打包好可以放到s3等存储上,供marathon部署任务时调用。
  • 这里我们结合marathon的一个任务部署的json配置来讲一下, 先看一个这个配置, 我将说明直接写在里面
{
  "id": "/test_task", //在marathon上的任务id
  "fetch": [
    {
      //每个任务都会打包成一个rootfs, mesos agent在运行时会从这个uri下载,然后自动解压缩
      "uri": "http://xxx.xxx.xxx:8080/rootfs.tar.gz", 
      "extract": true,
      "executable": false,
      "cache": false
    }
  ]
  //上面下载的rootfs.tar.gz被解压成rootfs目录,执行任务时先chroot到此目录, 然后运行真正的/test这个任务
  "cmd": "chroot ./rootfs /bin/bash -c \"/test > /dev/null \"", 
  "cpus": 2, //限定的cpu资源
  "mem": 1024, //限定的memory资源
  "disk": 2048, //限定的dist资源
  "instances": 25, //当前任务一共运行多少个实例
  "constraints": [  //限定当前任务只运行在有 "job=test_task"属性的agent上
    [
      "job",
      "CLUSTER",
      "test_task"
    ]
  ],
  "acceptedResourceRoles": [
    "test-role"
  ],
  "portDefinitions": [
    {
      "port": 10005,
      "name": "default",
      "protocol": "tcp"
    }
  ],
  "user": "root"
}
解决问题 4:集群整体运行情况的监控
  • 机器本身的基础监控一般公司还有自己的统一监控, 这部分不用投入精力;
  • 我们主要关注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构建的多任务调度系统就简单介绍完成,其中还有很多不完善的地方,有兴趣的同学可以一起讨论,互相学习~~~
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,185评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,652评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,524评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,339评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,387评论 6 391
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,287评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,130评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,985评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,420评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,617评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,779评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,477评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,088评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,716评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,857评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,876评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,700评论 2 354

推荐阅读更多精彩内容