Raspberry Pi docker 環境を構築する

これまでPiはマイクロSDということもありdocker導入は躊躇していたのですがマイクロSDからSSDへの換装を機にdockerを導入してみました。

まだ触り始めて2週間の超初心者ですがちょっと試しただけでもdockerの便利さがわかります。話題に上がるのも当然と思います。使いこなすのはやはり相当のスキルが必要そうですが簡単なところから突破していきたいと思います。

開発環境

Raspberry Pi 3 Host
gnome-terminal + geany
dockerには新コマンドと旧コマンドがあるようです。
docker container / image コマンド新旧比較
web上では旧コマンドで書かれているものが多いのですが少し長ったらしくなりますが当サイトのような初心者には新コマンドのほうが理解しやすいと思います。
当サイトではできるだけ新コマンド体系で記述しようと思います。

インストール
なにはともあれHostになるPi3にインストールしないことには使えません。
dockerインストールに方法についてはraspberrypi.orgにあります。
初回のインストールはソースリストと鍵を取得する必要があるのでwww.raspberrypi.orgの方法でインストールしなければいけませんね 訂正します。
$ apt show docker-ce -a してみるとかなり新鮮なものが入るようです。

$ curl -sSL https://get.docker.com | sh
$ sudo usermod -aG docker pi (username)
$ docker -v
Docker version 18.06.1-ce, build e68fc7a

インストール時は18.06.0~ceだったのでがすぐにupdateが入り18.06.1-ceに上がりました。
docker-composeはpipで入れたほうが良さそうです。(まだ使ってないのですが)

$ sudo apt install python-pip
$ sudo pip install docker-compose
$ docker-compose -v
docker-compose version 1.22.0, build f46880f

以上で最低限の開発環境が整いました。

ベースイメージの選択
巷ではalpine linuxが人気のようですが初めて触るdockerにはいくら軽いと言っても初心者には荷が重いですね。
という訳でやはりここは少々慣れているraspbianを探してみます。
見つかったのがここstretchベースのようです。それもかなり新鮮な感じがします。
schachr/raspbian-stretch
自前でbuildする方法も載っていますがpullでいいでしょう。

$ docker pull schachr/raspbian-stretch
$ docker image ls
schachr/raspbian-stretch   latest    edebd95dc401     6 days ago   128MB

テストラン

新しいコンテナを作成実行
$ docker run --name raspbian -it schachr/raspbian-stretch:latest /bin/bash
root@1f0c05e837aa:/# ls
bin  boot  dev	etc  home  lib	media  mnt  opt  proc  root  run  sbin	srv  sys  tmp  usr  var
root@1f0c05e837aa:/# exit
exit
コンテナ一覧の表示
pi@pi3:~ $ docker container ls
CONTAINER ID  IMAGE  COMMAND   CREATED  STATUS  PORTS  NAMES
停止中のコンテナを起動
pi@pi3:~ $ docker container start raspbian
raspbian
pi@pi3:~ $ docker container ls
1f0c05e837aa schachr/raspbian-stretch:latest "/bin/bash" 19 seconds ago  Up 16 seconds raspbian
実行中のコンテナにアタッチ
pi@pi3:~ $ docker container attach raspbian
root@1f0c05e837aa:/# exit
exit
コンテナの削除
pi@pi3:~ % docker container rm raspbian
raspbian

いろいろ試してみるとインストールできないパッケージがあります。ソースリストが不足しているようです。
またこのままではsystemdも使えませんね。
Hostとコンテナ間の共有ディレクトリがほしい。
portを使ってみる。

あなたがする必要があるのは、それを引っ張ってdocker pull schachr/raspbian-stretch:latestこのイメージに基づいてコンテナを作り直すことだけです。

仰せの通りコンテナを作り直す
1.ソースリストはHostのPi3からコピー、設定する
2.pullしたimageには/sbin/initがないので/lib/systemd/systemdを指定
pi@pi3:~ $ ll /sbin/init
lrwxrwxrwx 1 root root 20 6月 14 05:20 /sbin/init -> /lib/systemd/systemd
3.Hostに~/buildを作成、共有ディレクトリにする。コンテナ側は/mntにマウント
4.sshを設定、-p 22:22で接続する

以上から新たにコンテナを作成(–name stretch_lite)

$ docker container run --privileged -d -p 22:22 --name stretch_lite -v /home/pi/build:/mnt schachr/raspbian-stretch /lib/systemd/systemd
4c4d641d1b952855436ed40d0413f54098255a1caf11a4c695e35ec8512add28
$ docker container ls
4c4d641d1b95        schachr/raspbian-stretch   "/lib/systemd/systemd"   About a minute ago   Up About a minute   0.0.0.0:22->22/tcp   stretch_lite

実行中のコンテナの中に入る

$ docker container exec -it stretch_lite /bin/bash
root@4c4d641d1b95:/# df -h
Filesystem                        Size  Used Avail Use% Mounted on
overlay                            29G   14G   15G  48% /
tmpfs                              64M     0   64M   0% /dev
tmpfs                             464M     0  464M   0% /sys/fs/cgroup
/home/pi/build                     30G    7G   23G  22% /mnt
/dev/root                          29G   14G   15G  48% /etc/hosts
shm                                64M     0   64M   0% /dev/shm
tmpfs                             464M  6.1M  458M   2% /run
tmpfs                             5.0M     0  5.0M   0% /run/lock

ソースリストの変更については簡単にできるので書き直しました。(訂正)
こちらを参照してください。
Host(pi3)の/etc/apt/sources.list

deb http://raspbian.raspberrypi.org/raspbian/ stretch main contrib non-free rpi
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
#deb-src http://raspbian.raspberrypi.org/raspbian/ stretch main contrib non-free rpi

Host(pi3)の/etc/apt/sources.list.d/raspi.list

deb http://archive.raspberrypi.org/debian/ stretch main ui
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
#deb-src http://archive.raspberrypi.org/debian/ stretch main ui

imageではviやnanoも使えないのでコピーしたほうが早いです。共有ディレクトリ経由またはdocker cpでコピーします。
sources.listをコピー後1回目のupdateでkeyがないよと言ってくるのでdirmngrをインストール、gpgでkeyを取得します。keyを登録OK後再度update
手順の違いでkeyの取得に失敗した場合は/root/.gnupgを削除再度実行します。
upgradeではlocale関連で文句を言ってきますが取り敢えず問題ないと思います。

4c4d641d1b95:/ # cp /mnt/sources.list /etc/apt
# cp /mnt/raspi.list /etc/apt/sources.list.d
# apt update
# apt -y install dirmngr
# gpg --keyserver pgpkeys.mit.edu --recv-key 82B129927FA3303E
gpg: directory '/root/.gnupg' created
gpg: keybox '/root/.gnupg/pubring.kbx' created
gpg: /root/.gnupg/trustdb.gpg: trustdb created
gpg: key 82B129927FA3303E: public key "Raspberry Pi Archive Signing Key" imported
gpg: no ultimately trusted keys found
gpg: Total number processed: 1
gpg:               imported: 1
# gpg -a --export 82B129927FA3303E | apt-key add -
OK
# apt update && apt -y upgrade

アプリケーション(ツール)のインストール
使いやすいツールなどがあればここでインストールしておきます。

# apt -y install vim lv less dnsutils whois host curl wget sudo

ロケール
localesをインストール後/etc/locale.gen該当箇所のコメントを外してlocale-genを実行

# apt -y install locales
/etc/locale.gen
en_GB.UTF-8 UTF-8
ja_JP.UTF-8 UTF-8
# locale-gen
Generating locales (this might take a while)...
  en_GB.UTF-8... done
  ja_JP.UTF-8... done
Generation complete.

ローカルタイム

# rm /etc/localtime
# ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
# date
2018年  8月 31日 金曜日 11:01:29 JST

ssh server
sshを設定するにあたりuserを作成します。コンテナ内でもuserのファイルを操作することもあるだろうという想定で試してみます。

# adduser pi
ユーザ `pi' を追加しています...
新しいグループ `pi' (1000) を追加しています...
新しいユーザ `pi' (1000) をグループ `pi' として追加しています...
ホームディレクトリ `/home/pi' を作成しています...
`/etc/skel' からファイルをコピーしています...
新しい UNIX パスワードを入力してください:
新しい UNIX パスワードを再入力してください:
passwd: パスワードは正しく更新されました
pi のユーザ情報を変更中
新しい値を入力してください。標準設定値を使うならリターンを押してください
	フルネーム []: 
	部屋番号 []: 
	職場電話番号 []: 
	自宅電話番号 []: 
	その他 []: 
以上で正しいですか? [Y/n]
# apt -y install openssh-server
# systemctl start ssh
# systemctl status ssh
● ssh.service - OpenBSD Secure Shell server
   Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2018-08-31 19:15:37 JST; 4s ago
  Process: 5225 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
 Main PID: 5226 (sshd)
   CGroup: /docker/4c4d641d1b952855436ed40d0413f54098255a1caf11a4c695e35ec8512add28/system.slice/ssh.service
           └─5226 /usr/sbin/sshd -D


ssh接続での読み書きも特に問題なさそうです。

start exec stop

$ docker container start stretch_lite
stretch_lite
$ docker container exec -it stretch_lite /bin/bash
4c4d641d1b95:/ # exit
exit
$ docker container stop stretch_lite
stretch_lite

現在のコンテナからイメージ作成

$ docker container commit stretch_lite stretch_lite-img
sha256:6b75e8a5d6be8583ed48c2ffb47b066f62c3f08f10c9ec15046d73683e27e253
$ docker image ls | grep stretch_lite
stretch_lite-img  latest   6b75e8a5d6be    4 minutes ago   311MB

ファイルサイズは311MBになりました。
通常のraspbian-lite感覚で使うことができます。docker上の制約やないコマンドなどありますが必要なものはインストールすればいいだけでHostのPi3環境を汚すこと無くいろいろ試すことができそうです。

次回はこのイメージを活用してなんかやってみようと思います。