- 云原生
【免费下载链接】mesos
Apache 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 | 行为变更 |
| 预留资源支持 Labels | MESOS-4479 | 新功能 |
| Mesos containerizer 容器镜像支持 | MESOS-2840 | 实验性 |
| v1 Executor HTTP API | MESOS-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 参数:
--image_providers:声明允许的镜像类型,如docker、appc,可同时指定多个(--image_providers=docker,appc);--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/runtimeFramework 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 PONGDocker/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_backend | rootfs 供给策略:aufs/bind/copy/overlay | 自动选择 |
--docker_registry | 拉取 Docker 镜像的默认 registry 或本地归档目录 | https://registry-1.docker.io |
--docker_store_dir | Docker 镜像缓存目录 | /tmp/mesos/store/docker |
--docker_config | 默认 docker config 文件(路径或 JSON) | 无 |
--appc_simple_discovery_uri_prefix | Appc 简单发现的 URI 前缀 | http:// |
--appc_store_dir | Appc 镜像缓存目录 | /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-4712 | v1 Scheduler API 的订阅调用不再包含force |
ReserveResources/CreateVolumeACL 对象改为roles | MESOS-4591 | 授权粒度从 principal 转向按 role 授权 |
| 为 HTTP scheduler 增加 stream ID | MESOS-3583 | 支持多连接 HTTP scheduler 的会话标识 |
校验state.json中NetworkInfo的ip_address | MESOS-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 是直截了当的,仅存在少量向后兼容的废弃项。升级前请完整阅读 升级指南,其中有两点需要特别注意:
- 资源精度:0.28 仅支持标量资源三位小数精度;
- ACL 语义:
ReserveResources与CreateVolume的 ACL 对象已改为roles,旧定义需更新。
运行中集群的升级步骤如下(来自 upgrades.md#L1096-L1103):
- 重新构建并安装各类模块,供升级后的 master/agent 使用;
- 安装新 master 二进制并重启 master;
- 安装新 agent 二进制并重启 agent;
- 链接最新原生库 / jar / egg 以升级 scheduler(如必要);
- 重启 scheduler;
- 链接最新原生库 / 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
相关推荐
Apache Mesos 0.28.0 发布亮点解析:net_cls 网络隔离、资源精度与容器镜像支持
Apache Mesos 0.28.0 发布亮点解析:net_cls 网络隔离、资源精度与容器镜像支持 Apache Mesos 0.28.0 是该项目的又一重
集群管理任务调度后端Apache Mesos cgroups/net_cls 隔离器:基于 net_cls 子系统的容器网络隔离与流量标记实战指南
Apache Mesos cgroups/net_cls 隔离器:基于 net_cls 子系统的容器网络隔离与流量标记实战指南 导读 本文围绕 Apache M
集群管理任务调度后端Apache Mesos cgroups/net_cls 隔离器:容器网络标记与流量分类实战指南
Apache Mesos cgroups/net_cls 隔离器:容器网络标记与流量分类实战指南 Apache Mesos 的 cgroups/net_cls
云原生
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考