Mesos 0.23.0 在 0.22.0 发布 4 个月后于 2015.07.29 号发布,当然, 这么长的开发周期也带来了很多的新特性,包括一些尚不建议在生产环境中使用的实验性特性。

release note 中列举了以下新特性:

  • Per-container network isolation
  • SSL 支持
  • Oversubscription
  • Persistent volumes
  • Dynamic reservations
  • Fetcher caching

都是几个值得一提的特性,官方 release note 也对几个特性都有简单的介绍。

但是,除了 Per-container network isolation 外,其它几个特性都被标记为实验性质, 会在后续版本中逐渐稳定。

Per-container network isolation

Mesos 现在可以对每个容器的网络状况进行监控和限制,包括网络端口和带宽的使用情况, 可以通过 slave 的 /monitor/statistics.json 地址进行查看。

Per-container network isolation 在默认编译配置中并没有开启,用户需要 configure mesos 时指定 --with-network-isolator,所以,要开启该特性,用户需要自行编译打包。

注意:支持该特性,需要 Linux kernel 3.6+,并且还需要包含几个在 Linux kernel 3.15 中才被合并的 patches, 所以,如果有 Linux kernel 3.15 最好,否则需要确保 3.6+ kernel 打上了上面的 patch,或者自己 backport,build kernel。

另外,per-container network isolator 只在 mesos containerizer 中使用,所以, 使用 docker 作为 containerizer 并不能使用该特性。

在编译时开启了 Per-container network isolator 的 mesos 在启动时可以指定 --isolation="network/port_mapping",当然,--isolation 还可以指定其它值,以逗号分隔,例如:--isolation="cgroups/cpu,cgroups/mem,network/port_mapping"

在开启了 network/port_mapping 的 slave 上,还可以进行进一步的配置。

端口分配隔离

开启端口隔离之后,mesos 会使用 network namespaces 隔离各个容器的网络端口段, 但是 IP 依然共享主机的 IP。各个容器的网络端口段不会重叠, 如果容器使用了不属于自己端口段的端口,包将会被丢弃。

在启动 mesos-slave 时,首先需要指定 --isolation="network/port_mapping", 然后通过:

  • --resources
  • --ephemeral_ports_per_container 来指定端口的分配。

首先,需要了解一下从 mesos 角度看,主机端口的几种类型:

  • emphemeral 端口
  • mesos non-ephemeral

emphemeral 端口

emphemeral 端口,简单说就是当应用需要使用 socket 建立一个链接时,OS 随机从一个端口段里分配给应用的一个端口。这个端口段里的就是 emphemeral 端口。

Linux 上可以使用 sysctl net.ipv4.ip_local_port_range 查看 emphemeral 端口段,例如:

# net.ipv4.ip_local_port_range = 32768    61000

[32768,61000] 是 emphemeral 端口默认段,所以 mesos 以前版本中一直使用的端口段是 [31000,32000],这也避免了 mesos 分配的端口和 OS 分配给其他应用的端口冲突。

当开启网络隔离后,mesos 会从 emphemeral 端口段中为每个容器预留一段端口供任务使用, 同样,为了不和系统的 emphemeral 端口冲突,所以 mesos 只能使用 net.ipv4.ip_local_port_range 意外的端口,也就是 32767 以内,同时还有排除 well known 的服务端口,1024 以内的端口。

根据现在的 mesos 实现,端口范围 [31000,32000] 作为 non-emphemeral 端口,所以 mesos 给每个任务的 emphemeral 端口就是 [32001,32767],所以范围太小。 我们可以通过修改系统的 /etc/sysctl.conf 来修改 net.ipv4.ip_local_port_range 的范围,使系统的 emphemeral 端口段缩小,更多的留给 mesos 使用。

下面是 mesos 文档中建议的配置:

  • net.ipv4.ip_local_port_range = 57345 61000
  • --resources=ports:[31000-32000];ephemeral_ports:[32768-57344]
  • --ephemeral_ports_per_container=512

mesos non-emphemeral 端口

如前所述,mesos 使用 [31000,32000] 作为 non-emphemeral 端口,可以交给 framework 指定分配,而非随机分配,当然,更多的时候,framework 都是使用 offer 中最小的 non-emphemeral 端口,例如:第一个任务使用 31000,下一次,mesos 发送的 offer 中的资源端口范围则为 [310001,32000],而不会被分割为几段。

带宽限制

使用带宽限制可以限制容器网络上行的速率,但是并不能限制下行的速率。 可以使用以下两个参数限制和隔离:

  • --egress_rate_limit_per_container=100MB
  • --egress_unique_flow_per_container

这里 有比较详细的介绍。

SSL

Mesos 0.23.0 加入了实验性质的 SSL 支持,可以将 Mesos master, slave, framework 之间的通信通过 SSL 加密。

由于是实验性质的特性,而且 SSL 的引入会对性能带来一定影响,所以默认并没有开启, 需要在编译时开启。详细方法可以参考源码中的 docs/mesos-ssl.md

Oversubscription

Mesos 以前支持两种资源:

  • reserved resource
  • shared resource

reserved resource 是一种为某种 role 静态预留资源的方式,在启动 slave 的时候配置,一旦配置,在 slave 运行期间都不能改变,所以不够灵活。

Oversubscription 引入了第三种资源:revocable resource,只要任务的任何一类资源使用了 revocable resource,都表示这个任务可以被杀死。例如:一个任务只使用了 revocable 的 cpu 资源,而其它资源使用的是非 revocable resource。

引入 revocable resource 后,oversubscription 如下图所示:

oversubscription overview

首先在 mesos-slave 中引入了 Resource EstimatorQoS Controller, 前者用来估计 slave 中可用的 revocable resource,而 Qos Controller 则用来保证临时任务不要影响其它任务,如果影响,则会要求杀掉临时任务。

所以,为了保证不支持的 revocable resource 的框架的任务不被误杀,mesos 要求框架在注册时必须显示声明支持 REVOCABLE_RESOURCES;然后,mesos 才会将 revocable resource 在 offer 中发送给该框架。

目前 mesos 中实现了两个 Resource Estimator

  • noop, 不发送任何 revocable resource
  • fixed, 发送固定配置的 revocable resource

而 QoS Controller 则需要自行实现,更多详细内容可以参考 官方文档

Persistent volumes

Persistent volumes 能够为任务提供持久化存储,这些存储被分配在预留磁盘上,挂在 sandbox 之外,所以不会被 garbage collector 回收。

为了避免 persistent volumes 被误操作,只能通过 operators 和 frameworks 进行创建和删除操作。

注意: persistent volumes 是一个实验性质的特性,更多参考 官方文档

Dynamic reservations

Dynamic reservations 也是一个实验性质的特性,支持 slave 指定动态预留资源, 避免静态资源一旦指定,在整个 slave 运行周期都不能修改,一旦修改,必须重启 slave。

Dynamic reservations 提供了一种方法给管理员和 framework,管理员可以通过 HTTP API 来 reserve/unreserve 资源(从 0.25.0 开始),而 framework 则通过相应的 message 来 reserve/unreserve 资源。

当 framework 收到 shared offer 的时候,framework 可以发送消息要求预留资源, 成功后,mesos 将会更新这个 offer 中的资源信息,从而保证不再将 reserved resource 发送给其它 framework。

详细可以参考官方文档

Fetcher caching

Mesos 在启动 task 的时候,可以指定使用的 executor,或者一些需要的其它资源,例如: 使用 mesos-docker executor 启动任务(非原生 docker 支持),启动 storm 任务时下载 storm 包。

如果这些资源存放在某个内部服务器上,那么 mesos 就会从相应的地址下载。而 fetcher caching 机制就是为了避免每次都去下载,而只有在首次启动任务时下载,后续启动则从本地 cache 中复制即可。

这种方法和将资源部署到每个 slave 结点,然后指定地址为本地地址类似,但是更胜一筹, 简化了对结点的部署。

使用 fetcher caching 特性需要在 slave 上配置两个参数:

  • --fetcher_cache_size,指定 cache 目录大小,最好是比可用的空间小
  • --fetcher_cache_dir,指定 cache 目录

更多详细信息参考官方文档