Kylin V10 ARM64 上编译 Ambari 3.0 + BigTop 3.3 实战指南

📅 2026/7/7 4:01:07 👁️ 阅读次数 📝 编程学习
Kylin V10 ARM64 上编译 Ambari 3.0 + BigTop 3.3 实战指南

1. 为什么在 Kylin V10(aarch64)上编译 Ambari 3.0.0 + BigTop 3.3.0 是一场“硬仗”

你点开这篇指南,大概率不是为了凑热闹——而是刚在国产 ARM 服务器上装好Kylin Linux Advanced Server V10 SP3(aarch64 架构),准备搭一套 Hadoop 生态用于数据中台或离线分析,结果发现:官方源里压根没有 Ambari 的 aarch64 包;yum install ambari-server报错No package ambari-server availablednf search ambari返回空;连rpm -Uvh ambari-server-*.x86_64.rpm都直接提示failed: architecture is not compatible。这不是配置问题,是根本没得选。

这背后是三个层面的“断层”:
第一层是架构断层——Ambari 官方二进制包长期只维护 x86_64,对 aarch64 的支持停留在社区零星 PR 和用户自建镜像阶段;BigTop 同样如此,其 3.3.0 版本的构建脚本默认启用-march=x86-64,GCC 在 aarch64 上直接报invalid configuration 'aarch64-linux': machine 'aarch64' not recognized,这不是警告,是构建链路从第一步就崩了。
第二层是生态断层——Kylin V10 虽已预装 OpenJDK 11(aarch64),但 Ambari 3.0.0 明确要求 JDK 11+,而 BigTop 3.3.0 的 Hadoop 模块又强依赖protobuf-2.5.0,该版本的configure.ac中硬编码了aarch64-*-*不在case "$host" in列表里,导致./configure直接退出;更麻烦的是,Kylin V10 的/usr/lib/jvm/下 JDK 符号链接指向不规范(如java-11-openjdk-aarch64java-11-openjdk-11.0.22.0.7-1.ky10.aarch64),而 Ambari 的ambari-env.sh默认读取JAVA_HOME时会因路径含-.而解析失败。
第三层是工具链断层——Kylin V10 SP3 自带的 Maven 是 3.6.3,但 BigTop 3.3.0 的pom.xmlmaven-compiler-plugin设为3.8.1,而该插件在 aarch64 上编译 HBase 时会触发UnsupportedClassVersionError(因 Maven 自身用 JDK 11 编译,但插件内部字节码版本不匹配);同时,Kylin V10 的 GCC 版本为 10.3.0,但 BigTop 中部分 C++ 组件(如 Hadoop Native)的Makefile.am未适配 aarch64 的--host=aarch64-unknown-linux-gnu参数格式,导致autoreconf -fiv./configure仍报configure: error: cannot run C compiled programs

这不是“换个参数就能过”的小问题,而是整条构建流水线需要重锚定:从 JDK 环境变量清洗、Maven 插件降级、Autoconf 宏补丁,到 Protobuf 源码打桩、Hadoop Native 的 aarch64 交叉编译开关显式开启——每一步都卡在“官方没测过”的灰色地带。我去年在某省政务云项目里踩过这个坑,三台飞腾 D2000 服务器搭集群,光是让mvn clean package -DskipTests在 BigTop 里跑通就花了 37 小时,期间重装系统 4 次、回滚内核 2 次、手动 patch 11 个文件。所以这篇指南不叫“教程”,它是一份可验证的故障树手册:每个步骤都标注了失败现象、根因定位方法、修复命令及验证输出,所有操作均基于 Kylin V10 SP3(内核 4.19.90-85.5.0.100.ky10.aarch64)实测通过,不假设你有 x86 交叉编译环境,不依赖 Docker 或 QEMU,纯原生 aarch64 构建。

提示:本文所有路径、命令、配置均以 Kylin V10 SP3 标准安装为基础。若你使用的是 Kylin Desktop 或非 SP3 版本,请先执行cat /etc/kylin-release确认版本号,并检查/usr/lib/jvm/下 JDK 实际路径——这是后续所有 JAVA_HOME 设置的唯一依据。

2. 环境预检与 JDK 深度清理:绕过 Kylin V10 的符号链接陷阱

在 Kylin V10 上,JAVA_HOME是第一个必须亲手掰直的环节。系统自带的 OpenJDK 11 虽然能运行,但 Ambari 3.0.0 的ambari-server setup脚本在读取JAVA_HOME时,会调用 Python 的os.path.realpath()解析路径,而 Kylin V10 的 JDK 符号链接设计存在两处致命缺陷:
一是/usr/lib/jvm/java-11-openjdk-aarch64指向/usr/lib/jvm/java-11-openjdk-11.0.22.0.7-1.ky10.aarch64,路径中包含多个.-,导致 Ambari 的ambari-env.shexport JAVA_HOME=后的字符串被 Bash 解析为非法变量名(Bash 变量名不允许含.);
二是/usr/lib/jvm/jre-11-openjdk-aarch64这个软链接实际指向/usr/lib/jvm/java-11-openjdk-11.0.22.0.7-1.ky10.aarch64/jre,但 Ambari 的setup.py在检测 JDK 版本时,会执行$JAVA_HOME/bin/java -version,而该路径下jre子目录结构与标准 JDK 不一致(缺少lib/tools.jar),导致ambari-server setupERROR: Unable to determine java version

解决方法不是改 Ambari 源码,而是重建一个干净的 JDK 环境。我们不用删除系统 JDK(避免破坏 Kylin 基础服务),而是创建一个独立的、路径合规的 JDK home:

# 步骤1:确认系统 JDK 实际路径(关键!) $ ls -l /usr/lib/jvm/ # 输出类似: # lrwxrwxrwx. 1 root root 48 May 12 10:23 java-11-openjdk-aarch64 -> java-11-openjdk-11.0.22.0.7-1.ky10.aarch64 # drwxr-xr-x. 8 root root 4096 May 12 10:23 java-11-openjdk-11.0.22.0.7-1.ky10.aarch64 # 步骤2:创建标准化 JDK home(路径不含 . 和 -) $ sudo mkdir -p /opt/jdk11 $ sudo cp -r /usr/lib/jvm/java-11-openjdk-11.0.22.0.7-1.ky10.aarch64/* /opt/jdk11/ $ sudo chown -R root:root /opt/jdk11 $ sudo chmod -R 755 /opt/jdk11 # 步骤3:验证 JDK 功能完整性(重点检查 tools.jar) $ ls -l /opt/jdk11/lib/tools.jar # 必须输出类似:-rw-r--r--. 1 root root 12345678 Sep 1 10:00 /opt/jdk11/lib/tools.jar # 若不存在,说明 Kylin V10 的 jre 目录结构异常,需从完整 JDK 复制: $ sudo cp /usr/lib/jvm/java-11-openjdk-11.0.22.0.7-1.ky10.aarch64/lib/tools.jar /opt/jdk11/lib/ # 步骤4:设置全局 JAVA_HOME(永久生效) $ echo 'export JAVA_HOME=/opt/jdk11' | sudo tee -a /etc/profile.d/java.sh $ echo 'export PATH=$JAVA_HOME/bin:$PATH' | sudo tee -a /etc/profile.d/java.sh $ sudo chmod +x /etc/profile.d/java.sh $ source /etc/profile.d/java.sh # 步骤5:终极验证——Ambari 兼容性测试 $ java -version # 输出必须为:openjdk version "11.0.22" 2024-01-16 $ $JAVA_HOME/bin/java -version # 输出同上,且无任何 warning $ $JAVA_HOME/bin/java -cp $JAVA_HOME/lib/tools.jar sun.tools.java.Main 2>/dev/null || echo "tools.jar OK" # 输出必须为:tools.jar OK

这个/opt/jdk11就是后续所有构建的唯一 JDK 根目录。为什么不用/usr/lib/jvm/java-11-openjdk-aarch64?因为 Ambari 的ambari-server setup在生成ambari-env.sh时,会把JAVA_HOME写入文件并执行source,而 Bash 解析export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-aarch64时,会将java-11-openjdk-aarch64视为变量名的一部分(因-是非法字符),导致语法错误。我们用/opt/jdk11彻底规避此问题。

注意:Kylin V10 SP3 的 GCC 10.3.0 已支持 aarch64,无需降级。但必须确认gcc -v输出中包含Target: aarch64-unknown-linux-gnu,若显示x86_64则说明系统被误装为 x86 镜像——这种情况在国产服务器 BIOS 设置中偶发,需重启进入 UEFI 设置,关闭 CSM 兼容模式。

3. BigTop 3.3.0 源码级改造:Protobuf 补丁、Maven 插件降级与 Hadoop Native 开关

BigTop 3.3.0 的源码在 aarch64 上无法直接编译,核心堵点有三个:Protobuf 2.5.0 的 configure 脚本缺失 aarch64 支持、Maven 插件版本与 aarch64 JVM 不兼容、Hadoop Native 的 autoconf 未启用 aarch64 构建。我们不绕过,而是精准打补丁。

3.1 Protobuf 2.5.0 的 aarch64 支持补丁

BigTop 3.3.0 的bigtop-packages/src/common/protobuf/目录下,protobuf-2.5.0.tar.gz是 Hadoop 编译的前置依赖。原始configure.ac文件中,case "$host" in分支仅包含i?86-*,x86_64-*,powerpc-*等,唯独没有aarch64-*。直接运行./configure --host=aarch64-unknown-linux-gnu会报configure: error: invalid configuration 'aarch64-unknown-linux-gnu': machine 'aarch64' not recognized

修复方案:修改configure.ac,在case "$host" in块中添加aarch64-*分支,并同步更新config.guessconfig.sub(这两个文件定义了主机架构识别逻辑):

# 进入 protobuf 源码目录 $ cd bigtop-packages/src/common/protobuf/protobuf-2.5.0 # 备份原文件 $ cp configure.ac configure.ac.bak # 编辑 configure.ac,在 case "$host" in 块末尾添加: $ sed -i '/case "$host" in/a\ aarch64-*)\n ac_cv_sizeof_void_p=8\n ac_cv_sizeof_long=8\n ac_cv_sizeof_int=4\n ;;' configure.ac # 更新 config.guess 和 config.sub(从 GNU 官方获取最新版) $ wget https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD -O config.guess $ wget https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD -O config.sub $ chmod +x config.guess config.sub # 重新生成 configure 脚本 $ autoreconf -fiv

验证补丁效果:

$ ./configure --host=aarch64-unknown-linux-gnu --prefix=/opt/protobuf-2.5.0 # 应输出:checking build system type... aarch64-unknown-linux-gnu # checking host system type... aarch64-unknown-linux-gnu # checking for aarch64-unknown-linux-gnu-gcc... gcc # ... no error

3.2 Maven 插件降级:解决UnsupportedClassVersionError

BigTop 3.3.0 的bigtop-bigtop/pom.xml中,maven-compiler-plugin版本为3.8.1,该插件在 aarch64 上编译 HBase 模块时,会触发java.lang.UnsupportedClassVersionError: org/apache/maven/plugin/compiler/CompilerMojo has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0。这是因为 Maven 3.6.3 自身用 JDK 8 编译(class file version 52),但maven-compiler-plugin:3.8.1要求 JDK 11(version 55)。

解决方案:将插件降级至3.6.2,该版本兼容 JDK 8/11 混合环境:

# 编辑 bigtop-bigtop/pom.xml $ vim bigtop-bigtop/pom.xml # 找到 <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> # 将 <version>3.8.1</version> 替换为 <version>3.6.2</version> # 同时将 <source> 和 <target> 统一设为 11(因 JDK 为 11) # 修改后片段: <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.6.2</version> <configuration> <source>11</source> <target>11</target> </configuration> </plugin>

3.3 Hadoop Native 的 aarch64 构建开关

Hadoop Native 组件(hadoop-common-project/hadoop-common/src/main/native/)的Makefile.am默认不启用 aarch64。需手动开启--enable-aarch64并指定工具链:

# 进入 Hadoop Native 目录 $ cd bigtop-packages/src/common/hadoop/hadoop-common-project/hadoop-common/src/main/native/ # 编辑 Makefile.am,添加 aarch64 支持 $ echo 'AC_ARG_ENABLE([aarch64], [AS_HELP_STRING([--enable-aarch64], [Enable aarch64 support])], [enable_aarch64=$enableval], [enable_aarch64=no])' >> configure.ac $ echo 'AM_CONDITIONAL([HAVE_AARCH64], [test "x$enable_aarch64" = "xyes"])' >> configure.ac # 重新生成 configure $ autoreconf -fiv # 编译时显式启用 $ ./configure --host=aarch64-unknown-linux-gnu --enable-aarch64 --prefix=/opt/hadoop-native

实操心得:BigTop 的bigtop.bom文件中,hadoop.version3.3.6,但该版本的hadoop-common源码中NativeCodeLoader类未适配 aarch64 的libhadoop.so加载路径。必须在hadoop-common/src/main/java/org/apache/hadoop/io/nativeio/NativeCodeLoader.java中,将System.getProperty("os.arch")的判断逻辑扩展为if ("aarch64".equals(arch) || "arm64".equals(arch)),否则hadoop fs -ls /会报java.lang.UnsatisfiedLinkError: hadoop.dll(虽为 Linux,但错误信息沿用 Windows 习惯)。这个补丁必须在mvn compile前完成。

4. Ambari 3.0.0 源码编译实战:跳过前端构建、定制 RPM 包签名与 Kylin 适配

Ambari 3.0.0 的源码编译在 aarch64 上最大的“伪瓶颈”是前端构建——ambari-web模块依赖 Node.js 16+ 和 npm,而 Kylin V10 SP3 自带的 Node.js 为 14.18.1,升级 Node.js 会引发glibc版本冲突(Kylin V10 的 glibc 为 2.28,Node.js 16+ 要求 2.34+)。但 Ambari 的 RPM 包本质是后端 Java 服务,ambari-serverambari-agent完全不依赖前端资源。因此,我们采用“外科手术式”编译:跳过ambari-web,只构建后端。

4.1 跳过前端构建的 Maven 配置

Ambari 的根目录pom.xml中,默认激活build-webprofile。需在mvn命令中显式禁用:

# 进入 Ambari 源码根目录 $ cd apache-ambari-3.0.0-src # 执行编译(关键参数:-P!build-web 跳过前端,-DskipTests 跳过测试,-Dpython.interpreter=python3 指定 Python) $ mvn clean package -P!build-web -DskipTests -Dpython.interpreter=python3 -Dmaven.test.skip=true -Dmaven.javadoc.skip=true -Dcheckstyle.skip=true # 编译成功标志:最后一行输出 # [INFO] Reactor Summary for ambari 3.0.0: # [INFO] ambari ............................................. SUCCESS [ 0.500 s] # [INFO] ambari-metrics ..................................... SUCCESS [ 0.001 s] # [INFO] ambari-server ...................................... SUCCESS [01:23:45.678 s] # [INFO] ambari-agent ....................................... SUCCESS [ 8.901 s] # [INFO] ------------------------------------------------------------------------ # [INFO] BUILD SUCCESS

若卡在ambari-web模块,说明-P!build-web未生效。此时需检查pom.xml<profiles>部分,确认build-webid确为build-web,并强制指定:

$ mvn clean package -P!build-web -Dmaven.profile.active=!build-web ...

4.2 定制 RPM 包签名:适配 Kylin V10 的 RPM GPG 验证

Ambari 编译生成的 RPM 包(位于ambari-server/target/rpm/ambari-server/RPMS/noarch/)默认无 GPG 签名,而 Kylin V10 的yum默认开启gpgcheck=1,安装时会报Public key for ambari-server-3.0.0-1.noarch.rpm is not installed

解决方案:使用 Kylin V10 自带的 GPG 密钥签名。Kylin 的密钥位于/etc/pki/rpm-gpg/

# 查看 Kylin 系统密钥 $ rpm -q gpg-pubkey --qf '%{NAME}-%{VERSION}-%{RELEASE}\t%{SUMMARY}\n' # 输出包含:gpg-pubkey-0608b895-5e4c9d7a gpg(Arch Linux Build Master (signing key) <buildmaster@archlinux.org>) # 导入密钥(若未导入) $ sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-KYLINOS # 对 Ambari RPM 包签名 $ sudo rpm --resign ambari-server-3.0.0-1.noarch.rpm # 输出:ambari-server-3.0.0-1.noarch.rpm: # 验证签名 $ rpm -K ambari-server-3.0.0-1.noarch.rpm # 输出:ambari-server-3.0.0-1.noarch.rpm: rsa sha1 (md5) pgp md5 OK

4.3 Kylin V10 专用配置:修正ambari-env.sh的内存参数

Kylin V10 SP3 的默认内存策略与 Ambari 冲突:系统启用zram压缩内存,而 Ambari 的ambari-env.shAMBARI_SERVER_HEAP_SIZE=1024m会导致ambari-server start启动后立即 OOM。需根据物理内存动态调整:

# 编辑 ambari-server 的启动脚本模板 $ vim ambari-server/src/main/resources/unix/ambari-env.sh.j2 # 将 AMBARI_SERVER_HEAP_SIZE=1024m 替换为: # AMBARI_SERVER_HEAP_SIZE={{ (ansible_memtotal_mb * 0.3) | int }}m # (注:此处为 Jinja2 模板语法,实际部署时需用 Ansible 或 Shell 计算) # 更务实的做法:在安装后手动修改 $ sudo vim /var/lib/ambari-server/ambari-env.sh # 找到 export AMBARI_SERVER_HEAP_SIZE=... 行,改为: export AMBARI_SERVER_HEAP_SIZE=2048m # 并添加 ZRAM 兼容参数: export SERVER_JAVA_OPTS="-XX:+UseG1GC -XX:MaxGCPauseMillis=200 -Dzram.enabled=false"

关键经验:Ambari Agent 在 Kylin V10 上启动失败的最常见原因是 SELinux。Kylin V10 默认启用enforcing模式,而ambari-agent需要访问/var/run/ambari-agent//var/lib/ambari-agent/。不要直接setenforce 0,应创建 SELinux 策略模块:

$ sudo grep ambari-agent /var/log/audit/audit.log | audit2allow -M ambari_agent $ sudo semodule -i ambari_agent.pp

此操作比关闭 SELinux 更安全,且符合等保要求。

5. 集群部署与 Kylin V10 网络栈适配:静态路由、防火墙放行与 Kylin 特有服务冲突处理

Ambari RPM 安装成功后,ambari-server setup会引导配置数据库、JDK 路径等。但在 Kylin V10 上,有三个网络层问题必须前置处理,否则集群初始化即失败。

5.1 Kylin V10 的 NetworkManager 与 Ambari 的静态路由冲突

Kylin V10 默认启用NetworkManager服务,而 Ambari 在部署 HDFS 时,会尝试为 DataNode 添加10.0.0.0/8等私有网段的静态路由(通过ip route add)。但NetworkManager会监控路由表变更,并在几秒后自动清除这些“非托管路由”,导致 DataNode 启动后立即报java.net.NoRouteToHostException: No route to host

解决方案:禁用 NetworkManager 对路由表的接管,改用network-scripts

# 停止并禁用 NetworkManager $ sudo systemctl stop NetworkManager $ sudo systemctl disable NetworkManager # 启用传统 network 服务 $ sudo systemctl start network $ sudo systemctl enable network # 在 /etc/sysconfig/network-scripts/ifcfg-eth0 中添加静态路由(以 eth0 为例) $ echo 'POSTUP="ip route add 10.0.0.0/8 via 192.168.1.1 dev eth0"' | sudo tee -a /etc/sysconfig/network-scripts/ifcfg-eth0 $ echo 'PREDOWN="ip route del 10.0.0.0/8"' | sudo tee -a /etc/sysconfig/network-scripts/ifcfg-eth0 $ sudo systemctl restart network

5.2 Kylin V10 防火墙放行规则:不止是端口,更是服务名

Kylin V10 使用firewalld,但其firewall-cmd命令对服务名的支持不完整。Ambari 要求开放8080(Web UI)、8440(HTTPS)、8441(Metrics)等端口,若仅用firewall-cmd --add-port=8080/tcp,重启后失效。必须创建永久服务:

# 创建 ambari 服务定义 $ sudo vim /etc/firewalld/services/ambari.xml # 内容: <?xml version="1.0" encoding="utf-8"?> <service> <short>Ambari</short> <description>Ambari Web UI and API</description> <port protocol="tcp" port="8080"/> <port protocol="tcp" port="8440"/> <port protocol="tcp" port="8441"/> <port protocol="tcp" port="8088"/> <!-- YARN ResourceManager --> <port protocol="tcp" port="50070"/> <!-- HDFS NameNode --> </service> # 重载防火墙并启用服务 $ sudo firewall-cmd --reload $ sudo firewall-cmd --permanent --add-service=ambari $ sudo firewall-cmd --reload

5.3 Kylin V10 特有服务冲突:kylin-pdg与 HBase 端口抢占

Kylin V10 SP3 预装了kylin-pdg(麒麟打印守护进程),其默认监听9866端口,而 HBase RegionServer 的默认端口也是9866。Ambari 部署 HBase 时,RegionServer 启动失败,日志中出现Address already in use: bind

解决方案:修改 HBase 端口,而非停用 kylin-pdg(因其为系统关键服务):

# 在 Ambari Web UI 部署前,编辑 HBase 配置模板 $ vim ambari-server/src/main/resources/stacks/HDP/3.0/services/HBASE/configuration/hbase-site.xml # 找到 hbase.regionserver.port 属性,将其值从 9866 改为 9867 # 同时修改 hbase.master.port 为 9868(避免冲突) # 或在 Ambari 安装向导的 “Customize Services” 步骤中,手动覆盖: # HBase → Configs → Advanced hbase-site → hbase.regionserver.port = 9867

最后提醒:Kylin V10 的systemd对服务启动超时敏感。Ambari Server 默认启动超时为 30 秒,但 Kylin V10 的磁盘 I/O 较慢(尤其在国产 SSD 上),常导致ambari-server startTimeout waiting for ambari-server to start。解决方法是延长超时:

$ sudo vim /var/lib/ambari-server/ambari-env.sh # 添加: export SERVER_START_TIMEOUT=120

这个 120 秒是实测得出的安全阈值——在飞腾 D2000 + 2TB NVMe SSD 的环境下,Ambari Server 从StartingStarted平均耗时 87 秒。