3行まとめ
- Raspbianのイメージファイルからファイルシステムを
tar
ファイルとして抽出する。 -
docker image import
でtar
ファイルをインポートし、Dockerイメージに変換する。 - QEMUを用いてRaspbianのDockerイメージをx86_64環境で起動する。
1. 概要
Raspberry Pi用のLinuxディストリビューションである「Raspbian」には公式Dockerイメージがありません。(非公式イメージであればDocker Hubにいくつかあります)
セキュリティなどの懸念もあり、業務では非公式イメージは使いづらいのが実情です。
そこで、Raspbianのイメージファイル(*.img
)からDockerイメージを作成してみました。また、ARMv7版RaspbianのDockerイメージをx86_64環境で動作させてみました。
2019年9月11日12時55分追記: mt08さんからのコメントによると、Raspbianは公式のルートファイルシステムが別途配布されているとのことです。そのため、「4. ファイルシステムの抽出」の手順は不要です。
2. 環境
今回試した環境は以下の通りです。
- OS: Ubuntu 16.04.5 LTS
- Docker: 18.09.4
host$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.5 LTS"
host$ docker version
Client:
Version: 18.09.4
API version: 1.39
Go version: go1.10.8
Git commit: d14af54
Built: Wed Mar 27 18:34:51 2019
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 18.09.4
API version: 1.39 (minimum version 1.12)
Go version: go1.10.8
Git commit: d14af54
Built: Wed Mar 27 18:01:48 2019
OS/Arch: linux/amd64
Experimental: false
3. 対象イメージ
今回の対象イメージは「Raspbian Stretch Lite」(2019-04-08版)です。
host$ wget https://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2019-04-09/2019-04-08-raspbian-stretch-lite.zip
host$ ls -l 2019-04-08-raspbian-stretch-lite.zip
-rw-rw-r-- 1 yuya yuya 368729233 Apr 8 19:26 2019-04-08-raspbian-stretch-lite.zip
host$ sha256sum 2019-04-08-raspbian-stretch-lite.zip
03ec326d45c6eb6cef848cf9a1d6c7315a9410b49a276a6b28e67a40b11fdfcf 2019-04-08-raspbian-stretch-lite.zip
host$ unzip 2019-04-08-raspbian-stretch-lite.zip
host$ ls -l 2019-04-08-raspbian-stretch-lite.img
-rw-r--r-- 1 yuya yuya 1803550720 Apr 8 11:25 2019-04-08-raspbian-stretch-lite.img
host$ sha256sum 2019-04-08-raspbian-stretch-lite.img
d4e7d2caa051432a3b6f320c44939b9f65fd454d957904d1cb9fc1c1683ed716 2019-04-08-raspbian-stretch-lite.img
4. ファイルシステムの抽出
まず、イメージファイルをマウントし、ファイルシステムを抽出します。
Dockerコンテナ上にイメージファイルをマウントする方法については別記事『Dockerコンテナ上でイメージファイルをマウントする』をご参照ください。
以下、Dockerホスト側のプロンプトをhost$
、Dockerコンテナ内のプロンプトをdocker$
で示します。
host$ docker container run --interactive --tty --rm --privileged \
--volume $(pwd):/workspace \
ubuntu:18.04
docker$ apt-get update && apt-get install --yes --no-install-recommends parted
docker$ parted /workspace/2019-04-08-raspbian-stretch-lite.img unit B print
Model: (file)
Disk /workspace/2019-04-08-raspbian-stretch-lite.img: 1803550720B
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 4194304B 49174015B 44979712B primary fat32 lba
2 50331648B 1803550719B 1753219072B primary ext4
docker$ mkdir --parents /mnt/image
docker$ mount --options loop,offset=50331648 /workspace/2019-04-08-raspbian-stretch-lite.img /mnt/image
docker$ ls -l /mnt/image
total 88
drwxr-xr-x 2 root root 4096 Apr 8 09:51 bin
drwxr-xr-x 2 root root 4096 Apr 8 10:24 boot
drwxr-xr-x 4 root root 4096 Apr 8 09:39 dev
drwxr-xr-x 84 root root 4096 Apr 8 10:25 etc
drwxr-xr-x 3 root root 4096 Apr 8 09:48 home
drwxr-xr-x 16 root root 4096 Apr 8 09:58 lib
drwx------ 2 root root 16384 Apr 8 10:24 lost+found
drwxr-xr-x 2 root root 4096 Apr 8 09:37 media
drwxr-xr-x 2 root root 4096 Apr 8 09:37 mnt
drwxr-xr-x 3 root root 4096 Apr 8 09:48 opt
drwxr-xr-x 2 root root 4096 Feb 17 2019 proc
drwx------ 2 root root 4096 Apr 8 09:37 root
drwxr-xr-x 5 root root 4096 Apr 8 09:49 run
drwxr-xr-x 2 root root 4096 Apr 8 09:59 sbin
drwxr-xr-x 2 root root 4096 Apr 8 09:37 srv
drwxr-xr-x 2 root root 4096 Feb 17 2019 sys
drwxrwxrwt 2 root root 4096 Apr 8 10:25 tmp
drwxr-xr-x 10 root root 4096 Apr 8 09:37 usr
drwxr-xr-x 11 root root 4096 Apr 8 09:37 var
docker$ tar cfv /workspace/2019-04-08-raspbian-stretch-lite.tar -C /mnt/image .
docker$ ls -l /workspace/2019-04-08-raspbian-stretch-lite.tar
-rw-r--r-- 1 root root 856811520 Sep 10 07:38 /workspace/2019-04-08-raspbian-stretch-lite.tar
docker$ tar tfv /workspace/2019-04-08-raspbian-stretch-lite.tar | head
drwxr-xr-x root/root 0 2019-04-08 09:46 ./
drwxr-xr-x root/root 0 2019-04-08 10:24 ./boot/
drwx------ root/root 0 2019-04-08 10:24 ./lost+found/
drwxr-xr-x root/root 0 2019-02-17 15:05 ./proc/
drwxr-xr-x root/root 0 2019-04-08 09:39 ./dev/
crw------- root/tty 4,1 2019-04-08 09:39 ./dev/tty1
crw-rw---- root/audio 14,48 2019-04-08 09:39 ./dev/mixer3
crw-rw---- root/audio 35,131 2019-04-08 09:39 ./dev/smpte3
crw-rw---- root/audio 35,3 2019-04-08 09:39 ./dev/midi3
brw-rw---- root/disk 1,2 2019-04-08 09:38 ./dev/ram2
イメージファイルの内容を2019-04-08-raspbian-stretch-lite.tar
として抽出することができました。
5. Dockerイメージへの変換
続いて、tar
ファイルをDockerイメージに変換(インポート)します。
host$ docker image import 2019-04-08-raspbian-stretch-lite.tar raspbian-stretch-lite:2019-04-08
host$ docker image ls raspbian-stretch-lite
REPOSITORY TAG IMAGE ID CREATED SIZE
raspbian-stretch-lite 2019-04-08 b53519ee6f33 22 seconds ago 828MB
tar
ファイルをDockerイメージとしてインポートすることができました。
6. 異なるCPUアーキテクチャのDockerイメージを実行
上記のDockerイメージはARMv7用のDockerイメージであるため、当然ながらx86_64環境ではそのまま実行できません。
ここではCPUエミュレータである「QEMU」を使うことで、x86_64環境上でARMv7のDockerイメージを動かしてみます。
host$ sudo apt-get update && sudo apt-get install --yes --no-install-recommends qemu-user-static
host$ docker container run --interactive --tty --rm \
--volume /usr/bin/qemu-arm-static:/usr/bin/qemu-arm-static \
raspbian-stretch-lite:2019-04-08 \
/bin/bash
docker$ arch
armv7l
docker$ cat /etc/debian_version
9.8
無事に動作しました。
6.1. エラー例: QEMUを使用しない場合
host$ docker container run --interactive --tty --rm \
raspbian-stretch-lite:2019-04-08 \
/bin/bash
standard_init_linux.go:207: exec user process caused "no such file or directory"
7. 応用: クロスビルド用のルートファイルシステムの作成
上記のDockerイメージを活用することで「Raspbian向けクロスビルド環境のためのルートファイルシステムの作成」なども行うことができます。
OpenCVをインストールしたルートファイルシステムを作成する具体例を以下に示します。
host$ docker container run --interactive --tty \
--volume /usr/bin/qemu-arm-static:/usr/bin/qemu-arm-static \
--name raspbian_cross_build \
raspbian-stretch-lite:2019-04-08 \
/bin/bash
docker$ apt-get update && apt-get install --yes --no-install-recommends libopencv-dev
docker$ rm --recursive --force /var/lib/apt/lists/*
docker$ exit
host$ docker container export raspbian_cross_build > raspbian_cross_build.tar
host$ tar tf raspbian_cross_build.tar | sort | head
bin/
bin/bash
bin/bunzip2
bin/bzcat
bin/bzcmp
bin/bzdiff
bin/bzegrep
bin/bzexe
bin/bzfgrep
bin/bzgrep