一部のバイナリでは、docker内のqemu-user-staticが非常に遅いです。

一部のバイナリでは、docker内のqemu-user-staticが非常に遅いです。

私は現在一緒に働いていますArmbian ビルドシステムdocker内のchrootを使用してarmbianイメージをクロスビルドします(私の場合はamd64ホストでaarch64を使用します)。

しかし、何らかの理由で私のコンピュータでビルドスクリプトをapt-key add -実行すると、単一のCPUコアを100%継続的に使用しながら、実際に数時間かかります。

apt キーは次のように呼び出されます。その結果、コンテナの内部と同様のプロセスが発生します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(シェルスクリプト)内では、実際にはそれほど時間がかかるいくつかのバイナリが呼び出されます。たとえば、次のようになります。

  • 何度も呼び出されました/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で直接実行する場合ははるかに高速であることに注意する必要があります(この場合、Ubuntu 22.04はデフォルトでサポートされているため、armbianビルドスクリプトはdockerを使用しません)。

編集する:

次のように問題を正常に再現しました。

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

私はあなたと同じ問題に直面しました。これはGoogleに表示されるほとんど唯一の結果であるため、かなりまれなユースケースのようです。

/proc結局、この問題が見つかりましたが、chroot(Dockerコンテナ内)にインストールすることに関連していました。

あなたの例では、/procrootfsを入力/使用する前にDockerをchrootにインストールする必要があります。

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

これにより、chrootでデフォルトの暗号化速度を取得できます。

編集する:ルートが変更された以前のUbuntu 16.04イメージでは正常に動作しているようですがdebootstrap

debootstrapによって生成されたchrootの内容を見ると、procフォルダは/procls /proccannot 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 が/procDocker にバインドされます。/proc

また、再び削除さdebootstrap --second-stageれるように見えるため、その/proc手順が完了したら(chrootの外側から)再インストールする必要があります(参照:外部chrootから/ procにアクセスする)

メモ:umount <armbian-rootfs-dir>/procchrootingが完了してフォルダイメージを作成したい場合は、この作業を忘れないでください。

関連情報