RaspberryPi
ARM
Docker
raspbian

ARM環境のRaspbianイメージをx86上のDockerで動かす


はじめに

Raspberry Piを深く触っていると、実機上の作業では時間がかかりすぎて耐えられないことはないでしょうか。例えば…


  • Qt等、巨大なライブラリの最新版がどうしても必要となり、実機上でコンパイルしたら終わりそうにない or エラーのモグラ叩き(しかもスペックが貧弱なので、エラーが数時間おきで発生し収束しない)に陥ることが多々あります


    • パワフルなマシン上で、実機と同じ仮想環境を構築してコンパイルしたい

    • クロスコンパイルだと設定が複雑なので、時間は少しかかってもいいから単純にやりたい(Raspbianをやめて、最新のライブラリがあるArch Linuxを使うという手もあります)



  • 実機と同じアーキテクチャ上の仮想環境で、実機より効率よく開発したい

ということで、お手持ちのPC上でARM環境のRaspbianイメージをDockerで動かす手順をまとめました。

qemuのシステムエミュレーションを使うので、ホストPCのスペックと比べたら動作は全体的に遅くなります。

それでも馬力のあるマシンなら実機よりはるかにマシで、また、実機と同じ手順・バイナリが使えるので環境間の差異をあまり気にしなくて済む、というのが大きなメリットです。

本頁は、以下のサイトの手順を簡易にしたものになります

http://blog.guiraudet.com/raspberrypi/2016/03/03/raspbian-image-for-docker.html

また、Dockerの基本的な操作は割愛します。コンテナの起動/ログイン/終了といった手順は別途お調べください。


ざっくりとした手順


  • Dockerをインストール

  • Linux環境を用意 (上記のDocker上でも別マシン上でも良い)

  • Linux環境でRaspbianイメージを取得し、イメージファイルを展開

  • 展開先にqemu-arm-staticを入れる

  • tarで固め、Dockerのホスト環境へ移動

  • Dockerイメージを作成

  • Dockerを起動

なお、筆者が確認した環境ですが、Host環境はmacOS Mojave、Linux環境はDocker上のDebian(多分64bit)、Raspbianは32bit版です。


詳細な手順


Dockerのインストール

割愛します


Linux環境を用意

ここも詳細は割愛しますが、上述のDockerにDebianを入れた前提で記載を進めます。

別環境で行う場合、特権が必要なコマンドは頭にsudoをつけてください。

Dockerで行うときはイメージファイルがマウントできるよう、--privilegedオプションをつけてください。

$ docker pull debian

$ docker run -it debian --privileged
(Debian環境にログイン)
#


Linux環境でRaspbianイメージを取得し、イメージファイルを展開

lite、desktop、fullなdesuktop、なんでもいいです。

コマンド中の日本語は正しいファイル名に置き換えてください(「ダウンロードしたファイル」、「imgファイル」)

(Raspbian Lite)

# wget https://downloads.raspberrypi.org/raspbian_lite_latest
(Raspbian with desktop)
# wget https://downloads.raspberrypi.org/raspbian_latest
(Raspbian with desktop and recommended software)
# wget https://downloads.raspberrypi.org/raspbian_full_latest

(zipを展開)
$ unzip ダウンロードしたファイル

(imgを展開 ※offsetの箇所の解説は追記予定)
# mkdir image
# sudo mount -o loop,offset=$((512*98304)) imgファイル image


展開先にqemu-arm-staticを入れる

# apt-get -y install qemu-user-static

# mv image/etc/ld.so.preload image/etc/ld.so.preload.bak
# cp /usr/bin/qemu-arm-static image/usr/bin


Dockerイメージを作成

いつ基準のものかをファイル名のYYYY-MM-DDにつけておくとあとでわかりやすいと思います。不要な場合は除去してください。

# cd image

# tar cf ../docker-image-YYYY-MM-DD-raspbian-stretch.tar .

何らかの手段でホスト環境に上記tarファイルをコピー

(Linux環境を抜けます)
# exit

(ホスト環境にて)
$ docker import docker-image-YYYY-MM-DD-raspbian-stretch.tar raspbian-x86_64:YYYYMMDD


Dockerを起動

ホスト環境にて実施します。docker run時は必要に応じてオプションをいじってください。下記の例ではポート5901番で起動したVNCに接続可、マウント可にしてあります。

$ docker run -p 5901:5901 --privileged -it raspbian-x86_64:YYYYMMDD /bin/bash

無事起動したら、raspi-configでタイムゾーン等を変更後、いつもの通りapt-get updateapt-get upgradeにて、環境が出来上がります。

ユーザpiで作業したい場合は、以下のようにします。

# su pi

$ cd
(以下、/home/pi下で作業)

また、CPUやメモリをどのくらい割くかはDockerのオプションで指定してください。

CPU8コアメモリ4GBとか、贅沢な環境が手に入ります。


普段の運用

詳細は割愛しますが、以下の繰り返しになります。stopしないと裏でずっと回ってくれます。VNCを併用するのもいいと思います。

$ docker start (コンテナID)

$ docker attach (コンテナID)
(ログイン)
#
(作業)
# exit
(ログアウト)
$ docker stop (コンテナID)