实录分享 | 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 等等。


今天就到这里,谢谢大家。
已邀请:

要回复问题请先登录注册