news 2026/10/13 6:00:47

Mesos Mini 实战与源码剖析:一条 docker run 命令拉起本地 Mesos 集群

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Mesos Mini 实战与源码剖析:一条 docker run 命令拉起本地 Mesos 集群
  • 集群管理
  • 任务调度
  • 后端

【免费下载链接】mesos

Apache Mesos

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

Mesos Mini 是 Apache Mesos 社区维护的 Docker 镜像,它让你在本地用一条docker run命令获得一个“真集群”:一个 Mesos master、一个 Mesos agent 和一个示例框架 Marathon。读完本文,你既能掌握 Mesos Mini 的完整使用流程(启动、通过 Marathon API 部署应用、停止与镜像 tag 选择),也能从源码层面理解它是如何在一个容器内用 systemd 编排多服务、内嵌 Docker Daemon(Docker-in-Docker)解决嵌套 cgroup 问题的——这对编写框架端到端集成测试、模拟 master failover 等场景直接有用。

为什么需要 Mesos Mini

能在 Docker 中一键拉起本地 Mesos 集群,可以显著简化以下场景:

  • 现场演示(Demo):在会场网络不稳定的情况下做 Mesos 现场演示,本地容器化集群不依赖外部网络服务。
  • 框架开发:用本地 Mesos 集群为框架编写端到端集成测试,并且可以轻易地自动化进测试套件(CI)。
  • 测试未发布的 Mesos 新特性:虽然也可以从源码构建 Mesos,但大多数框架开发者不熟悉构建流程且耗时较长,直接用快照镜像更方便。

这个思路类似 Kubernetes 生态的 minikube 或早期的 minimesos 工具。由于 minimesos 已不再维护,Apache Mesos 社区决定在 Mesos 仓库内自行维护一套方案,以简化 CI 集成。

快速上手:一条命令启动本地集群

前提是宿主机已安装 Docker(文档在 Linux 与 MacOS 上均验证过)。执行:

$ docker run --rm --privileged -p 5050:5050 -p 5051:5051 -p 8080:8080 mesos/mesos-mini

参数说明:

  • --rm:容器退出后自动删除容器对象;
  • --privileged:容器内需要操作 cgroup、挂载、网络等,必须放开特权;
  • -p 5050:5050:Mesos master UI(见MESOS_ADVERTISE_IP等配置,master 监听 5050);
  • -p 5051:5051:Mesos agent;
  • -p 8080:8080:Marathon UI 与 API。

启动后,容器内会运行 1 个 master、1 个 agent 和 1 个示例框架(Marathon),可分别访问:

  • Mesos master UI:http://localhost:5050
  • Mesos agent:http://localhost:5051
  • Marathon UI:http://localhost:8080

通过 Marathon 部署应用

可以在本地集群里像生产环境一样用 Marathon 提交应用。例如把如下内容保存为app.json:

{ "id": "test", "cmd": "sleep 1000", "cpus": 1, "mem": 128, "disk": 0, "instances": 1, "container": { "docker": { "image": "alpine" }, "type": "DOCKER" }, "networks": [ { "mode": "host" } ] }

然后通过 Marathon 的 v2 API 提交:

$ curl -X POST -d @app.json -H "Content-type: application/json" http://localhost:8080/v2/apps

注意这里提交的是type: DOCKER的容器,它走的是 Mesos agent 的Docker Containerizer(见下文“内嵌 Docker Daemon”一节),而不是 UCR,这正是 Mesos Mini 想要覆盖的典型生产路径。

停止本地集群使用docker stop <CONTAINER_ID>。由于容器内所有状态都在容器内,容器停止后所有产物(work dir、嵌套容器等)都会随之清理,天然“无残留”。

镜像 tag 规范

社区维护以下 Docker 镜像 tag(以 Docker Hub 上的mesos/mesos-mini为准):

Tag含义示例
mastermaster 分支最新 HEADmesos/mesos-mini:master
<RELEASE_BRANCH>发布分支最新 HEAD1.7.x
master-<DATE>master 分支快照构建master-2018-11-19
<RELEASE_BRANCH>-<DATE>发布分支快照构建1.7.x-2018-11-19

注意:不支持1.7.x之前的发布分支,之后的新发布分支都会被支持。

从源码看,tag 的生成逻辑就在 CI 脚本 mini.sh 中:脚本先用git describe --exact-match判断 HEAD 是否为精确 tag——是则推 tag 名镜像;否则取当前所在远端分支(形如[0-9]+\.[0-9]+\.x,找不到则回退为master)拼出<分支>-<日期>作为快照 tag,并把分支名作为“latest” tag 推送。这与上表的 tag 规范一一对应。

它是如何实现的

用 systemd 管理多个服务

Mesos Mini 容器内直接用systemd编排多个守护进程。Dockerfile 的关键步骤包括:

  1. 设置ENV container docker并清理系统自带的无关 service(getty、dbus、logind 等),只保留精简的 systemd 环境(Dockerfile);
  2. 内嵌静态版 Docker 17.12.0 CE 到/usr/local/bin,并复制docker.service、docker_daemon.json(Dockerfile);
  3. 安装 Marathon(1.6.322)并复制marathon.service(Dockerfile);
  4. 执行systemctl enable docker mesos-slave mesos-master marathon,将四个服务设为开机自启(Dockerfile);
  5. 容器入口为entrypoint.sh,最终exec /usr/sbin/init让 systemd 成为 PID 1(entrypoint.sh),并用STOPSIGNAL SIGRTMIN+3通知容器停止时向 systemd 发送标准停机信号,走优雅停止流程(Dockerfile)。

其中mesos-master.service、mesos-slave.service这两个 unit 来自 Mesos 打包脚本 support/packaging/common/,与正式发行版使用的同一套 systemd 单元文件——这也是“尽量模仿生产环境”的体现。

由此带来一个非常实用的能力:可以单独重启某个服务。例如重启 Mesos master:

$ docker exec <CONTAINER_ID> systemctl restart mesos-master

同理也可以重启 agent(mesos-slave)、Marathon 或 Docker daemon。这对需要模拟master failover的端到端集成测试尤其有用——测试脚本可以随时把 master 杀掉再拉起,观察框架的重注册行为。

各服务的环境变量配置同样以 systemd 环境文件的形式提供:

  • master 环境:master_environment 中设置MESOS_CLUSTER=mesos-mini、MESOS_ADVERTISE_IP=127.0.0.1、MESOS_WORK_DIR=/var/lib/mesos/master;
  • agent 环境:agent_environment,这是理解 UCR/Docker Containerizer 行为的关键,后面详述。

内嵌 Docker Daemon(Docker in Docker)

Mesos Mini 的目标之一是尽可能贴近生产配置。为了让框架能真正拉起 Docker 容器(type: DOCKER的 task),容器内嵌了一个 Docker Daemon。你可以在宿主机上直接查看 Mesos 集群内部的 Docker 容器:

$ docker exec <CONTAINER_ID> docker ps

从实现看,几个细节保证了“嵌套容器”的正确性:

  1. cgroup parent 的嵌套。docker_env.sh 在 dockerd 启动前读取容器自身 PID 1 的 memory cgroup 路径,生成CGROUP_PARENT=<容器cgroup>/docker写入环境变量文件;docker.service 以dockerd --cgroup-parent=${CGROUP_PARENT}启动并设置Delegate=yes。这样内层 Docker 容器的 cgroup 全部嵌套在 Mesos Mini 容器自己的 cgroup 之下,Mini 容器退出时不会在宿主机留下任何 cgroup 残留。
  2. 存储驱动选择 vfs。docker_daemon.json 中配置"storage-driver": "vfs",避免 overlay 等存储驱动在容器嵌套场景下的兼容性问题,代价是磁盘占用略大——对一个测试镜像而言是可接受的取舍。
  3. 内嵌 dockerd 使用静态二进制(Docker 17.12.0 CE),不依赖 CentOS 发行版自带的 docker 包,保证版本可控(Dockerfile)。

UCR 的 cgroup 布局修复

对 Mesos Containerizer(UCR),Mesos Mini 打开了生产环境中通常启用的大部分 isolator。可以从 agent_environment 看到 agent 的实际启动配置:

MESOS_CONTAINERIZERS=mesos,docker MESOS_ISOLATION=filesystem/linux,network/cni,cgroups/cpu,cgroups/mem,cgroups/blkio,cgroups/devices,disk/du,docker/runtime,volume/sandbox_path,volume/host_path,posix/rlimits,namespaces/pid,linux/capabilities

即同时启用mesos(UCR)与docker两种 containerizer,并叠加 cgroup、namespace、rlimits 等一套接近生产的 isolator 组合。UCR 的网络走 CNI:MESOS_NETWORK_CNI_CONFIG_DIR=/etc/mesos/cni指向 ucr-default-bridge.json(mesos-cni-port-mapper+ bridge 委托,子网172.31.254.0/24),CNI 插件 v0.7.4 由 Dockerfile 预装到/usr/libexec/mesos/cni。

但这里有一个嵌套容器特有的坑:外层 Docker 会为每个 cgroup 子系统做 bind mount,例如把当前容器的 cgroup 绑定到子系统根:

/sys/fs/cgroup/memory/docker/<cid> -> /sys/fs/cgroup/memory

这会“骗过”依赖/proc/<pid>/cgroup的组件——因为该 proc 文件不受 bind mount 影响,Mesos agent 与 UCR 据此判断进程所属 cgroup 时会得到与实际挂载点不符的路径。

entrypoint.sh 的解决方式是:容器启动时解析/proc/self/mountinfo,找出所有 Docker 做的 cgroup bind mount,然后对每个子系统再叠加一层 bind mount,在/sys/fs/cgroup/<subsystem>/docker/<cid>下重建“等同于宿主机”的 cgroup 布局:

$ mkdir -p /sys/fs/cgroup/memory/docker/<cid> $ mount --bind /sys/fs/cgroup/memory /sys/fs/cgroup/memory/docker/<cid>

之后再把 agent 的--cgroups_root指向这一层。从当前仓库的 agent_environment 看,该标志的取值是$(grep memory /proc/1/cgroup | cut -d: -f3)/mesos,即容器 PID 1 所在 memory cgroup 路径(形如docker/<cid>)下的mesos子目录——与博客描述的思路一致:让 agent 认为自己运行在“宿主机”的 cgroup 树上,从而在 Mini 容器退出时不遗留任何 cgroup 痕迹。

其他值得一提的 agent 配置

继续看 agent_environment:

  • MESOS_IMAGE_PROVIDERS=DOCKER+MESOS_IMAGE_PROVISIONER_BACKEND=copy:agent 可直接从 Docker 镜像仓库拉取镜像并复制进 UCR 沙箱(UCR 拉镜像路径);
  • MESOS_DISK_PROFILE_ADAPTOR=org_apache_mesos_UriDiskProfileAdaptor:通过 uri_disk_profile.json 模块从http://localhost/mesos_disk_profiles.json轮询加载磁盘 profile(10 秒一次),用于演示资源 provider/磁盘 profile 能力;
  • MESOS_SYSTEMD_ENABLE_SUPPORT=false、MESOS_HOSTNAME_LOOKUP=false:在容器环境下关闭 hostname 反查等不适合的操作。

Marathon 侧,marathon.sh 中的启动参数也呼应了本文档“当前限制”一节:--internal_store_backend "mem"与--disable_ha说明 Marathon 使用内存存储而非 ZooKeeper;marathon.service 还设置了Restart=always与RestartSec=5,即使测试中把 Marathon 杀掉它也会自动拉起。

构建与 CI

Mesos Mini 的构建脚本托管在 Mesos 仓库 support/mesos-mini/ 目录中。build.sh 是两阶段构建:

  1. 先调用support/packaging/centos/下的脚本构建基础镜像mesos/mesos-centos(基于 centos7.dockerfile 编译安装完整 Mesos 发行版);
  2. 再以mesos/mesos-centos:<tag>为BASE_IMAGE_NAME构建 Dockerfile,产出mesos/mesos-mini:<tag>。

也就是说,mesos/mesos-mini使用mesos/mesos-centos作为基础镜像。有些用户只需要“安装了 Mesos 的镜像”而不是完整 Mini 集群,mesos/mesos-centos正好满足这一需求,其 tag 规则与 mini 相同。

Jenkins CI 通过 mini.sh 与 docker-centos.sh 每日自动为受支持的发布分支和 master 分支构建并推送快照镜像(对应上文的<分支>-<日期>tag)。如需为 Mini 提交 bug 修复或新功能,遵循 Apache Mesos 的贡献流程即可。

当前限制

  • 只能启动一个Mesos agent(单节点集群,无法模拟多 agent 拓扑);
  • Marathon 使用内存存储而非 ZooKeeper(见--internal_store_backend mem),容器重启后 Marathon 状态不保留;
  • 未启用 SSL(master/agent 均为 HTTP 明文)。

如果你的集成测试需要验证 HA(多 master、ZooKeeper 选主)或多 agent 场景,Mesos Mini 无法覆盖,需要自行编排多容器环境。

小结

Mesos Mini 的价值在于“用最小成本获得一条贴近生产的路径”:systemd 编排的 master/agent/Marathon、双 containerizer(UCR + Docker)、生产级 isolator 组合、CNI 网络与镜像 provider,全部收敛在一条docker run命令里;而 cgroup bind mount 重建、cgroup-parent嵌套、--cgroups_root重定位等细节,则保证了容器停止后零残留。对于框架开发者,它既是现成的本地测试集群,也模拟了 failover 等运维动作的验证手段。关键源码入口汇总:support/mesos-mini/Dockerfile、support/mesos-mini/entrypoint.sh、support/mesos-mini/mesos/agent_environment、support/jenkins/mini.sh。

  • 集群管理
  • 任务调度
  • 后端

【免费下载链接】mesos

Apache Mesos

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

相关推荐

上一篇:ARIS 替代模型组合全指南:不用 Claude / OpenAI API,如何用 GLM、Kimi、DeepSeek、MiniMax 与 Codex 驱动跨模型审稿循环
下一篇:10分钟上手YOLOv4模型训练:从数据集到部署的零基础完整指南

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/13 5:58:30

C语言图形库ege入门教程:安装配置与环境搭建详解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/13 5:57:57

Java工程师24周转型Agent工程师:从后端思维到LLM系统实战

1. 为什么Java老手转Agent工程师反而有优势身边不少写了五六年Java的朋友最近都在聊转型的事&#xff0c;方向出奇地一致——Agent Engineer。有人觉得这是跟风&#xff0c;但我实际接触下来发现&#xff0c;Java工程师转这个方向&#xff0c;起点比想象中高得多。原因不复杂&a…

作者头像 李华
网站建设 2026/10/13 5:57:16

Claude Code 从入门到规模化:终端 AI 编程代理的完整实践指南

Claude Code 从入门到规模化&#xff1a;终端 AI 编程代理的完整实践指南 【免费下载链接】developer-roadmap Interactive roadmaps, guides and other educational content to help developers grow in their careers. 项目地址: https://gitcode.com/GitHub_Trending/de/d…

作者头像 李华
网站建设 2026/10/13 5:56:21

西门子PLC实战:锂电浆料线程序开发与通讯调试全流程

很多人找我聊西门子PLC程序开发怎么入门&#xff0c;我一般不会直接甩教程&#xff0c;而是先反问一句&#xff1a;你见过新能源浆料线吗&#xff1f;去年我接手了一条锂电正极浆料产线的整套PLC程序开发&#xff0c;从需求梳理到带料调试&#xff0c;前后折腾了小半年。说句实…

作者头像 李华
网站建设 2026/10/13 5:55:09

Agent技能设计实战:从Function Calling到稳定落地

去年我接手了一个项目&#xff0c;目标很明确&#xff1a;在某个跨平台系统里&#xff0c;让大模型驱动的Agent替用户去处理日常事务——查日程、建提醒、发通知、拉资料汇总。最开始我天真地以为&#xff0c;给大模型塞几个函数定义&#xff0c;它就能老老实实地把事情干完。结…

作者头像 李华