☰
Apache Mesos 0.28.0 特性深度解析:net_cls 网络隔离、统一容器化与 v1 Executor HTTP API
2026/10/14 5:25:09 网站建设 项目流程
  • 云原生

【免费下载链接】mesos

Apache Mesos

项目地址:https://gitcode.com/gh_mirrors/mesos2/mesos
点击查看免费下载

Apache Mesos 0.28.0 是 Mesos 发展历程中承上启下的一个重要版本:它在 Linux cgroups 网络隔离、标量资源精度、动态预留资源元数据、统一容器镜像支持以及 v1 Executor HTTP API 五个方向同时迈出了关键一步,为后续 1.x 时代的 Unified Containerizer 与原生 HTTP API 奠定了基石。本文以 官方 0.28.0 发布公告 为主线,结合仓库内对应的官方文档、agent 参数定义 与 isolaor 源码,逐项还原每个特性的配置方法、工作原理、API 变化与升级路径,帮助读者在今天的 Mesos 代码库中理解这些能力的来源与用法。

版本概览:0.28.0 带来了什么

根据发布公告,0.28.0 的核心特性包括六项:

特性JIRA 编号类型
cgroups/net_cls 网络隔离器MESOS-4343新功能
标量资源三位小数精度MESOS-4687行为变更
预留资源支持 LabelsMESOS-4479新功能
Mesos containerizer 容器镜像支持MESOS-2840实验性
v1 Executor HTTP APIMESOS-4793实验性
Docker Remote API v1.21 服务发现MESOS-4370兼容性改进

此外还有一批 API 调整(/state端点行为、TASK_KILLING状态、v1 Scheduler API 字段移除、ACL 对象变更、HTTP Scheduler stream ID、state.json网络地址校验等),并由 44 位贡献者共同完成。

特性一:cgroups/net_cls 网络隔离器

背景与原理

cgroups/net_clsisolator 允许运维人员在 Mesos 集群内为容器提供网络性能隔离与网络分段。其原理是利用 Linux cgroups 的net_cls子系统:内核会为从容器发出的数据包打上一个 32 位的标签(handle),内核模块如qdisc(流量整形)与net-filter(防火墙)可以据此执行运维人员指定的网络策略,策略通常通过tc和iptables等用户态工具下发。

32 位 handle 的形式为0xAAAABBBB,由 16 位 primary handle(0xAAAA)与 16 位 secondary handle(0xBBBB)组成,写入到该 cgroup 下的net_cls.classid文件。

启用方式

在启动 agent 时,将cgroups/net_cls追加到--isolation标志即可:

$ sudo mesos-agent \ --isolation=cgroups/net_cls,... \ --cgroups_net_cls_primary_handle=0xAAAA

按照 cgroups-net-cls 官方文档,默认情况下 isolator不管理handle,而是假定由运维人员自行分配。只有指定了 16 位 primary handle(形式0xAAAA)的--cgroups_net_cls_primary_handle标志后,isolator 才会为每个容器分配一个 16 位 secondary handle,并把二者组合写入容器对应 cgroup 的net_cls.classid。

源码级的句柄管理机制

在 net_cls.cpp 中,NetClsHandleManager维护了 primary/secondary 句柄的分配状态:

  • alloc(net_cls.cpp#L81-L128):为每个 primary handle 维护一个位图,扫描查找空闲的 secondary handle,默认的 secondary 取值范围是闭区间[1, 0xffff](0不可用)。
  • reserve/free:agent 重启后从net_cls.classid读回已有句柄并标记占用(recoverHandle),容器销毁时释放句柄。
  • isolate:在容器启动的isolate阶段通过cgroups::net_cls::classid()把句柄写入 cgroup 的net_cls.classid文件。
  • status:把分配的 classid 写入ContainerStatus的CgroupInfo.NetCls字段,进而通过 agent 的 /state 端点 暴露给运维人员。

与此对应,agent 还提供--cgroups_net_cls_secondary_handles=0xAAAA,0xBBBB标志来限定可用的 secondary handle 范围(仅在设置了 primary handle 时生效),两个标志的完整参数说明见 flags.cpp#L626-L635。

特性二:标量资源精度升级到三位小数

变更内容

标量资源(如"2.5 CPUs")的内部表示方式发生了改变。0.28.0 开始,Mesos可靠地支持最多三位小数精度的资源(如"2.501 CPUs");超过三位小数的资源会被四舍五入。内部资源运算是基于支持三位小数精度的定点格式(fixed-point)完成的,仅在输入输出时与浮点数互转。

对 Framework 的影响

  • 之前依赖浮点运算做资源加减的 framework,在舍入误差与数值精度上可能观察到差异;
  • 更细粒度的预留(如"0.0001" CPUs)不再受支持。升级文档 upgrades.md#L1086-L1090 明确说明:framework 可以预留"0.001" CPUs,但三位小数以下的精度在旧版本中本就不可靠。

实现依据

该变更的权威说明同时出现在发布公告(MESOS-4687)、升级指南 与ReservationInfo等资源相关 protobuf 定义(mesos.proto#L1384)中,属于对资源数值表示的全局性改造。

特性三:预留资源支持 Labels

变更内容

0.28.0 起,被预留的资源(reserved resources)可以附带Labels——一组键值对,用于把元数据与预留资源关联起来。例如,framework 可以用 Labels 区分同一 agent 上、为同一 role 预留但用途不同的两份资源。

Protobuf 定义

在 mesos.proto 的 ReservationInfo 中,labels被定义为可选字段,注释明确写道:

Labels are free-form key value pairs that can be used to associate arbitrary metadata with a reserved resource. For example, frameworks can use labels to identify the intended purpose for a portion of the resources the framework has reserved at a given slave. Labels should not contain duplicate key-value pairs.

即:Labels 是自由格式的键值对,用于给预留资源附加任意元数据,同一资源内不允许出现重复键值对。该字段可与ReservationInfo.type(STATIC/DYNAMIC)、role、principal等字段配合使用,完整用法见 mesos.proto#L1384-L1448。

特性四:实验性容器镜像支持(Unified Containerizer)

动机:统一容器化

0.28.0 通过 MESOS-2840 为 Mesos containerizer 引入了容器镜像支持(即后来的 Unified Containerizer):framework 可以不依赖 docker daemon(engine)或 rkt,直接用 Mesos containerizer 启动 Docker/Appc 容器,隔离完全交给 isolator 完成。动机是同时维护 Mesos containerizer 与 Docker containerizer 两套实现成本极高,且某些资源(如 agent 上的网络句柄)需要跨容器化器协调,几乎无法落地。详细论证见 container-image.md 的 Motivation 小节。

核心组件:Image Provisioner

Mesos containerizer 中新增了image provisioner组件,负责拉取、缓存并准备容器根文件系统(rootfs),同时从容器镜像中提取运行时配置,交给对应的 isolator 做隔离。0.28.0 支持 Docker 与 Appc 两种镜像规范(OCI 为后续规划)。注意:容器镜像目前仅支持 Linux。

配置 agent

启用容器镜像支持需要同时配置两类 agent 参数:

  1. --image_providers:声明允许的镜像类型,如docker、appc,可同时指定多个(--image_providers=docker,appc);
  2. --isolation中必须追加以下 isolator:
    • filesystem/linux:支持容器镜像必然涉及切换文件系统根目录,只有该 isolator 支持(需要 root 权限);
    • docker/runtime:解析 Docker 镜像中的运行时配置(Entrypoint/Cmd、环境变量等)。如果--image_providers包含docker而未启用此 isolator,agent 将拒绝启动。

完整的最小配置示例(来自 container-image.md#L79-L85):

$ sudo mesos-agent \ --containerizers=mesos \ --image_providers=appc,docker \ --isolation=filesystem/linux,docker/runtime

Framework API

框架侧新增Imageprotobuf 消息,目前包含APPC与DOCKER两种类型:

message Image { enum Type { APPC = 1; DOCKER = 2; } message Appc { required string name = 1; optional Labels labels = 3; } message Docker { required string name = 1; } required Type type = 1; optional Appc appc = 2; optional Docker docker = 3; }

其中 Docker 镜像的name采用与docker pull一致的引用格式:[REGISTRY_HOST[:REGISTRY_PORT]/]REPOSITORY[:TAG|@DIGEST]。框架还需在ContainerInfo中设置ContainerInfo.MESOS类型并填写MesosInfo.image:若image未指定,容器使用宿主文件系统;若指定,则用它作为启动容器的镜像。

上手实操

按 container-image.md 的 Test it out 小节,依次启动 master、agent 后,用mesos-execute拉起 Docker 容器:

# 启动 master $ sudo sbin/mesos-master --work_dir=/tmp/mesos/master # 启动 agent $ sudo GLOG_v=1 sbin/mesos-agent \ --master=<MASTER_IP>:5050 \ --isolation=docker/runtime,filesystem/linux \ --work_dir=/tmp/mesos/agent \ --image_providers=docker \ --executor_environment_variables="{}" # 用 mesos-execute 启动 redis(--shell=false 表示使用镜像内默认 entrypoint/cmd) $ sudo bin/mesos-execute \ --master=<MASTER_IP>:5050 \ --name=test \ --docker_image=library/redis \ --shell=false

然后用 redis-cli 验证容器是否在运行:

$ sudo docker run -ti --net=host redis redis-cli 127.0.0.1:6379> ping PONG

Docker/Appc 支持现状与相关 agent 参数

  • image provisioner 基于 Docker v2 registry API 拉取镜像,同时支持 manifest v2 schema1 与 schema2;拉取基于curl,SSL 自动处理;私有 registry 需要运维为curl配置 CA 证书。
  • 需要认证的拉取通过--docker_config支持(可指向本地 docker config 文件,如file:///home/vagrant/.docker/config.json,或直接传 JSON 字符串)。
  • 私有 registry 可通过--docker_registry指定,或直接在镜像名中带<REGISTRY>/<REPOSITORY>前缀(此时会忽略 flag 值);若该 flag 指向本地目录,provisioner 会从本地docker save产生的归档中拉取镜像。
  • Appc 仅支持根文件系统;镜像发现采用简单机制:在 URI 模板{name}-{version}-{os}-{arch}.{ext}前拼接appc_simple_discovery_uri_prefix(默认http://)。

相关 agent 参数及默认值(定义见 flags.cpp):

参数说明默认值
--image_providers逗号分隔的允许镜像提供方(如APPC,DOCKER)无
--image_provisioner_backendrootfs 供给策略:aufs/bind/copy/overlay自动选择
--docker_registry拉取 Docker 镜像的默认 registry 或本地归档目录https://registry-1.docker.io
--docker_store_dirDocker 镜像缓存目录/tmp/mesos/store/docker
--docker_config默认 docker config 文件(路径或 JSON)无
--appc_simple_discovery_uri_prefixAppc 简单发现的 URI 前缀http://
--appc_store_dirAppc 镜像缓存目录/tmp/mesos/store/appc

Provisioner Backends

provisioner backend 负责把一组文件系统层叠加成根文件系统,支持copy、bind、overlay、aufs四种(见 container-image.md#L300-L385):

+---------+--------------+------------------------------------------+ | Backend | Suggested on | Disabled on | +---------+--------------+------------------------------------------+ | aufs | ext4 xfs | btrfs aufs eCryptfs | | overlay | ext4 xfs* | btrfs aufs overlay overlay2 zfs eCryptfs | | bind | | N/A(--sandbox_directory' must exist) | | copy | | N/A | +---------+--------------+------------------------------------------+
  • copy:把所有层复制到目标根目录;
  • bind:适合大体积单层镜像且内核不支持 overlayfs 的场景,近乎零 IO,但仅支持单层、文件系统只读;
  • overlay:需要 Linux 内核 4.0+ 的多 lower layer 支持,兼顾效率与多层合并;
  • aufs:为 kernel 3.18 之前 overlayfs 未合入、且 Ubuntu 14.04 Docker 默认存储后端为 AUFS 的场景提供兼容。

未设置--image_provisioner_backend时,Mesos 自动选择:优先overlay,其次aufs,最后copy。

特性五:实验性 v1 Executor HTTP API

概述

Executor HTTP API 允许 executor 直接向 agent 的/api/v1/executor端点发送 HTTP 请求,无需 executor driver。这使 executor 可以不依赖 C++ 或原生客户端库开发(理论上可用任意通用 HTTP 库直接对接)。端点接受application/json或application/x-protobuf两种编码的 POST 请求,首个请求必须是SUBSCRIBE,其响应为200 OK+Transfer-Encoding: chunked的流式连接。

关键约定:executor应尽可能长期保持订阅连接并增量处理响应,无法在连接关闭后才解析的 HTTP 客户端库不可用;非SUBSCRIBE请求必须走独立连接,agent 以202 Accepted应答(表示已接收、不代表处理完成)。

Calls(executor → agent)

  • SUBSCRIBE:通信的第一步,也是订阅/executor事件流。请求中可携带unacknowledged_tasks与unacknowledged_updates(断连重连场景);agent 首先回送SUBSCRIBED事件。若 executor 在--executor_registration_timeout(agent 启动时配置)内未完成订阅,agent 会强制销毁 executor 所在容器。
  • UPDATE:可靠上报任务状态;终端状态(TASK_FINISHED/TASK_KILLED/TASK_FAILED)必须尽快上报,以便 Mesos 释放资源。未收到ACKNOWLEDGED的更新需在重连时随SUBSCRIBE重新发送。
  • MESSAGE:向 scheduler 发送任意二进制数据(Base64 编码),Mesos 不解释、不保证送达。

Events(agent → executor)

agent 按 RecordIO 格式在订阅连接上流式推送事件:先发送 64 位无符号长度的文本表示,再发送 JSON 或二进制 Protobuf(可能压缩)编码的事件体。支持的事件包括:

  • SUBSCRIBED:订阅成功后的首个事件,返回 executor/framework/agent 信息;
  • LAUNCH:指派新任务,executor 必须回送UPDATE;
  • KILL:请求停止某任务,executor 必须回送终端更新;
  • ACKNOWLEDGED:确认已收到某条状态更新,被确认的更新不得重试;
  • MESSAGE:scheduler 转发的自定义消息(不做送达保证);
  • SHUTDOWN:要求 executor 优雅退出;超时(MESOS_EXECUTOR_SHUTDOWN_GRACE_PERIOD)后 agent 会强制销毁容器并对剩余活动任务发送TASK_LOST;
  • ERROR:异步错误,建议 executor 中止并重试订阅。

(LAUNCH_GROUP事件为 1.1.0 后续版本加入,本版本不包含。)

Executor 环境变量与断连恢复

agent 会为 executor 注入MESOS_FRAMEWORK_ID、MESOS_EXECUTOR_ID、MESOS_SANDBOX、MESOS_AGENT_ENDPOINT、MESOS_CHECKPOINT、MESOS_EXECUTOR_SHUTDOWN_GRACE_PERIOD、MESOS_EXECUTOR_AUTHENTICATION_TOKEN等变量;启用 checkpoint 时还会设置MESOS_RECOVERY_TIMEOUT与MESOS_SUBSCRIPTION_BACKOFF_MAX(分别对应 agent 的--recovery_timeout与--executor_reregistration_timeout)。

断连后的重试策略取决于 framework 是否启用 checkpoint:未启用则不应重试并优雅退出;启用则应在MESOS_RECOVERY_TIMEOUT内采用合适的退避策略(如线性退避)重试订阅。agent 的--recover标志支持reconnect(默认,重连旧 executor 并等其全部回归才标记恢复完成)与cleanup(杀掉旧 executor 后退出,常用于不兼容升级)两种恢复模式。

特性六:Docker Remote API v1.21 服务发现

0.28.0 还针对使用 Docker Remote API v1.21 的 Docker 容器增加了服务发现支持(MESOS-4370)。这意味着使用该 API 版本部署的 Docker 容器能够被 Mesos 的服务发现机制正确识别与处理。

API 变更汇总

发布公告还列出了一批 API 层面的调整:

变更JIRA说明
agent 恢复期间/state不返回部分状态MESOS-4066请求/state端点时不再返回不完整状态
引入TASK_KILLING状态MESOS-4547新增任务状态,表示任务正在被杀(见 mesos.proto#L2388)
移除 v1 Scheduler APISubscribeCall 的force字段MESOS-4712v1 Scheduler API 的订阅调用不再包含force
ReserveResources/CreateVolumeACL 对象改为rolesMESOS-4591授权粒度从 principal 转向按 role 授权
为 HTTP scheduler 增加 stream IDMESOS-3583支持多连接 HTTP scheduler 的会话标识
校验state.json中NetworkInfo的ip_addressMESOS-4427确保ip_address合法

关于TASK_KILLING:它是 executor 在真正杀死任务前上报的中间状态,用于告知框架"任务正在被杀"。仓库测试 command_executor_tests.cpp 中有专门用例验证:只有声明了TASK_KILLING_STATEcapability 的 framework 才会收到TASK_KILLING更新(见 command_executor_tests.cpp#L157-L261)。

关于ReserveResources/CreateVolumeACL:变更后 principal 可按 role 被授权执行预留资源/创建卷操作;默认情况下 framework 或 operator 可以为任意 role 预留资源。若希望维持旧行为(只能为自己的 role 预留),需要显式配置ReserveResourcesACL。升级文档 upgrades.md#L1092-L1094 特别提醒:既有 ACL 定义已过时,需要同步更新。

升级指南:从 0.27.x 滚动升级到 0.28.0

发布公告明确:从 Mesos 0.27.0 集群滚动升级到 0.28.0 是直截了当的,仅存在少量向后兼容的废弃项。升级前请完整阅读 升级指南,其中有两点需要特别注意:

  1. 资源精度:0.28 仅支持标量资源三位小数精度;
  2. ACL 语义:ReserveResources与CreateVolume的 ACL 对象已改为roles,旧定义需更新。

运行中集群的升级步骤如下(来自 upgrades.md#L1096-L1103):

  1. 重新构建并安装各类模块,供升级后的 master/agent 使用;
  2. 安装新 master 二进制并重启 master;
  3. 安装新 agent 二进制并重启 agent;
  4. 链接最新原生库 / jar / egg 以升级 scheduler(如必要);
  5. 重启 scheduler;
  6. 链接最新原生库 / jar / egg 以升级 executor(如必要)。

总结

Apache Mesos 0.28.0 是一个兼具"补课"与"铺路"性质的版本:cgroups/net_cls与资源精度改造修复了网络隔离和数值表示上的历史问题;预留资源 Labels 为资源管理增加了元数据维度;而容器镜像支持与 v1 Executor HTTP API 两大实验特性,则直接指向了后续 1.x 时代 Unified Containerizer 与纯 HTTP API 的技术路线。对于今天的 Mesos 使用者来说,理解 0.28.0 的这些设计决策,是掌握 Mesos containerizer、容器镜像支持、Executor HTTP API 以及 agent 参数体系 的起点。更多细节可进一步阅读 cgroups net_cls 文档、升级指南 与仓库 CHANGELOG。

  • 云原生

【免费下载链接】mesos

Apache Mesos

项目地址:https://gitcode.com/gh_mirrors/mesos2/mesos
点击查看免费下载
上一篇:10个实用技巧:使用mmlw-roberta-large-openmind优化波兰语NLP任务
下一篇:终极指南:Swift异步编程常见问题与BrightFutures解决方案

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询