基于Docker的ONIE编译环境搭建与常见问题解决指南
stgit补丁栈与HEAD不同步彻底删除源码目录+配合download-clean/download刷新,保证源码和补丁链一致。stgit uninit命令不存在直接,再stg init。多线程编译导致补丁/源码状态混乱开发调试建议单线程编译,遇到异常优先make clean或彻底清理相关目录。Debian 9源不可用推荐Debian 11+国内镜像源,所有依赖和脚本均已适配。源码包/补丁反复失败
基于Docker的ONIE编译环境搭建与常见问题解决指南
1. 简介
本教程介绍如何使用Docker容器快速搭建ONIE(Open Network Install Environment)编译环境。通过Docker,可以在隔离、可复现的环境中完成ONIE镜像的编译,避免主机环境污染和依赖冲突。
2. Docker环境准备
2.1 安装Docker
以Debian/Ubuntu为例:
sudo apt-get update
sudo apt-get install -y docker.io
2.2 配置用户权限(可选)
将当前用户加入docker组,避免每次都用sudo:
sudo adduser $USER docker
需重新登录或执行
su - $USER使权限生效。
3. 构建ONIE编译环境镜像
假设你已在ONIE源码的contrib/build-env目录下,且有Dockerfile文件。
cd ~/src/onie/contrib/build-env
sudo docker build -t debian:build-env .
如需重新构建镜像(Dockerfile有变更):
docker stop onie docker rm onie sudo docker build -t debian:build-env .
4. 挂载主机目录(用于产物输出)
在主机上创建一个目录,供容器内build用户读写,建议权限为777:
mkdir --mode=0777 -p ${HOME}/src
该目录会在容器内映射为 /home/build/src。
5. 启动并进入ONIE编译容器
sudo docker run -it -v ${HOME}/src:/home/build/src --name onie debian:build-env
-it:交互式终端-v:挂载主机目录到容器--name onie:容器命名为onie,便于后续管理
进入容器后,命令提示符类似:
build@xxxxxxx:~$
如意外断开,可用
docker attach onie重新连接。
6. 容器内编译ONIE
6.1 克隆ONIE源码
容器内已提供clone-onie脚本,执行:
./clone-onie
源码会被克隆到 /home/build/src/onie。
6.2 进入build-config目录
cd src/onie/build-config
6.3 编译ONIE镜像
以KVM平台为例:
make MACHINE=kvm_x86_64 all
以Accton平台为例:
make MACHINEROOT=../machine/accton MACHINE=accton_as7816_64x all
具体平台参数请参考ONIE源码的
INSTALL文件或machine目录。
7. 获取编译产物
编译完成后,产物会出现在主机的 ${HOME}/src/onie/build/images 目录下。例如:
ls -l ${HOME}/src/onie/build/images
常见产物包括:
onie-recovery-*.iso恢复镜像onie-updater-*升级器*.vmlinuz内核*.initrdinitrd
8. 常见注意事项与容器管理
- .gitconfig:容器内默认的.gitconfig为虚拟用户信息,正式开发请自行修改为真实信息。
- 用户/组ID:容器内build用户的UID/GID与主机不一致,建议挂载目录设为777,避免权限问题。
- 容器管理:
- 断开后可用
docker attach onie重新连接。 - 停止容器:
docker stop onie - 删除容器:
docker rm onie
- 断开后可用
- 镜像重建:如Dockerfile有变更,需先停止并删除旧容器,再重新build。
9. 参考
10. 常见问题与解决方法
10.1 依赖包缺失导致编译失败
- 表现:编译中报错找不到如
rsync、perl、bc、bison、flex、libssl-dev、libelf-dev、autopoint、gettext等命令或库。 - 解决方法:
在Dockerfile或容器内安装所有必需依赖:apt-get update && apt-get install -y \ build-essential gcc g++ make autoconf automake bison flex \ texinfo libtool libtool-bin gawk libncurses5-dev bc \ dosfstools mtools pkg-config git wget help2man libexpat1-dev \ fakeroot python3 python3-pip python3-dev python3-setuptools \ libssl-dev libelf-dev libpopt-dev uuid-dev cpio unzip \ bsdmainutils curl sudo rsync perl locales autopoint gettext procps特别注意:
rsync、perl、bc、bison、flex、libssl-dev、libelf-dev、autopoint、gettext、make、gcc、g++必须有!
10.2 locale(en_US.UTF-8)缺失导致构建失败
- 表现:日志出现
could not find a UTF8 locale ... please enable en_US.UTF-8,或locale相关报错。 - 解决方法:
apt-get update && apt-get install -y locales echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen locale-gen update-locale LANG=en_US.UTF-8 export LANG=en_US.UTF-8 export LANGUAGE=en_US:en export LC_ALL=en_US.UTF-8检查
locale -a输出应包含en_US.utf8。
10.3 工具链gcc未生成
- 表现:
x86_64-onie-linux-uclibc-gcc等交叉编译器未生成,只有binutils工具。 - 排查思路:
- 查看
build/x-tools/.../build.log,搜索error、fail、gcc等关键字,找到gcc构建失败的具体原因。 - 检查依赖包是否齐全。
- 检查locale是否配置正确。
- 检查基础镜像兼容性。
- 查看
10.4 基础镜像选择建议
- ONIE官方推荐使用Debian 9(stretch)或Debian 10(buster)作为基础镜像,兼容性最佳。
- Debian 11及以上可能因部分包名、工具链、locale等兼容性问题导致构建失败。
- 如遇到莫名其妙的依赖或构建问题,建议先尝试回退基础镜像。
10.5 容器内root权限安装依赖
- build用户无sudo密码时,可用root用户进入容器:
sudo docker exec -it --user root onie /bin/bash # 安装依赖 apt-get update && apt-get install -y rsync ... exit # 再用build用户进入 sudo docker attach onie - 推荐所有依赖都在Dockerfile中一次性安装,避免手动操作。
10.6 git相关问题
- 表现:
fatal: detected dubious ownership in repository ...Author identity unknown ... please tell me who you are.
- 解决方法:
在容器内执行:git config --global --add safe.directory <出错目录> git config --global user.name "build" git config --global user.email "build@example.com"可批量信任所有目录:
git config --global --add safe.directory '*'
10.7 busybox setuid root 提示
- 表现:
You will probably need to make your busybox binary setuid root to ensure all configured applets will work properly.
- 说明:
这是busybox的常规提示,ONIE构建流程会自动处理,无需手动干预。
10.8 Secure Boot/GRUB/GPG签名相关报错
- 表现:
Can't load key from file ... ONIE-shim-key-secret-key.pem或ONIE-shim-key-cert.pem不存在gpg: no default secret key: No secret key,gpg: signing failed: No secret key
- 解决方法:
- 关闭签名:
- 构建时加参数:
make all SECURE_BOOT_ENABLE=no SECURE_GRUB=no GPG_SIGN_ENABLE=no - 或在
Config.*/platform-config等文件中注释/删除ONIE_SIGN_KERNEL、CONFIG_SIGN_KERNEL、ONIE_GPG_SIGN_KERNEL等变量。
- 构建时加参数:
- 如需签名,手动生成自签名密钥:
mkdir -p <key目录> openssl req -new -x509 -newkey rsa:2048 -keyout ONIE-shim-key-secret-key.pem -out ONIE-shim-key-cert.pem -days 3650 -nodes -subj "/CN=ONIE Test Shim Key/" - 安装GPG依赖:如遇
pgrep: not found,需apt-get install -y procps。 - 说明:关闭签名不会影响普通BIOS/非Secure Boot环境下的启动,但在开启UEFI Secure Boot的设备上会导致无法启动。
- 关闭签名:
10.9 多线程编译的风险与建议
- 表现:
- 多线程编译时,错误信息容易被淹没,部分任务失败会导致"半成品"状态,后续编译易遇到git/stgit等二次报错。
- 建议:
- 开发/调试阶段建议单线程编译(不加
-j或-j1)。 - 自动化流水线可用多线程,但每次都
make clean或用全新源码树。 - 遇到异常中断,建议先
make clean或手动清理相关目录。
- 开发/调试阶段建议单线程编译(不加
10.10 stgit/git补丁管理相关清理建议
- 表现:
stg init: master: branch already initialized或补丁应用失败
- 解决方法:
- 执行
make clean或make kernel-clean、make user-clean等目标,或手动删除相关源码目录(如build/kvm_x86_64-r0/kernel/linux-*、build/user/.../grub)。 - 保证每次补丁应用前源码树是"干净"的。
- 执行
10.11 如何彻底刷新源码状态,解决源码"脏"或补丁无法应用问题
-
场景:遇到grub等源码目录"脏"、补丁无法应用、stgit/git状态异常等问题时。
-
推荐操作流程:
- 备份download目录(防止重复下载大文件):
cp -a /home/build/src/onie/build/download /home/build/src/onie/build/download.bak - 清理download状态:
make download-clean - 还原download文件:
cp -a /home/build/src/onie/build/download.bak/* /home/build/src/onie/build/download/ - 刷新download状态:
make download - 删除有问题的源码目录(如grub):
rm -rf /home/build/src/onie/build/user/x86_64-g8.3.0-lnx5.4.86-uClibc-ng-1.0.38/grub - 重新make,此时会自动重新解包源码,彻底解决源码"脏"或补丁应用失败问题。
- 备份download目录(防止重复下载大文件):
-
说明:
- 只删除源码目录不够,必须配合download-clean和download,才能保证依赖链和stamp文件同步刷新。
- 该方法适用于所有ONIE源码包(如grub、kernel等)。
10.12 关于Debian 11环境的说明
- 背景:
- 原版Debian 9官方源
apt update经常报错,导致依赖无法安装。 - 所以使用Debian 11(bullseye)作为基础镜像,并使用国内镜像源(如清华/中科大)。
- 原版Debian 9官方源
- Debian 11下的注意事项:
- 需补充
autopoint、gettext、procps等依赖包。 - 某些老旧ONIE/crosstool-ng源码可能与新系统有兼容性问题,遇到依赖缺失、包名变化、locale等问题请参考本节其他小节的解决办法。
- Dockerfile示例:
FROM debian:11 RUN echo "deb http://mirrors.ustc.edu.cn/debian/ bullseye main contrib non-free" > /etc/apt/sources.list && \ echo "deb http://mirrors.ustc.edu.cn/debian/ bullseye-updates main contrib non-free" >> /etc/apt/sources.list && \ echo "deb http://mirrors.ustc.edu.cn/debian/ bullseye-backports main contrib non-free" >> /etc/apt/sources.list && \ echo "deb http://mirrors.ustc.edu.cn/debian-security bullseye-security main contrib non-free" >> /etc/apt/sources.list # 其余依赖安装同10.1
- 需补充
10.13 其他典型问题与最终有效解决办法总结
- stgit补丁栈与HEAD不同步:
- 彻底删除源码目录+配合download-clean/download刷新,保证源码和补丁链一致。
- stgit uninit命令不存在:
- 直接
rm -rf .git/patches,再stg init。
- 直接
- 多线程编译导致补丁/源码状态混乱:
- 开发调试建议单线程编译,遇到异常优先
make clean或彻底清理相关目录。
- 开发调试建议单线程编译,遇到异常优先
- Debian 9源不可用:
- 推荐Debian 11+国内镜像源,所有依赖和脚本均已适配。
- 源码包/补丁反复失败:
- 按10.11流程彻底刷新源码和download状态。
更多推荐



所有评论(0)