实录分享 | Mesos PMC带你回顾Mesos 2016

数人云上海&深圳两地“容器之Mesos/K8S/Swarm三国演义”的嘉宾精彩实录第五弹!Mesos Committer登场,为我们带来Mesos 2016年新功能的全面解读及未来展望。Mesos爱好者不容错过哦^_^

黄浩松,Apache Mesos PMC

目前就职于Shopee(东南亚社交电商平台),负责公司自动化运维平台建设,业余时间长期在Apache Hadoop / Apache HBase / Tensorflow 打酱油。

今天想跟大家介绍一下Mesos,以及Mesos社区过去一年在容器化方面做的一些工作。我本人是一名在Shopee负责基础设施工作的工程师, Shopee主要做东南亚的电商市场。平常除了上班之外,下班和周末的空余时间我经常会在社区打酱油,是Apache Mesos Committer,对Mesos比较熟悉。大家可以通过下面的链接加入Mesos的Slack,遇到任何问题都可以在Slack上发问。更正式的方式是通过Mesos的邮件列表,上面的user@mesos.apache.org是专门给用户的,下面的dev@mesos.apache.org是给开发者的,如果你确定发现了Mesos的BUG,可以直接把遇到的错误还有错误日志贴到Mesos JIRA上。

What is Mesos?

今天照顾一下没有了解到Mesos的同学,讲一下什么是Mesos,以及当初为什么公司看各种容器编排框架的时候选择了Mesos,后面最主要讲今年社区做Mesos容器化方面做的两个比较大的东西,一个是Unified Containerizer,另一个是对POD的支持。

Mesos的目标是想做一个数据中心的Kernel,类似于主流服务器操作系统的Kernel是Linux一样。从一台服务器的角度来说,一个Linux kernel资源抽象,单台机器的CPU,单台机器有多少内存,对Mesos来说因为是一个数据中心的操作系统,就上面的应用提供一个集群这样视角的资源,看到是这一批机器有多少空余的CPU,有多少空余的memory。如果你是针对单台机器编程的话,在Linux Kernel里面看到的是那种POSIX的API,比如进程、线程、包括系统标用调类的,如果用Mesos的话,它会提供对应的API,包括Task,Resource等相关的抽象接口,把整个集群的资源抽象起来。在资源隔离方面,Linux Kernel用的是不同的用户,还有不同的进程空间。但是Mesos主要是用容器,用CGroup、Namespace及其他东西来隔离不同用户之间的应用。

一个典型的Mesos集群是这样的,公司把Spark和Kafka跑在了同一个Mesos集群里面,一般一个Mesos集群里面有多台Master,Master是Meoss的控制节点,然后在每一台机器上都装一个Mesos Agent,Mesos Agent具体去启动用户的任务,Master之间的选举包括HA通过Zookeeper来做。在Mesos上面跑着各种各样的Framework ,包括Spark、Kafka。Kubernetes或者Marathon都可以跑在Mesos上,也支持Cassandra这样有状态的分布式的数据库跑在Mesos上面。通过把不同种类型的Framework混布在一起,给不同的Framework分配不同的角色和Quota,避免不同Framework互相的资源抢占。过去一年社区还做了包括Quota,Weights,现在还在做的多层资源调度,让离线还有实时应用更好的充分利用整个计算集群的资源。

Linux编程的时候接触到的都是进程、线程等概念,Mesos则将进程抽象为Framework、Resource、Task还有Excutor这几个概念。举个典型的例子,假设用户要启动一个Docker的镜像,上层的Framework,即Marathon会发一个请求,Mesos会定期的把Resource Offer发到Framework ,Marathon收到了用户的任务请求之后就会找出匹配的Offer,将用户的那些要启动的镜像等一系列的参数发给Mesos Master,Mesos Master收到之后直接会到对应的Mesos Agent上去启动任务,变成一个Task。

Mesos本身有不同的抽象级别,最基础的级别是API。C++、Java、Python、Golang都有对应的API库,如果你使用的语言找不到对应的库的话,整个Mesos API都是基于HTTP,实现对应的库也非常简单。像使用SDK,API开发新的Framewor都是需要一些时间的,大概耗费几周或者1、2个月的时间。还有一种更简单使用Meos的方式,直接用JSON等形式的DSL来定义好应用,这种只需要几分钟就可以搞定。像Marathon用的就是JSON形式的DSL,Aurora则是使用形似Python的DSL。

Why choose Mesos?

为什么当初Shopee在那么多Framework中选择了Mesos,有三个重要原因:Mesos经过这么多年已经非常稳定,其次它的Scalability非常好,另外对于公司有各种奇奇怪怪的需求,可以非常容易在它上面做扩展和可定制化。

Mesos最开始是2009年Ben读博士时候做的一个项目,在2010年5月,他们几个人去Twitter介绍了一下它,Twitter觉得这个很像谷歌的Borg,非常好,就直接把他们招进来继续做,9月的时候发布了Mesos的第一个版本,在2010年12月进入了Apache的孵化器,在第三年成为了Apache的顶级项目,现在快1.2的版本了,这些年下来是相当稳定的。有一个完整的Powered By Mesos的列表,现在上面有100多家公司,还有更多的公司因为不知道有那个列表的存在,没有加进去。

像Apple、Twitter、Uber都是在生成环境非常广泛地使用Mesos,在社区也有非常多的贡献。还有像Paypal,2 Sigma这样的金融公司,以及Verizon的这种电信运营商。Mesos在国内也有非常多的用户,像小米、知乎、豆瓣和国内的三大运营商,特别是豆瓣在很早的时候就开始使用Mesos,他们在Mesos上面开发了很多框架,并且开源出来,还有微博、唯品会、携程等。Twitter据我所知,内部有3万多台机器都已经跑在了Mesos里,Apple可能有更多,最开始他们把Siri即苹果的语音助手放在Mesos,后来感觉效果不错,就把更多的服务迁移到了Mesos上面。

Verzion使用 Mesos也很多,他们演示了在60秒内启动了5万个Container,所有Container在60秒内都全部启动完成了。为什么Mesos可以扩展到这么多台机器,最关键的一点是Master是无状态的,设计得非常简单。否则像其他的一些容器编排调度的框架把状态存在etcd或者consul里面,当机器越来越多时,存储那些状态的一些外部存储,比如etcd会最先成为瓶颈。Mesos master只用Zookeeper做leader选举以及HA,并不会有其他而外的状态信息。本身Mesos只是想做一个数据中心的Kernel,就像Linux的Kernel一样本身非常小。Mesos只专注于资源的分配和隔离,以及任务管理。

Mesos每发一个版本之前都会做回归测试,有时候一个不经意的改动,看上去感觉只是拷贝了某一个的protobuf Message,但是实际上扩展到几万台机器时,这个改动都可能造成性能的下降。所以每次发布之前,社区都会进行非常严格各方面的测试。Shopee目前机器是几千台,将来可能也会像Twitter或者是Apple那样把Mesos用在几万台机器上,所以,那时候就选择了Mesos。而且Mesos参与的公司比较多,有IBM、Microsoft、Uber、Apple等公司,整个社区都可以一起帮忙测试和改进Mesos,让Mesos非常稳定。新版本发布的时候,如果有任何兼容性的问题任何人都可以直接一票拒绝。

另外对于Shopee而言,有内部的服务器资产管理系统、自己内部的验证、以及一些特殊的硬件设备,调研Mesos的时候就发现Mesos扩展性很好,可以在上面继续实现公司各种需求。每一个公司都有公司内部的不同的情况,Mesos只专注做资源调度和隔离,而其他部分则倾向于对接开放的标准,比如在网络方面支持CNI,在存储方面支持Docker Volume,而不是强制让用户使用某种网络模型或者某种存储。事实上也不存在一个容器编排框架,可以满足所有不同公司不同用户的需求,所以,Mesos会尽量倾向于把所有的东西都做成模块,把核心的东西都做得比较简单。

跑在Mesos上的Framework有很多种类型,有一些是跑web服务的,这种一般需要一直跑,本身没有状态,会很容易的水平扩展;有一些是定时跑的,而且定时的服务之间有相互的依赖,比方一定要A完成之后才能做B;另外一些数据库的,本地每一个Container之间不能随便启动,之间有相互的依赖。就长时间跑的servies来说,Mesos上有很多不同种类的Framework ,都是不同公司实现的,像Mesosphere的Marathon,还有数人云也实现了一个Swan。你可以在Mesos上面跑Spark、Flink、Storm这种计算的任务,Alluxio、Ceph、HyperTable这种数据库及文件系统。当然还有其他各种类型,比如Tensorflow on Mesos的机器学习Framework,还有Vamp的一个DevOps框架,可以做自动的扩容和缩容,根据整体的服务的情况,把container的instance scale in和scale out。更多的框架,可以在Mesos的官网的文档里找到。

在Service Discovery方面,Mesos提供了很多的选项,包括基于DNS的,我们公司做的基于Zookeeper的,其他公司也会有各种不同方案。traefik比较有意思,一个域名过来,域名下面不同的路径,它会对应地把这个路径转发到不同的后端Container,可以看到/api这个路径就转到这一个instance, /web的话就转到另一个instance。它可以监听Mesos或者Marathon里面新起容器的变化,自动动态更新。为什么需要动态更新呢,假设一种场景,这台机器挂掉了,Marathon会在其他机器上新起Container,而这个Container因为被调度到不同机器,机器的IP或者端口已经变化了,如果直接使用Nnginx或者Apache的话,没办法感知到这种的变化,像用这个traefik就可以感受到其他的变化,重新生成一个配置文件并加载。

七层一定要有HTTP或者HTTPS协议,像linkerd也是类似的,但四层的可以使用TCP或者UDP。它监听Mesos或者Marathon的变化,把服务的IP自动更新到配置。也有使用Mesos-DNS的,但是用DNS的时候有一个问题,就是DNS本身有一个TTL,当服务挂或者是迁移的时候有一定的downtime,所以Shopee大部分东西还是基于Zookeeper做服务发现,并没有用DNS的方式。

Marathon也有自己的LoadBalancer,基于HAProxy,同样是是监听自己API里面容器状态的变化。除了Service Discovery之外,Mesos大部分已经模块化,可以按照它的接口实现包括验证、采集、拉取资源,以及增加一些Hook,比如在Docker启动前做什么、销毁后做什么,包括Master Contender,如果公司内部不喜欢用Zookeeper的话,可以用etcd做Mesos的HA和Leader选举。以上主要为大家介绍了Mesos,以及为什么Shopee那时选用了Mesos。

Mesos containerization in last year

接下来讲一下社区在过去一年容器化方面做的工作,第一部分主要是加入了不同镜像的支持,包括Docker,appc和oci。之前如果要在Mesos里面跑Docker,一定要装一个Docker Daemon,所有启动Docker的任务都是把它delegate到Docker Daemon,如果没有Docker Daemon,机器就跑不了Docker的任务。现在Mesos可以直接去Docker registry把镜像一层一层拉下来直接解压并启动任务,所以,就算机器上没有装Docker Daemon也没有问题。

在网络方面Mesos去年支持了cni,cni是其他容器的编排平台都支持的网络协议的通用接口。通过Mesos支持cni,就可以把Mesos和像Maclan及其他一些Vlan的方式结合起来使用。

然后也支持了Docker volume ,一些公司想在Mesos里面用企业存储,比如EMC的ScaleIO,Mesos通过支持Docker volume的这种方式来对接了这些不同种类的分布式文件系统。

在安全方面Mesos也做了很多,包括Linux capabilities、User namespace, seccomp。当任务在容器里面跑的时候,在容器里面不可以重启服务器,不可以修改网络配置和宿主机上的一些文件。通过Linux capabilities还有user namespace,做到在容器里面虽然是root,但是宿主机的角度看来是一个普通的用户,这样在容器里面跑得任务就会比较安全,没有办法做一些宿主机root用户能做的事,比如重启机器这种危险的事。

还有一个是POD,就是把一组的任务跑在不同container里面,这几个container有相同的namespace。最主要的是可以实现DEBUG、Log采集这样的功能。Log采集要求一定可以访问到相同的文件系统。Mesos最近还在做了一个CLI,可以从本地要远程连接整个集群的某一个Container,或者直接登录进去进去里面调试或者是执行一些命令。以上这些改动,方便大家更好的使用Mesos。

What is Unified Containerizer?

关于Unified Containerizer,之前讲到支持Docker 、Appc、OCI三种不同的镜像格式、支持三种不同镜像格式的Containerizer就叫Unified Containerizer。Mesos里面Unified Containerizer是处于Mesos Agent和Task之间中间的一个组件。它会接收agent的命令,把任务启动起来,并且把任务放到Container里面,而不是说直接在宿主机的环境跑,它会做包括创建,销毁,检测等Contaienr的管理工作,比如Container挂掉了,或者把健康检查之类的一些状态把它汇报给agent。

Unified Containerizer里面只分三个东西, Launcher、Isolators和Provisioner。Launcher主要是启动容器和杀死容器,现在Mesos支持Mac,Linux,Windows,不同的操作系统就是用不同的Launcher。机器上跑的大部分的容器隔离的功能都是在Isolator完成的,包括Cgroup不同的subsystem,CPU、memory都是对应的一个一个的Isolator。磁盘控制容器只能用多少的磁盘空间,是通过Disk下面的几个Isolators来管,包括一些GPU的Isolators,这些都是模块化的,如果不想使用的话,参数的时候不传进去,就不会加载进来。Provisioner是做镜像管理,镜像格式都是在Provisioner这里把镜像拉取下来解压,一层层地解压到机器上。

过去一年Mesos另外一个比较大的特性是支持POD,如果有POD的使用要求可以把Mesos升级到1.1。Mesos的POD还有其他一些方面的特点,可以支持任意层数的嵌套,最大可以嵌到32层的Container,也可以动态的创建和销毁这些嵌套的Container。大家可以看到原有的Container又启动新的嵌套container,通过这种方式,这几个嵌套container拥有同样的网络namespace,最主要的作用比如debug,Nginx出问题了,可以通过Nested Container直接远程到container里面debug。一些公司想把他们的log收集工具集成进来,可以在这里面起一个额外的container来采集log。

(此处是演示)启动Mesos的集群,可以看到POD很简单,就是一个生产者和消费者,消费者不停的往里面写数据,一直把它打出来,定义path外面有一个宿主,启动这个POD,等tasks状态变成running ,可以看到它在输出,这个是consumer的log,生产者的信息也会在把那个打出来,两个因为share相同的namespace之后才可能这样互相通信。

What's the next?

接下来Mesos要做的事情:

  • 把Mesos CLI的工具改善,之前Mesos Container无法远程连上进行调试,大家在下个月1.2发布后就可以看到。
  • 多层次的资源调度,这是Mesos之前说过的改进,避免实时还有离线的任务之间相互的资源抢占,让不同种类型的任务可以混布在一起。
  • 支持更多类型的Cgroups subsystem,把之前漏掉的但是不那么迫切的几个Cgroup subsystem补齐,包括blkio和cpuset等等。

今天就到这里,谢谢大家。