在docker容器中进行debbootstrap

dbf7pr2w  于 2023-04-11  发布在  Docker
关注(0)|答案(9)|浏览(133)

我的问题是我想在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(更干净)。有没有办法让它工作?
多谢了!

xbp102n0

xbp102n01#

你可以使用debootstrap的fakechroot变体,像这样:

fakechroot fakeroot debootstrap --variant=fakechroot ...

干杯!

6za6bjd0

6za6bjd02#

不,目前不可能。
Issue #1916(涉及在docker build期间运行特权操作)仍然是一个开放的问题。曾经讨论过添加命令行标志和RUNP命令,但这两个都没有实现。

qxgroojn

qxgroojn3#

--cap-add=SYS_ADMIN --security-opt apparmor:unconfined添加到docker run命令对我来说很有用。
参见moby/moby issue 16429

9njqaruj

9njqaruj4#

这仍然不起作用(2018-05-31)。
当前唯一的选项是debootstrap,后跟docker import- Import from a local directory

# mkdir /path/to/target
# debootstrap bionic /path/to/target
# tar -C /path/to/target -c . | docker import - ubuntu:bionic
k2arahey

k2arahey5#

debootstrap版本1.0.107,自Debian 10 Buster(2019年7月)起或在Debian 9 Stretch-Backports中可用,具有原生support for Docker,并允许在不需要特权的情况下构建Debian根映像。

  • Dockerfile
FROM debian:buster-slim AS builder
RUN apt-get -qq update \
&& apt-get -q install --assume-yes debootstrap
ARG MIRROR=http://deb.debian.org/debian
ARG SUITE=sid
RUN debootstrap --variant=minbase "$SUITE" /work "$MIRROR"
RUN chroot /work apt-get -q clean

FROM scratch
COPY --from=builder /work /
CMD ["bash"]
  • docker build -t my-debian .
  • docker build -t my-debian:bullseye --build-arg SUITE=bullseye .
rseugnpd

rseugnpd6#

有一个有趣的解决方案,但它涉及到运行Docker两次。第一次,使用标准的Docker镜像,如ubuntu:latest,仅通过使用--foreign选项运行debootstrap的第一阶段。
debootstrap --foreign bionic /path/to/target
然后,不要让它做任何需要特权的事情,并且通过修改将在第二阶段使用的函数来做任何不需要的事情。

sed -i '/setup_devices ()/a return 0' /path/to/target/debootstrap/functions
sed -i '/setup_proc ()/a return 0' /path/to/target/functions

运行该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

camsedfj

camsedfj7#

这并没有解决在没有设置--privileged的容器中执行chroot的OP要求,但它是一种可能有用的替代方法。
请参阅Docker Moby以了解异构rootfs构建。它创建了一个本地临时目录,并使用debootstrap在其中创建了一个rootfs,这需要sudo。然后它使用

FROM scratch
ADD rootfs.tar.xz /
CMD ["/bin/bash"]

这是在docker镜像中运行预先制作的rootfs的常用方法。一旦镜像构建完成,它就不需要特殊权限。并且它得到了docker devel团队的支持。

flmtquvp

flmtquvp8#

经过无数次的反复尝试,我得到了这个工作(注意,这是一个外来的chroot,即用于不同的客户机架构-对于本机架构,事情可能更简单):

apt-get -y install debootstrap fakechroot fakeroot qemu-user-static binfmt-support
mkdir -p $CROSS_ROOT
fakeroot -s .fakeroot.state debootstrap --variant=buildd --include=fakechroot,fakeroot,build-essential,ca-certificates,debian-archive-keyring,git,sudo --arch=${CROSS_ARCH} --foreign ${CROSS_RELEASE} $CROSS_ROOT $CROSS_MIRROR
mkdir -p $CROSS_ROOT/usr/bin
ln /usr/bin/qemu-*-static $CROSS_ROOT/usr/bin/
fakeroot -i .fakeroot.state -s .fakeroot.state chroot $CROSS_ROOT /debootstrap/debootstrap --second-stage --verbose

上面的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的情况下将拒绝工作)。

cmssoen2

cmssoen29#

简短的回答,没有特权模式,没有办法。
Docker的目标是微服务,并不是虚拟机的替代品。在一个容器中安装多个容器肯定与此不一致。为什么不使用多个Docker容器呢?

相关问题