docker 内的 qemu-user-static 某些二进制文件非常慢

docker 内的 qemu-user-static 某些二进制文件非常慢

我目前正在与Armbian 构建系统它使用 docker 内的 chroot 来交叉构建 armbian 映像(在我的情况下,在 amd64 主机上使用 aarch64)。

然而,由于某种原因,当构建脚本apt-key add -在我的机器上执行时,实际上需要花费几个小时,同时不断使用 100% 的单个 CPU 核心。

apt key 的调用方式如下: ,从而产生类似于容器内部的chroot <armbian-rootfs-dir> bash -c 'cat armbian.key | apt-key add -'过程。/usr/bin/qemu-aarch64-static /bin/bash -c cat armbian.key | apt-key add -

在 apt-key (这是一个 shell 脚本)内部,会调用一些二进制文件,这实际上需要那么长时间,例如:

  • 多次调用/usr/bin/apt-config,例如/usr/bin/apt-config shell ARCHIVE_KEYRING_URI APT::Key::Archiv
  • 致电/usr/bin/gpg-conf/usr/bin/gpgconf --kill all准确地说)
  • ps aux可能更多,但我可能错过了一些(在等待时偶尔会看)

我真的很无能,为什么这些调用(最多需要几秒钟)在通过 docker -> chroot -> qemu 执行时需要几个小时才能终止。

我真的不明白是什么让这这么慢。我将非常感谢任何有关如何进一步调试的指示。

编辑:我应该提到的是,当直接在 ubuntu 22.04 VM 上执行时,所讨论的步骤要快得多(在这种情况下,armbian 构建脚本不使用 docker,因为本机支持 Ubuntu 22.04)。

编辑:

我成功地重现了这个问题,如下所示:

docker run --name armbian-test -d --rm ghcr.io/armbian/docker-armbian-build:armbian-ubuntu-jammy-latest bash -c 'while sleep 1; do true; done'
docker exec armbian-test bash -c 'apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends bash git psmisc uuid-runtime bc binfmt-support bison libc6-dev make dpkg-dev gcc ca-certificates ccache cpio debootstrap device-tree-compiler dialog dirmngr dosfstools dwarves flex gawk gnupg gpg imagemagick jq kmod libbison-dev libelf-dev libfdt-dev libfile-fcntllock-perl libmpc-dev libfl-dev liblz4-tool libncurses-dev libssl-dev libusb-1.0-0-dev linux-base locales lsof ncurses-base ncurses-term ntpdate patchutils pkg-config pv qemu-user-static rsync swig u-boot-tools udev uuid-dev zlib1g-dev file tree expect colorized-logs unzip zip pigz xz-utils pbzip2 lzop zstd parted gdisk fdisk aria2 curl wget axel parallel python3-dev python3-distutils python3-setuptools python3-pip python2 python2-dev gcc-x86-64-linux-gnu gcc-aarch64-linux-gnu gcc-arm-linux-gnueabihf gcc-arm-linux-gnueabi gcc-riscv64-linux-gnu debian-archive-keyring libc6-amd64-cross g++-aarch64-linux-gnu g++ btrfs-progs cryptsetup openssh-client f2fs-tools nilfs-tools xfsprogs zerofree qemu-utils qemu-utils libudev-dev libusb-1.0-0-dev dh-autoreconf build-essential gcc-arm-linux-gnueabi gcc-or1k-elf time'
docker exec armbian-test debootstrap --variant=minbase --arch=arm64 bullseye /debootstrap
docker exec armbian-test time chroot /debootstrap /bin/bash -c '/usr/bin/apt-config shell ARCHIVE_KEYRING_URI APT::Key::Archiv'

答案1

我遇到了和你一样的问题。这似乎是一个相当罕见的用例,因为这几乎是谷歌上出现的唯一结果。

/proc不过,我最终确实发现了这个问题,它与安装到 chroot (从 Docker 容器内)有关

在您的示例中,在输入/使用 rootfs 之前,您应该将 Docker 安装/proc到 chroot 中:

mount -t proc /proc <armbian-rootfs-dir>/proc

然后,您将在 chroot 中获得本机加密速度

编辑:这似乎在旧的 Ubuntu 16.04 映像 chroot 上运行良好,但在使用debootstrap.

查看 debootstrap 创建的 chroot 的内容,该proc文件夹似乎是/proc.我的理解是这不应该起作用,事实上,ls /proc从 chroot 内部运行会导致cannot access 'proc': Too many levels of symbolic links

为了解决这个问题(我相信有人会告诉我为什么这是一个坏主意),从 chroot 之外运行:

rm <armbian-rootfs-dir>/proc
mkdir -p <armbian-rootfs-dir>/proc
mount -t proc /proc <armbian-rootfs-dir>/proc

这会删除符号链接并将 chroot 绑定/proc到 Docker 上/proc

还值得注意的是,debootstrap --second-stage似乎会/proc再次卸载,因此当该阶段完成时,您需要重新安装它(从 chroot 外部)(参考:从外部 chroot 访问 /proc

笔记:umount <armbian-rootfs-dir>/proc当您完成 chroot 并希望对文件夹进行映像时,请不要忘记。

相关内容