Ubuntu 22.04 编译安装 Apache Mesos 1.11.0 指南

Ubuntu 22.04 从源码编译安装 Apache Mesos 1.11.0 的完整实测记录:依赖安装、官方校验下载、configure 选项说明、glibc 2.35 与 -Werror 两大编译故障的修补、make install 布局与最小集群启动验证。

Apache MesosMesosApache安装部署Ubuntu 22.04集群2026/10/15

Ubuntu 22.04 编译安装 Apache Mesos 1.11.0 指南

本文全部命令与回显均在 Ubuntu 22.04(内核 5.15)服务器上实测执行,工具链为 gcc 11.4.0 与 GNU Make 4.3。Mesos 已于 2025 年 10 月整体迁入 Apache Attic,本文安装的是其 1.11.0 版本,适用于学习集群资源调度原理与维护存量遗产系统,不建议新项目采用。

一、安装目标与路线

1.1 安装目标

在全新安装的 Ubuntu 22.04 服务器上完成 Mesos 1.11.0 的源码编译、安装与启动验证,最终得到:

  • 核心守护进程 /usr/local/sbin/mesos-master 与 /usr/local/sbin/mesos-agent;
  • 调试与运维工具 /usr/local/bin/mesos-execute、mesos-log、mesos-resolve 等;
  • 批量启停脚本 mesos-start-cluster.sh、mesos-daemon.sh 等;
  • 核心库 /usr/local/lib/libmesos.so 与 C++ 头文件 /usr/local/include/mesos/;
  • 一套可运行的最小集群(单 Master + 单 Agent)并跑通真实任务。

产物规模的直观预期(实测):sbin 下 13 个守护进程与脚本、bin 下 9 个 CLI 工具、include 下 133 个头文件,以及一个 850MB 的主库(未 strip,原因见 4.3 节)。

1.2 为什么选择源码安装

Apache Mesos 官方从不提供 Linux 二进制发行包,安装方式只有两条:源码编译,或使用第三方系统仓库。Debian/Ubuntu 官方仓库曾长期收录 mesos 包,但随 1.9 版本(2019 年)后上游发包节奏放缓而停止更新,Ubuntu 22.04 的仓库里已没有 1.11;第三方 PPA 也早已失修。因此源码编译是获取 1.11.0 的唯一官方途径。发行包同时内嵌了全部第三方组件源码(实测源码包 3rdparty/ 目录下有 25 个 .tar.* 文件),编译过程完全不需要访问外网,这一设计对离线服务器非常友好。

25 个内嵌组件本身就是一张「Mesos 技术栈地图」(实测清单,按构建角色归类):

  • 基础库:boost-1.65.0(C++ 模板库)、protobuf-3.5.0(协议序列化)、glog-0.4.0(日志)、gperftools-2.5 与 jemalloc-5.0.1(可选内存分配器)、rapidjson-1.1.0 与 re2-2020-07-06(JSON 与正则);
  • 网络与并发:libev-4.22、libevent-2.0.22、http-parser-2.6.2、concurrentqueue-7b69a8f;
  • 存储与选举:leveldb-1.19(replicated log 与注册表的存储引擎)、zookeeper-3.4.8(客户端绑定);
  • 安全与隔离:libsasl2(外部依赖)、libseccomp-2.3.3(系统调用过滤)、elfio-3.2(ELF 解析,UCR 用);
  • 生态协议:grpc-1.10.0(CSI 存储接口)、csi-0.2.0 与 csi-1.1.0(CSI 规范协议)、nvml-352.79(GPU 监控)、libarchive-3.3.2(制品解包)、picojson-1.3.0;
  • 构建与测试工具链:googletest-release-1.8.0、pip/setuptools/wheel(Python 绑定用,--disable-python 后仍随包存在)。

理解这张地图有实际收益:排障时看到报错路径里的 grpc-1.10.0、leveldb 等字样,能立刻定位是哪一层的问题(如 7.1 节的 gettid 冲突就在 grpc 层)。

1.3 环境与版本

$ gcc --version | head -1
gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

$ make --version | head -1
GNU Make 4.3

$ java -version 2>&1 | head -1
openjdk version "1.8.0_504"

磁盘方面:源码包 72,210,031 字节,解压后约 130 MB,构建目录峰值实测约 6.1 GB,安装产物约 100 MB。在 12 核环境下全量编译约需 40 分钟。

二、系统准备与依赖

2.1 安装编译依赖

apt-get update
apt-get install -y build-essential automake autoconf libtool \
  libapr1-dev libcurl4-openssl-dev libsasl2-dev libsvn-dev \
  zlib1g-dev openjdk-8-jdk python3

各依赖的作用:build-essential/automake/autoconf/libtool 提供 autotools 构建链(Mesos 的 bootstrap 与 configure 依赖它们);libapr1-dev 是 APR 运行时(网络与内存抽象,libprocess 事件引擎的底座),libcurl4-openssl-dev 供 Master/Agent 的 HTTP 客户端使用,libsasl2-dev 提供 SASL 认证能力,libsvn-dev 用于 SVN 历史遗留的 URL 解析(configure 会探测,缺失时相关能力被关闭而非报错),zlib1g-dev 提供压缩。openjdk-8-jdk 虽然 configure 时会被探测(即使计划禁用 Java 构建也建议安装,见 4.2 节),python3 供运维脚本使用。

两个工程提醒:其一,这套依赖里没有 quilt/patch 工具,但 7.1 节的 grpc 补丁流程只需要 sed/ed 级别的编辑即可完成;其二,构建对 swap 敏感——12 核并发的 C++ 编译瞬时内存可观,内存紧张的机器建议降低并发度而不是依赖 swap,否则编译时长会不可控地膨胀。

2.2 确认 JDK

$ ls /usr/lib/jvm/
java-1.8.0-openjdk-amd64  java-8-openjdk-amd64

后续 configure 前需要显式导出 JAVA_HOME:

export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64

三、获取源码包并校验

3.1 官方下载地址

Mesos 已退役,常规镜像不再保留其发行包,实测 dlcdn 上无 mesos 目录;完整历史只存于 Apache 归档站点:

https://archive.apache.org/dist/mesos/1.11.0/mesos-1.11.0.tar.gz

归档站点刻意限速(响应头携带 Vary: Slow,Glacial),72 MB 的包需要下载数分钟,属正常现象。同目录提供官方校验文件 mesos-1.11.0.tar.gz.sha512。严格的供应链校验还有第二层:归档目录上级的 KEYS 文件收集了发布经理的 GPG 公钥,下载 mesos-1.11.0.tar.gz.asc 后可做签名验证。sha512 校验防「下载损坏」,GPG 验签防「包被替换」,生产留档流程建议两层都做(本文以 sha512 为准实测,GPG 验签流程与常规 Apache 项目一致)。

3.2 下载与校验

实测下载与校验过程:

$ cd /opt/src
$ wget https://archive.apache.org/dist/mesos/1.11.0/mesos-1.11.0.tar.gz
$ ls -l mesos-1.11.0.tar.gz
-rw-r--r-- 1 root root 72210031 mesos-1.11.0.tar.gz

$ sha512sum mesos-1.11.0.tar.gz
48ecc9457f8f86fc3a7f769a43539cfbb1e2178069aaea19ccaa78917612a2ddaefa033a5ace40ccf6f483be4c49e154008c85bc9c715b07415448e2b93ebdba  mesos-1.11.0.tar.gz

与官方 .sha512 文件内容完全一致,包完整性确认无误。这里特别提醒:不要对 72 MB 的归档下载使用断点续传后直接编译,一旦中间块损坏,gzip 多数时候仍能解出部分文件,错误会推迟到编译阶段才暴露,反而更难排查;下载完成务必先做校验和比对。

3.3 解压

$ cd /opt/src
$ tar xzf mesos-1.11.0.tar.gz
$ ls mesos-1.11.0
3rdparty  LICENSE  Makefile.am  NOTICE  README.md
aclocal.m4  bin  bootstrap  compile  config.guess  config.sub
configure  configure.ac  depcomp  include  install-sh  ltmain.sh
m4  missing  src  support

Mesos 的构建使用「树外构建」(out-of-tree build)模式:在源码目录之外另建构建目录执行 configure,所有产物落在构建目录,源码目录保持干净。

两个关键目录的结构值得先认识(理解源码组织,4.1 节的 configure 选项才不陌生):

  • include/:对外 API 声明。include/mesos/mesos.proto 是核心数据模型(实测 3995 行,资源、任务、框架、Agent 的全部消息定义在此),include/mesos/v1/ 是 v1 HTTP API 的协议与头文件(其中 v1/scheduler/scheduler.proto 816 行,定义框架与 Master 之间的全部 Call 与 Event);
  • src/:实现主体,按子系统分目录:master/(分配器、注册表、恢复逻辑)、slave/(Agent 与 containerizer 隔离层)、launcher/ 与 executor/(任务启动器与执行器,即沙箱内进程的宿主)、linux/ 与 posix/(平台相关隔离实现)、authentication/ 与 authorizer/(安全扩展点)、csi/(存储接口)、hook/ 与 examples/(扩展机制与教学样例——examples 里的框架示例是学习调度协议的最好入口)。

四、配置(configure)与编译

4.1 推荐的 configure 选项

$ mkdir -p /opt/build && cd /opt/build
$ export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
$ /opt/src/mesos-1.11.0/configure --disable-java --disable-python --disable-werror

三个选项的实测理由:

  • --disable-java:跳过 Java 绑定与 Java 测试框架构建。Java 绑定会通过内嵌 Maven 下载数百 MB 依赖,是整条编译链最耗时且最易失败的环节;本文目标是 C++ 核心(Master/Agent/CLI),无需 Java 绑定;
  • --disable-python:跳过 Python 绑定与基于 Python 的新版 mesos CLI;
  • --disable-werror:不把编译告警当错误。1.11.0 于 2020 年发布,在 gcc 11.4 下源码与内嵌第三方组件会触发大量新的告警(见第九章排障实录),不加此选项编译必然中断。

除这三个必选项外,configure 还暴露了一批值得了解的开关(实测 configure --help 摘录,按使用频率排序):

  • --disable-bundled:改用系统预装依赖而非内嵌源码。系统库版本与 1.11 期望不匹配的概率极高,除非有统一包管理强约束,否则保持内嵌(默认);
  • --enable-debug:调试构建(配合 CFLAGS/CXXFLAGS 定制优化级别),源码级调试 Mesos 时使用;
  • --disable-hardening:关闭栈保护等加固措施。默认开启的加固会轻微增加性能开销,学习环境可关,生产保持默认;
  • --enable-jemalloc-allocator:用内嵌 jemalloc 替换默认分配器,长驻进程内存碎片敏感场景值得开启(本文未启用);
  • --enable-network-ports-isolator:启用网络端口隔离器(配合 --isolation=network/ports),需要细粒度端口资源管控时使用;
  • --disable-nvml:无 GPU 的机器可关闭 NVML 头文件探测,缩短 configure 时间;
  • --enable-silent-rules 与 make V=0/V=1:控制 make 输出详细度,排障编译错误时用 V=1 看完整命令行。

选择策略一句话概括:默认选项是「内嵌一切 + 加固 + 发布级优化」,学习编译原理与排障时用本文三开关的极简组合;做性能实验时再逐个开启 jemalloc、debug 等开关,一次只改一个以便归因。

configure 正常结束时尾部输出关键探测结果(实测摘录):

checking whether we can build with -Werror... no
checking for styles of subdirectories... one-level
checking JAVA_HOME... /usr/lib/jvm/java-8-openjdk-amd64
configure: build report:
-------------------------------------------------------
mesos:   1.11.0
c++:     GNU 11.4.0
python:  disabled
java:    disabled
-------------------------------------------------------

configure 的完整探测面比这三行宽得多,了解它检查什么能预判大部分「configure 阶段失败」:系统探测(目标三元组、编译器特性、大文件支持)、外部依赖探测(APR、SASL、SVN、zlib、curl,任一缺失都会给出明确的 checking xxx... no 行)、内嵌组件解包计划(3rdparty 各组件的解压与 patch 步骤在 configure 末尾登记)、构建开关汇总(上面的 build report)。排障口诀:看最后一个 checking 行,它就是失败点;往上看两行通常有对应的 why。

4.2 编译

$ cd /opt/build
$ make -j12

12 核并发约 40 分钟完成。构建分两大阶段:先从 3rdparty 内嵌源码构建 glog、protobuf、grpc、boost 等第三方库,再编译 Mesos 自身(libprocess、libmesos 与各命令行程序)。两阶段的时间与资源特征差别明显,规划硬件时可参考:

  • 第三方阶段约占三分之二时间,grpc 与 protobuf 是其中最重的两个(模板密集,单文件编译时间长),该阶段以 CPU 为主、内存平稳;
  • Mesos 自身阶段内存波动大,-j 并发数超过物理内存承载能力时典型的表现是 cc1plus 被 OOM killer 终止(终端报 internal compiler error: Killed),遇到即按「每并发 1.5GB 内存」的经验重新估 -j 值重跑;
  • 全程无需外网(组件全部内嵌),但 3rdparty 解压与 stamp 记录占用构建目录约 3 到 4 倍源码包体积的磁盘,构建目录至少预留 8GB。

第三方阶段的进度可以通过构建目录 3rdparty/ 下的 stamp 文件观察(实测解压与构建完成后共 27 个 stamp,对应 25 个归档组件与 2 个无归档目录组件):

$ ls /opt/build/3rdparty/ | grep -c stamp
27

最后生成核心二进制(构建目录 /opt/build/src/ 下,libtool 包装脚本指向 .libs/ 内真实文件):

$ file /opt/build/src/mesos-master
/opt/build/src/mesos-master: Bourne-Again shell script, ASCII text executable
$ ls -la /opt/build/src/.libs/mesos-master | awk '{print $5, $9}'
2725592 /opt/build/src/.libs/mesos-master

4.3 安装

$ cd /opt/build
$ make install
$ ldconfig

安装布局实测(产物规模与命名都以本次输出为准):

$ ls /usr/local/sbin/ | head -8
mesos-agent
mesos-daemon.sh
mesos-master
mesos-slave
mesos-start-agents.sh
mesos-start-cluster.sh
mesos-start-masters.sh
mesos-stop-agents.sh

$ /usr/local/sbin/mesos-master --version
mesos 1.11.0

$ ls -la /usr/local/lib/ | grep -E "libmesos|modules"
-rwxr-xr-x 1 root root 850586456 libmesos-1.11.0.so
-rwxr-xr-x 1 root root     1076 libmesos.la
lrwxrwxrwx 1 root root       18 libmesos.so -> libmesos-1.11.0.so
drwxr-xr-x 3 root root     4096 mesos

三个容易踩坑的命名与形态细节:

  • 库的版本化方式是「版本后缀 + 无版本符号链接」(SONAME 实测为 libmesos-1.11.0.so),而不是常见的 libmesos.so.11 形态——网上资料常照搬后一种写法,与实际安装产物对不上;排障时以 objdump -p /usr/local/lib/libmesos.so | grep SONAME 的输出为准;
  • libmesos-1.11.0.so 高达 850MB,因为未做 strip(内含调试符号)。生产磁盘紧张时可先 strip --strip-unneeded 该库缩小体积,但会失去符号级排障能力,建议在留档一份带符号副本后再瘦身;
  • /usr/local/lib/mesos/modules/ 下随主库一同安装了 4 个官方模块(实测):libfixed_resource_estimator(固定资源估算器)、libload_qos_controller(负载 QoS 控制器)、liblogrotate_container_logger(任务日志轮转)、liburi_disk_profile_adaptor(磁盘画像适配器),它们以 --modules 参数按需挂载,是 Mesos 模块化扩展机制的官方示例。

头文件与工具的完整规模:/usr/local/include/mesos/ 下 133 个 C++ 头文件(scheduler.hpp、executor.hpp 与 v1 proto 对应头等),/usr/local/sbin 13 个脚本与守护进程,/usr/local/bin 9 个 CLI 工具(mesos-execute、mesos-log、mesos-resolve 等)。

安装后必须执行一次 ldconfig 注册库路径,否则启动守护进程时报 libmesos-1.11.0.so 无法加载。

五、最小集群启动验证

5.1 启动 Master

$ mkdir -p /opt/data/mesos/master /opt/data/mesos/agent
$ nohup /usr/local/sbin/mesos-master --ip=127.0.0.1 \
    --work_dir=/opt/data/mesos/master > /opt/data/mesos/master.log 2>&1 &
$ curl -s http://127.0.0.1:5050/state | head -c 200
{"version":"1.11.0","build_date":"2026-10-14 ...","build_time":"...","build_user":"root","git_sha":"...","git_branch":"...","git_tag":"1.11.0",...}

Master 默认监听 5050,/state 接口返回 JSON 集群状态;浏览器访问 http://服务器IP:5050 即可打开 WebUI。

这条命令只给了三个参数,实际可用参数有上百个(mesos-master --help 可见,分组组织),高频项的含义在此展开,后文 Agent 与多 Master 都要复用:

  • --work_dir:Master 与 Agent 各自的数据根。Master 侧放注册表(replicated log),Agent 侧放任务沙箱;两者语义完全不同,混用目录是新手常见错误;
  • --ip / --advertise_ip:监听地址与对外宣告地址。跨网段部署时 advertise 决定其他节点如何回连,配错的表现是 Master 收得到注册、任务却下发失败;
  • --quorum:单 Master 用 --quorum=1(显式声明),多 Master 集群配 2 或更多(配合 --zk);
  • --cluster:集群别名,展示在 WebUI 标题与 /state,便于多环境识别;
  • --roles / --weights:预置角色与权重(旧式静态配置),现在更推荐运行期 Quota API;
  • --log_dir 与 --logbufsecs:日志目录与缓冲刷新秒数(默认 0 即实时刷),排障期建议保持 0。

防火墙放行清单按角色区分:Master 需放行 5050(HTTP API 与 WebUI)与 5051 的入站回源(框架与 Agent 通信);Agent 需放行 5051 与任务沙箱使用的动态端口段;引入 ZooKeeper 后加 2181。单机验证环境本机访问无防火墙问题,跨机部署时端口不通是最先要排除的因素——curl 一次 /state 与 /health 即可完成双端探测(/health 返回 200 即进程健康)。

5.2 启动 Agent

在 Ubuntu 22.04 服务器(本文环境)上,Agent 默认的 systemd cgroup 探测会失败,实测报错:

Failed to initialize systemd: Failed to locate systemd cgroups hierarchy:
'/sys/fs/cgroup/systemd' is not a valid hierarchy

加上 --systemd_enable_support=false 重新启动:

$ nohup /usr/local/sbin/mesos-agent --master=127.0.0.1:5050 \
    --work_dir=/opt/data/mesos/agent \
    --systemd_enable_support=false > /opt/data/mesos/agent.log 2>&1 &
$ sleep 5
$ curl -s http://127.0.0.1:5050/state | python3 -c \
  "import json,sys; d=json.load(sys.stdin); print([(a['id'],a['pid']) for a in d['slaves']])"
[('S0', 'slave(1)@172.17.0.2:5051')]

Agent 注册成功,集群具备运行任务的能力。/state 的 activated_slaves 由 0 变 1,Agent 侧进程名实测为 slave(1),二者一致即注册链路可信。

5.3 运行第一个任务

$ /usr/local/bin/mesos-execute --master=127.0.0.1:5050 \
    --name=hello --command="echo install-ok"
(依次输出 TASK_STARTING、TASK_RUNNING、TASK_FINISHED)

任务沙箱 stdout 文件中出现 install-ok,即代表「邀约 → 启动隔离实例 → 执行 → 状态回报」全链路可用。

沙箱目录的层级结构值得看一眼,它与 /state 里的 ID 体系一一对应(实测路径骨架):

/opt/data/mesos/agent/slaves/<AgentID-S0>/frameworks/<FrameworkID-0001>/executors/<执行器名>/runs/<运行UUID>/stdout

AgentID、FrameworkID 都由 Master 分配(前缀是 Agent 或 Framework 注册时生成的 UUID),runs 下的 UUID 每次任务运行都不同——同一个框架重复跑任务会产生多个 runs 目录,这正是「沙箱按运行隔离」的物化形态。排障时从 /state 拿到 framework/task 的 ID,即可沿该层级直达沙箱;反向清理时,删除某个 frameworks/<id> 目录即清掉该框架在此 Agent 的全部痕迹(需先确保任务已结束)。

紧接着做一次反例对照(实测):命令不存在时任务同样走完流程但落在失败终态:

$ /usr/local/bin/mesos-execute --master=127.0.0.1:5050 \
    --name=fail-demo --command="nosuchcmd-xyz"
TASK_FAILED(Status update: TASK_FAILED,message: Command exited with status 127)

退出码 127 是 shell 「命令未找到」的标准码,经 Agent 原样回传到状态消息里。这个对照实验的价值在于把「任务失败」与「平台故障」区分开:TASK_FAILED 带明确退出码是应用层问题,任务长期卡在 STAGING 不动或状态无法上报才是平台层问题——安装验证时用成功任务,排障训练时用这类失败任务。

5.4 冒烟验证清单

最后用四条只读命令完成安装验收(全部实测通过):

$ curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:5050/health
200
$ curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:5051/health
200
$ curl -s http://127.0.0.1:5050/flags | python3 -c "import json,sys; f=json.load(sys.stdin)['flags']; print(f['work_dir'])"
/opt/data/mesos/master
$ curl -s http://127.0.0.1:5050/state | python3 -c "import json,sys; d=json.load(sys.stdin); print(d['version'], len(d['slaves']))"
1.11.0 1

Master 与 Agent 的 /health 均 200、/flags 回读的 work_dir 与启动参数一致、/state 报告的版本与 Agent 数量正确——四项全过即可认为安装与集群状态可信。/flags 的价值在排障:它返回进程实际生效的参数(含默认值),配置文件改没改对,问它比翻文件猜更可靠。

5.5 work_dir 与注册表结构

Master 的 work_dir 不只是个数据目录,它是集群「事实的来源」。实测注册表以 LevelDB 结构持久化在 replicated_log 子目录:

$ ls -la /opt/data/mesos/master/replicated_log/ | awk '{print $5, $9}'
000004.log        1770
CURRENT           16
LOCK
LOG               65
MANIFEST-000002   65

000004.log 是 LevelDB 的预写日志(注册表全部写操作先进这里),MANIFEST 与 CURRENT 记录数据文件布局,LOCK 防止两个 Master 进程共用同一目录——因此「复制 work_dir 到另一台机器起第二个 Master」这类操作必须先停进程。/flags 接口可确认 registry 实现形态(实测 registry=replicated_log)。备份集群注册信息的正确姿势是:停 Master → 整体复制 work_dir → 重启;运行中直接复制会得到不一致快照。

5.6 从最小集群到生产形态

单 Master + 单 Agent 验证通过后,生产化改造清单如下:

  1. 多 Master + ZooKeeper:三台机器各起 mesos-master,统一加 --zk=zk1:2181,zk2:2181,zk3:2181/mesos --quorum=2,Agent 的 --master 改为同一段 zk 串,客户端通过 mesos-resolve 解析当前主;
  2. systemd 托管:为 mesos-master / mesos-agent 编写 unit(示例骨架,按实际路径调整):
[Unit]
Description=Mesos Agent
After=network.target

[Service]
Type=simple
Environment=JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
ExecStart=/usr/local/sbin/mesos-agent --master=zk1:2181,zk2:2181,zk3:2181/mesos \
  --work_dir=/var/lib/mesos --systemd_enable_support=true
Restart=always
RestartSec=5
LimitNOFILE=16384

[Install]
WantedBy=multi-user.target
  1. Agent 资源声明:生产 Agent 用 --resources 显式声明可让渡给任务的资源(如 cpus:12;mem:24576;disk:102400),与系统级守护、监控预留隔开;
  2. 日志与轮转:守护进程日志走 syslog 或重定向文件并配置轮转,任务沙箱日志默认随 work_dir 增长,长生命周期任务建议启用官方 logrotate_container_logger 模块(见 4.3 节模块清单);
  3. 观测接入:把 /metrics/snapshot 接入监控(指标分组解读见介绍篇 5.3 节),5050/5051 探活进拨测。

注意 systemd unit 里 --systemd_enable_support=true 与 5.2 节的手工验证相反:systemd 管理下该层级真实存在,保留默认集成反而正确。

六、卸载与清理

$ cd /opt/build && make uninstall
$ rm -rf /usr/local/include/mesos
$ ldconfig
$ rm -rf /opt/build /opt/src/mesos-1.11.0 /opt/src/mesos-1.11.0.tar.gz
$ rm -rf /opt/data/mesos

make uninstall 依据安装清单删除文件,再删除头文件目录与构建产物即可完全清理。若升级前想保留集群注册信息,备份 /opt/data/mesos/master 的 Registrar 数据后再清理。

卸载是否干净需要验证而不是假设。三步检查:which mesos-master 与 ls /usr/local/sbin | grep mesos 应无输出;ls /usr/local/lib | grep libmesos 应只剩 mesos/modules 目录残留(make uninstall 有时不会级联删除模块目录,手工 rm 掉 /usr/local/lib/mesos 即可);ldconfig -p | grep mesos 应无注册项。注意卸载不会触碰运行中的进程——先停 Master/Agent 再清理,否则正在运行的进程虽然继续存活,但重启后就地失效,属于典型的「半卸载」状态。

七、FAQ 排障实录

以下 14 个问题覆盖「依赖、configure、编译、安装、启动、运行」全周期,全部在 Ubuntu 22.04(gcc 11.4.0、OpenJDK 8)实测复现并解决。排查思路统一为三问:报错出自哪个阶段(第三方组件还是 Mesos 自身)、错误码或信号是什么(127 命令未找到、1 通用错误、9 被 OOM 终止)、当前操作的是哪份产物(/usr/local 安装层还是构建目录中间层)。

7.1 grpc 编译报 gettid 歧义(glibc 2.34 及以上必现)

实测错误(make.log 摘录):

/opt/build/3rdparty/grpc-1.10.0/src/core/lib/gpr/log_linux.cc:42:12:
error: 'long int gettid()' conflicts with a previous declaration
'long int sys_gettid() ...'
error: 'long int gettid()' was declared 'extern' and later 'static' [-fpermissive]

原因:glibc 2.34 起 gettid 成为系统正式函数(unistd.h 提供声明),而 Mesos 1.11 内嵌的 grpc-1.10.0 在 log_linux.cc 中自定义了 static long gettid(void),同名冲突。修复方法:把该文件中的 gettid 重命名为 sys_gettid(函数定义与调用点共两处),并把对应 diff 追加到 Mesos 自带的第三方补丁文件 /opt/src/mesos-1.11.0/3rdparty/grpc-1.10.0.patch,随后删除构建目录中的 grpc-1.10.0 目录与 stamp 文件再继续 make。必须采用「追加到官方补丁文件」的方式,因为 make 会重新解压 grpc 源码,直接改解压出来的文件会在重编时被覆盖。

7.2 gcc 11 下 -Werror 触发大量告警错误

实测两类典型错误:picojson 头文件触发 suggest parentheses around assignment used as truth value [-Werror=parentheses];boost 头文件触发告警链并最终 cc1plus: all warnings being treated as errors。根因是 1.11.0 构建系统默认给编译选项追加 -Werror,而 2020 年后的编译器新增了更多告警类别。解决:configure 增加 --disable-werror(该开关为官方提供)。加过该开关后编译告警依然存在但不再中断。

7.3 需要 Java 吗?--disable-java 后为何仍探测 JDK

Java 绑定与 Python 绑定均可禁用(4.1 节),但 configure 阶段仍会探测 JAVA_HOME(输出 JAVA_JVM_LIBRARY 等检查项)。实测不设 JAVA_HOME 时 configure 会以 Could not find Java installation 类错误中止。因此即使全部禁用,也先安装 openjdk-8-jdk 并导出 JAVA_HOME。

7.4 构建时间与磁盘占用

实测 12 核 + make -j12 全量约 40 分钟;构建目录峰值 6.1 GB,安装完成后构建目录可整体删除。若机器核数少,可以分阶段:先 make -j4 构建第三方库,观察内存占用后再调整并发度。

7.5 归档站点下载慢或中断

archive.apache.org 对所有请求限速(Vary: Slow,Glacial),72 MB 需数分钟;中断后建议删除部分文件重新整包下载并校验,理由见 3.2 节。

7.6 Agent 启动失败:Failed to locate systemd cgroups hierarchy

环境没有 /sys/fs/cgroup/systemd 层级时(非 systemd 托管、或层级被其他驱动接管),Agent 初始化 systemd 支持失败直接退出。解决:启动参数追加 --systemd_enable_support=false(实测验证通过)。若在 systemd 环境中希望启用 cgroups 隔离,保持默认并确保 /sys/fs/cgroup/systemd 可写即可。

7.7 启动报 libmesos-1.11.0.so: cannot open shared object file

make install 后没有执行 ldconfig。执行 ldconfig 后用 ldconfig -p | grep mesos 确认注册(应出现 libmesos-1.11.0.so,库的真实 SONAME 带 1.11.0 后缀,见 4.3 节)即可。也可临时用 LD_LIBRARY_PATH=/usr/local/lib 前缀启动。

7.8 端口冲突:5050/5051 被占用

Master 默认 5050、Agent 默认 5051,可通过 --port/--agent_port 覆盖;排障时用 ss -tlnp 确认占用者。多实例同机共存是常见做法:每个实例独立 --work_dir 即可。

7.9 WebUI 打不开但 /state 正常

Master WebUI 静态文件安装于 /usr/local/share/mesos/webui,若部署时用 DESTDIR 装到了非默认前缀且未迁移目录,会出现 API 正常但页面 404 的情况;把 webui 目录放置到 <prefix>/share/mesos/webui 即可。

7.10 编译产物在哪里?为什么 /opt/build/src/mesos-master 是脚本

libtool 的包装脚本机制:构建目录顶层是包装器,真实 ELF 在同级 .libs/ 目录。日常不必直接使用构建产物,执行 make install 后统一使用 /usr/local 前缀下的安装产物。

7.11 make 中途失败,重跑会从头编译吗

不会全量重来。Mesos 构建以组件为增量单位:第三方库的解压与 patch 有 stamp 文件守护(4.2 节),已完成的组件不会重复处理;Mesos 自身代码按目标文件增量编译。因此 7.1 节修完 grpc 补丁后只需删除 grpc 的目录与 stamp 再 make,其余阶段全部复用。唯一要警惕的是「删除了构建目录里的源码却没删 stamp」,此时 make 认为 stamp 有效而实际文件缺失,会报出找不到头文件的诡异错误——删就成对删。

7.12 怎么验证安装产物完整、二进制确实链接到了新装的库

三步实证:ldd /usr/local/sbin/mesos-master | grep mesos 应解析到 /usr/local/lib/libmesos-1.11.0.so 且无 not found;objdump -p /usr/local/lib/libmesos.so | grep SONAME 应输出 libmesos-1.11.0.so;/usr/local/sbin/mesos-master --version 输出 mesos 1.11.0。三者都过,安装链路即可信。

7.13 改了启动参数不生效,怎么确认进程实际在用什么

问 /flags。它返回进程当前生效的全部参数与默认值,与启动命令逐项对照即可发现「拼错参数名被静默忽略」或「写进了错误的前缀」两类问题。例如怀疑 work_dir 配置错,curl -s http://127.0.0.1:5050/flags | grep -A2 work_dir 直接给出生效值。注意 /flags 是只读快照,改参数必须重启进程后重查。

7.14 Agent 的 work_dir 越来越大,能直接删里面的东西吗

不能整目录乱删。/opt/data/mesos/agent/slaves 下按「AgentID/frameworks/框架ID/executors/执行器/runs/运行UUID」组织(5.3 节实测骨架),已结束任务的 runs 可以按目录删除释放空间,但注册表与 Agent 元数据(work_dir 根下的 meta 子目录等)删除会导致 Agent 注册状态异常。安全做法:任务结束后按框架清理 runs 目录;整体重置则停进程、备份注册表、清空 work_dir 重来。