Edited at

QEMUのユーザーモードをDockerコンテナ上で使う

More than 3 years have passed since last update.

QEMUのユーザーモードをDockerコンテナ上で使おうとした際に発生した問題のメモ。


環境


  • Debian wheezy on Docker


QEMUインストール時に発生するエラー

バイナリで提供されているユーザーモードQEMUをインストールする。このパッケージは、インストール時にbinfmt(ネイティブとは異なるアーキテクチャ向けのバイナリをQEMU経由で実行するために必要)の設定を行ってくれる。しかしDockerコンテナ上では、その際に行われるmountコマンドの実行がエラー終了する。

(docker host)$ docker run -it <image> /bin/bash

(docker container)$ apt-get install -y qemu-user-static
...
mount: permission denied
update-binfmts: warning: Couldn't mount the binfmt_misc filesystem on /proc/sys/fs/binfmt_misc.

# 手動で実行しようとしてもダメ
(docker container)$ mount -t binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc
mount: permission denied

(ref.) binfmtについて

この後、Debianの公式ドキュメントに書いてある手順でarmの実行環境を作ろうとした際、binfmtの設定が行われていないことが原因でエラーが発生した。


docker run時に特権を与える

docker run時に--privilegedオプションを与えることで、通常は禁止されている操作を実行する権限が得られる。

(docker host)$ docker run -it --privileged <image> /bin/bash

(docker container)$ apt-get install -y qemu-user-static
...
# binfmtの設定に必要なmountが既に実行されている。
(docker container)$ mount -t binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc
mount: binfmt_misc already mounted or /proc/sys/fs/binfmt_misc busy
mount: according to mtab, binfmt_misc is already mounted on /proc/sys/fs/binfmt_misc

(ref.) http://www.tsugihagi.net/entry/2014/10/05/083120


(おまけ)

元々armの実行環境としてQEMUを使いたかったため、それが問題なく動作することを確認する。

実行環境の作成はDebianの公式ドキュメントの手順に従った。

(docker container)$ debootstrap --foreign --no-check-gpg --arch=armel wheezy /root/workspace/arm_env

# staticリンク済みのqemuコマンドをarm実行環境にコピー
(docker container)$ cp /usr/bin/qemu-arm-static /root/workspace/arm_env/usr/bin/

# armバイナリであることを確認
(docker container)$ file /root/workspace/arm_env/bin/ls
/root/workspace/arm_env/bin/ls: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, for GNU/Linux 2.6.26, BuildID[sha1]=bc7dc95b8916aca9a598d8328ef6eae2165ede8f, stripped

# amd64バイナリはこんな感じ
(docker container)$ file /bin/bash
/bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.26, BuildID[sha1]=05e0f155082725dfdc56c4d4cedcc7c2536500a1, stripped

# chrootが問題なく成功する
(docker container)$ DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true LC_ALL=C LANGUAGE=C LANG=C chroot /root/workspace/arm_env /bin/ls .
bin dev home media opt root sbin srv tmp var
boot etc lib mnt proc run selinux sys usr