Docker buildxでRaspberry PiやJetson用のコンテナをクロスビルド
 Author: 水卜

Docker buildx事始め

Dockerは便利です。

マルチアーキのコンテナはARMプロセッサにも対応し、Raspberry PiやJetson nanoなどのマイコンでも問題なく動きます。

ただ、当然のことながら、macやwindowsで使っているコンテナをそのままラズパイで動かすことはできません。プロセッサが違えば扱う機械語が変わり、コンテナのアーキテクチャが変わります。

ラズパイのコンテナはラズパイと同じプロセッサのマシンでビルドする必要があります。

しかし、ラズパイ上でコンテナをビルドしようとすると途方もない時間がかかります。

少しでも早くビルドするために、ラズパイと同じARMプロセッサのクラウド環境を用意し、そこでビルドするしかありませんでした。

しかしこれからはbuildxがあります。

buildxがあれば、ホストPCがwindowsだろうとmacだろうと、ラズパイで動かすためのコンテナをビルドできます。IoT案件の強い味方です。

前提

Docker19.03から対応しているようなので、Dockerのバージョンをそれ以上にしてください。

ビルド手順

ARM用のコンテナをlocalPCでビルドしてみます。

  1. Docker on Desktopメニューを開く

  2. Settings (macOS の場合は Preferences) > Daemon をクリック

  3. Experimental features チェックを有効化

  4. Apply & Restartをクリック

# 異なるCPUアーキテクチャイメージの実行環境を設定(念の為)
$ docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
# 対応しているプラットフォームを確認
$ docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS  PLATFORMS
default * docker                  
  default default         running linux/amd64, linux/arm64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
# 新規ビルダーを作成
$ docker buildx create --use --name mybuilder
# ビルダーを起動してから状態を出力
$ docker buildx inspect --bootstrap
# ビルダーを確認
$ docker buildx ls
# ARMv8(64)とARMv7用にビルド
$ docker buildx build . -t <dockerアカウント名>/<image名>:<tag> --push --platform linux/arm64,linux/arm/v7

試しに、作成したコンテナをラズパイからpullして動かしてみてください。

$ docker pull <dockerアカウント名>/<image名>:<tag>
$ docker run -it <dockerアカウント名>/<image名>:<tag> bash

Docker Hubを使わずデプロイしたい

Docker Hubをprivateで使いたいけど金がない。そんな時。

buildxの-oオプションで、イメージをそのままtarに吐き出すことができます。

scpで送ってラズパイでloadしましょう。

# ホスト
$ docker buildx build . -t pxosdk:0.1 --platform linux/arm64 -o type=docker,dest=- > myimage.tar
$ scp myimage.tar pi@<host>:<dir>
# ラズパイ
$ docker load < myimage.tar

参考

https://github.com/docker/buildx