解决ubuntu18.04使用docker编译openwrt卡住不动的问题

这两天由于工作需要,下载编译了最新的openwrt代码,但是编译时遇到了一个奇怪的问题,编着编着卡住不动了。大概到下图位置就一直卡死了,最开始我以为是慢,需要时间下载或执行啥的,结果第二天来还是卡住不动。我才意识到出问题了。

从上面日志可以看出openwrt在编译package/libs/toolchain时出了问题,所以我接下来执行make -j1 V=s package/libs/toolchain/compile编译,发现这个也是这个现象。那么可以定位是编译package/libs/toolchain过程中有问题。我把编译过程丢给deepseek,它也没头绪,回答驴头不对马嘴。

在我没思路的时候,deepseek给了个好建议,就是抓系统调用日志,使用strace追踪系统调用过程,这样就可以把过程中遇到的错误或者问题找到了,至少知道问题出在哪,接着我就使用strace -f -o /tmp/build.log make -j1 V=s package/libs/toolchain/compile重新执行了一遍,然后把抓出来的日志,继续喂给deepseek,让他分析。结果就是不出意外,deepseek还是没头绪。

接着我在编译卡住时,ps看了一下当前执行的进程,发现两个进程很可疑:
一个是/work/staging_dir/host/bin/fakeroot /work/staging_dir/host/bin/bash /work/scripts/ipkg-build -m "" /work/build_dir/target-mipsel_24kc_musl/toolchain/ipkg-mipsel_24kc/libgcc /work/bin/targets/ramips/mt7621/packages;
一个是/work/staging_dir/host/bin/faked。

我继续追踪系统调用strace -f -o /tmp/faked.log /work/staging_dir/host/bin/faked,然后继续把日志喂给deepseek,这种苦力活它比较适合。

但这次却出现了意外,它居然找到问题原因了!!!就是下图!!!

终于有点希望了,紧接着我问小d,我该怎么解决这个问题,它又开始瞎bb了,说了好几个方法都没有效果,试的我都累死了。

在我将要放弃的时候,不出意外的又出现了转机,居然成功了!!!好家伙,这是把我当小日子整啊,心脏都快受不了了。

千言万语总结起来,其实就是使用docker命令的时候,添加参数”--privileged --userns=host“就可以解决,这样就再也不会卡住了。

例如我的执行命令如下:
sudo docker run -it --privileged --userns=host --rm -v /home/test/openwrt:/work ubuntu22.04 /bin/bash

当然到这里问题解决了,你可能想知道到底是为什么,你也可能不想知道。如果不想知道那看到这里可以结束了,想知道的请继续看下去。

问题背景

由于我的电脑是ubuntu18.04,内核版本5.4。当在​​Linux 5.4内核​​上使用Docker容器编译OpenWrt时,遇到编译过程卡住的问题。核心错误表现为:
close_range(0, 2, 0) = -1 EPERM (Operation not permitted)
这个问题在​​内核版本低于5.9​​的环境中特别常见,因为close_range系统调用是在Linux 5.9中引入的。

问题原因分析

1.内核版本限制

close_range系统调用在Linux 5.9+中引入,Linux 5.4内核无法识别该系统调用,内核错误地返回EPERM(操作不允许)而非正确的ENOSYS(功能未实现)。

2. Docker安全机制
默认seccomp配置文件阻止未知系统调用,用户命名空间隔离限制权限,Capabilities机制限制特权操作。

3. fakeroot实现依赖
fakeroot的faked守护进程尝试使用close_range,该调用需要CAP_SYS_ADMIN能力,旧内核上无法降级。

解决方案

--privileged --userns=host
参数作用解释
docker run --privileged --userns=host -it your_image
--privileged 授予所有Linux能力禁用seccomp和AppArmor,允许close_range系统调用,解除安全机制限制。
--userns=host 使用主机用户命名空间,容器root=主机root 绕过用户命名空间隔离,解决UID映射问题。

为什么这个组合有效?
​​解除能力限制​​,授予CAP_SYS_ADMIN能力,允许特权系统调用,启用所有内核功能接口。

​​绕过安全机制​​:
禁用seccomp过滤器(允许所有系统调用)
禁用AppArmor/SELinux限制
​​消除用户命名空间隔离​​:
容器内root用户=主机root用户
避免UID/GID映射问题
直接访问主机内核接口

安全警告

--privileged --userns=host虽然有效,但​​极大降低安全性​​,仅在以下场景使用:
✅ 临时构建环境
✅ 受信任的CI/CD流水线
✅ 隔离的开发环境
​​避免在生产环境使用​​,可能的风险包括:
容器逃逸攻击
主机文件系统被篡改
内核级漏洞利用 
资源滥用(fork炸弹等)

适用场景

本方案适用于:
  • Docker容器中运行fakeroot
  • 旧内核(<5.9)环境
  • OpenWrt编译过程卡住
  • 类似构建工具依赖特权操作
是的,最后的总结是小d,deepseek做的,实在太累了,懒的写了,还是让这苦力干吧
Ubuntu 18.04系统上使用Docker离线部署或运行DeepSeek模型,需要预先下载好模型文件和Docker镜像,然后将其导入到目标环境中。以下是具体的步骤和方法: ### 1. 准备工作 在有网络连接的环境中,首先需要获取DeepSeek模型的Docker镜像和相关文件。可以通过以下命令拉取Docker镜像并保存为tar文件: ```bash docker pull deepseek_model_image:tag # 替换为实际的镜像名称和标签 docker save -o deepseek_model_image.tar deepseek_model_image:tag ``` 同时,需要下载DeepSeek模型的权重文件和其他依赖项,并确保这些文件可以被Docker容器访问。 ### 2. 导入Docker镜像到离线环境 将保存的Docker镜像文件(deepseek_model_image.tar)复制到目标Ubuntu 18.04系统中,然后使用以下命令加载镜像: ```bash docker load -i deepseek_model_image.tar ``` ### 3. 配置Docker容器 在离线环境中,需要确保所有依赖项(如Python库、模型权重等)已经打包并包含在Docker镜像中,或者可以通过本地挂载的方式提供给容器。可以通过编写Dockerfile来构建一个包含所有必要依赖的镜像,或者直接使用已有的镜像并挂载模型文件目录。 ### 4. 运行DeepSeek模型 使用Docker运行DeepSeek模型时,可以通过以下命令启动容器: ```bash docker run -it --rm -v /path/to/model:/model deepseek_model_image:tag ``` 其中,`/path/to/model`是本地存储模型权重文件的路径,`deepseek_model_image:tag`是加载的Docker镜像名称和标签。 ### 5. 验证模型运行 在容器启动后,可以通过执行模型的推理脚本来验证是否成功运行DeepSeek模型。例如: ```bash docker exec -it container_id python /model/inference.py ``` 其中,`container_id`是运行中的容器ID,`inference.py`是模型的推理脚本。 ### 注意事项 - 确保Ubuntu 18.04系统上已经安装了Docker,并且版本兼容。 - 在离线环境中,所有依赖项和模型文件必须提前准备好,并且不能依赖网络下载。 - 如果模型需要GPU支持,需要确保Docker容器能够访问GPU资源,并且安装了相应的驱动和库[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乄江逸尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值