我的问题是我想在docker容器中构建一个chroot环境。问题是debootstrap无法运行,因为它无法在chroot中挂载proc:W: Failure trying to run: chroot /var/chroot mount -t proc proc /proc
(in问题的日志结果是:mount: permission denied
)
如果我run --privileged
容器,它(当然)工作...我真的真的真的很想在Dockerfile中卸载chroot(更干净)。有没有办法让它工作?
多谢了!
9条答案
按热度按时间xbp102n01#
你可以使用debootstrap的fakechroot变体,像这样:
干杯!
6za6bjd02#
不,目前不可能。
Issue #1916(涉及在
docker build
期间运行特权操作)仍然是一个开放的问题。曾经讨论过添加命令行标志和RUNP
命令,但这两个都没有实现。qxgroojn3#
将
--cap-add=SYS_ADMIN --security-opt apparmor:unconfined
添加到docker run
命令对我来说很有用。参见moby/moby issue 16429
9njqaruj4#
这仍然不起作用(2018-05-31)。
当前唯一的选项是
debootstrap
,后跟docker import
- Import from a local directoryk2arahey5#
debootstrap
版本1.0.107
,自Debian 10 Buster(2019年7月)起或在Debian 9 Stretch-Backports中可用,具有原生support for Docker,并允许在不需要特权的情况下构建Debian根映像。Dockerfile
:docker build -t my-debian .
docker build -t my-debian:bullseye --build-arg SUITE=bullseye .
rseugnpd6#
有一个有趣的解决方案,但它涉及到运行Docker两次。第一次,使用标准的Docker镜像,如
ubuntu:latest
,仅通过使用--foreign
选项运行debootstrap的第一阶段。debootstrap --foreign bionic /path/to/target
然后,不要让它做任何需要特权的事情,并且通过修改将在第二阶段使用的函数来做任何不需要的事情。
运行该docker的最后一步是让docker执行将其自身tar到作为卷包含的目录。
tar --exclude='dev/*' -cvf /guestpath/to/volume/rootfs.tar -C /path/to/target .
好了,现在准备第二次运行。首先将tar文件作为docker镜像加载。
cat /hostpath/to/volume/rootfs.tar | docker import - my_image:latest
然后,使用
FROM my_image:latest
运行docker并运行第二个debootstrap阶段。/debootstrap/debootstrap --second-stage
这可能有点迟钝,但它确实可以在不需要
--priveledged
的情况下工作。您可以通过运行第二个docker容器来有效地取代运行chroot
。camsedfj7#
这并没有解决在没有设置
--privileged
的容器中执行chroot
的OP要求,但它是一种可能有用的替代方法。请参阅Docker Moby以了解异构rootfs构建。它创建了一个本地临时目录,并使用
debootstrap
在其中创建了一个rootfs,这需要sudo。然后它使用这是在docker镜像中运行预先制作的rootfs的常用方法。一旦镜像构建完成,它就不需要特殊权限。并且它得到了docker devel团队的支持。
flmtquvp8#
经过无数次的反复尝试,我得到了这个工作(注意,这是一个外来的chroot,即用于不同的客户机架构-对于本机架构,事情可能更简单):
上面的
fakechroot
包是以前测试的剩余部分,这里可能不需要。唯一的限制是,一旦chroot设置好,你可能无法绑定挂载
/proc
和/sys
。任何需要这些目录之一的东西都可能无法在chroot中工作。这是在GitLab CI runner(据我所知,它以非特权模式运行)和Debian buster上测试的。(Github Actions runner似乎限制较少-我将此设置从GHA移植到GL,并进行了一些调整。)
主要外卖:
fakechroot
不需要(在非特权Docker容器上可以轻松使用chroot
),但fakeroot
是-因为这可以防止debootstrap
在尝试挂载/sys
或/proc
时遇到权限错误。因为我们没有使用fakeroot
,所以--variant
可以是标准容器之一(不是fakechroot
,因为这个变体在没有fakechroot
的情况下将拒绝工作)。cmssoen29#
简短的回答,没有特权模式,没有办法。
Docker的目标是微服务,并不是虚拟机的替代品。在一个容器中安装多个容器肯定与此不一致。为什么不使用多个Docker容器呢?