容器内挂载卷使用Buildroot遇权限拒绝错误,原因是什么?
挂载目录编译Buildroot时sed权限错误分析
相关文件内容
Dockerfile
FROM debian:buster ENV DEBIAN_FRONTEND=noninteractive RUN useradd -u 501 -ms /bin/bash build RUN apt-get clean && apt-get update RUN apt-get install -y \ git \ sudo \ sed \ wget \ cpio \ unzip \ rsync \ bc \ bison \ flex \ libssl-dev \ make \ kmod \ libc6-dev \ libncurses5-dev \ crossbuild-essential-armhf \ crossbuild-essential-arm64 WORKDIR /home/build USER build VOLUME ["/home/build"]
容器运行脚本
# Defaults IMAGE_NAME=${IMAGE_NAME:-"linux_builder"} ARCH=${ARCH:-"arm"} CORES=${CORES:-0} KERNEL=${KERNEL:-"kernel7"} CROSS_COMPILE=${CROSS_COMPILE:-"arm-linux-gnueabihf-"} VOLUME="$(pwd)/fs" # Run builder environment podman run --rm \ --device /dev/fuse \ --cap-add SYS_ADMIN \ --name $IMAGE_NAME \ -v $VOLUME:"/home/build/fs" \ -e ARCH=$ARCH \ -e KERNEL=$KERNEL \ -e CROSS_COMPILE=$CROSS_COMPILE \ -it \ $IMAGE_NAME \ bash $@
错误现象
将Buildroot检出到容器内部/home/build目录时编译正常,但挂载宿主机目录$(pwd)/fs到容器/home/build/fs后编译出现权限错误:
/bin/bash ./libtool --mode=install /usr/bin/install -c pkgconf '/home/build/buildroot/output/host/bin' libtool: install: /usr/bin/install -c pkgconf /home/build/buildroot/output/host/bin/pkgconf make[2]: Leaving directory '/home/build/fs/buildroot/output/build/host-pkgconf-1.6.3' make[1]: Leaving directory '/home/build/fs/buildroot/output/build/host-pkgconf-1.6.3' /usr/bin/install -m 0755 -D package/pkgconf/pkg-config.in /home/build/fs/buildroot/output/host/bin/pkg-config /bin/sed -i -e 's,@STAGING_SUBDIR@,arm-buildroot-linux-gnueabihf/sysroot,g' /home/build/fs/buildroot/output/host/bin/pkg-config /bin/sed: couldn't open temporary file /home/build/fs/buildroot/output/host/bin/sedWes6rs: Permission denied make: *** [package/pkg-generic.mk:300: /home/build/fs/buildroot/output/build/host-pkgconf-1.6.3/.stamp_host_installed] Error 4
即使以root身份运行容器,问题依然存在。
问题原因及解决方法
核心原因
- 挂载目录权限映射不匹配:宿主机目录的UID/GID和容器内用户的UID/GID不一致,导致容器内用户(包括root)无法在挂载目录下创建临时文件。sed的
-i选项需要在目标文件所在目录生成临时文件,无写入权限则触发报错。 - 安全模块限制:宿主机的SELinux或AppArmor可能阻止容器对挂载目录进行写入操作,即使目录权限看起来正常。
解决办法
方法1:匹配挂载目录与容器用户UID
在宿主机执行命令,将挂载目录的所有者改为容器内build用户的UID(501):
sudo chown -R 501:501 $(pwd)/fs
重新运行容器编译即可解决权限问题。
方法2:添加SELinux挂载选项(适配SELinux开启的系统)
修改运行脚本中的挂载参数,添加z或Z选项开放容器访问权限:
-v $VOLUME:"/home/build/fs:z"
z:共享标签,允许容器和宿主机共同访问该目录Z:私有标签,仅允许当前容器访问该目录
方法3:以root身份进入容器调整权限
- 修改Dockerfile,移除
USER build,默认以root用户启动:
WORKDIR /home/build VOLUME ["/home/build"]
- 运行容器后,执行以下命令调整权限并切换到build用户编译:
chown -R build:build /home/build/fs su build # 执行编译命令
内容的提问来源于stack exchange,提问作者fazibear
相关产品推荐
相关产品推荐

