dullwhaleのメモ帳

何度も同じことを調べなくてよいように...

(古い情報)Raspberry Pi 3 Model Bでarm64のdocker-composeを起動するまでの作業ログ

注意

この文章は 2021/08/10 に書いたメモをサルベージしたものである。 現在同じ手順を実行しても失敗する可能性が高い。 必要になったら調べ直せ。

より新しい手順を書いた↓

Raspberry Pi 3 Model BにRaspberry Pi OS 64bitをインストール - dullwhaleのメモ帳

Raspberry Pi 3 Model BにRasberrypi OSをインストールしてdocker-composeをarm64で稼働させるための手順のログ

arm64のRaspberrypi OSを入手する

Raspberry Pi OSの公式イメージはarmhfになっている。 hfはhard floatのことで、浮動小数点演算をハードウェアでサポートしている。 armhfは最低でも32bitであればよいから、32bitイメージになっている。

arm64イメージは未だベータ扱いになっている。 arm64イメージはここで配布されている。

OSのインストール

まずはイメージを焼く。 公式にはRaspberry Pi ImagerというSDカードなどにOSイメージを焼くツールがあるが、インストールを要求するため使わなかった。 代わりにインストールが不要なbalenaEtcherを使った。 今回はポータブルHDDにインストールした。

初回起動までの手順

OSイメージの書き込みに成功したら、USBをPCを一旦抜いて再度挿し、/bootパーティションsshという空のファイルを作る。 sshファイルを作ることで初回起動時にsshデーモンが立ち上がりディスプレイなしでセットアップができる。

また、消費電力削減とセキュリティ向上のため、不要な機能をOFFにする。 /boot/config.txtに以下の設定を追加する。

# 有線接続しかしないから、WifiをOFFにする。
dtoverlay=disable-wifi
# 有線接続しかしないから、bluetoothもOFFにする。
dtoverlay=disable-bt
# オンボードのサウンドカードをOFFにする。
dtparam=audio=off

LAN内で起動したラズパイがIPを取得できるよう、DHCPサーバを立てておく。 DHCP側でリースしたIPアドレスが分かるようにtcpdumpDHCPのパケットをキャプチャしておくと楽。

tcpdump -i INTERFACE port 67 or port 68 -e -n -vvv

起動

LANケーブルを繋ぎ、USBメモリを挿した状態で電源を供給する。 ラズパイの起動は遅いから気長に待つ。 少なくとも1分程度かかった。 しばらく待つとパケットをキャプチャしているDHCPサーバ側でIPのリースが行われたことが分かるから、次のようにしてラズパイにSSHする。

ssh pi@リースされたIPアドレス

初回起動時のパスワードはraspberryである。 sshに成功すると「使う前にraspi-configで初期設定しろ」という旨のメッセージが表示される。 raspi-configを使うとTUIの設定画面が出てくるので各種設定する。

sudo raspi-config

後から変更できるものが多いため、そこまで気にする必要はない。 SSHサーバの有効化だけ忘れずに行う。

IPアドレスの固定化

毎回DHCPでIPが変わってしまうとDNSを設定する必要があるから、IPを固定にする。 以下の設定ファイルを更新する。

vi /etc/dhcpcd.conf

最低限、以下の設定を行う

interface eth0
static ip_address=172.16.0.4/24
static routers=172.16.0.1
static domain_name_servers=172.16.0.1

sudo rebootしてしばらく待ち、固定後のアドレスでsshしてみる。 IPが変わっているためssh時にman-in-the-middle攻撃を受けているかも警告がでる。 ~/.ssh/known_hostsから該当する行を削除すれば接続できる。

セキュリティの確保

ラズパイ公式のドキュメントを参考に必要な設定をおこなう。

piユーザの削除

デフォルトのpiユーザは狙われやすい。 別名のユーザを作成し、piユーザを削除する。 次のコマンドでユーザを作成する。作成する際にパスワードの設定を促される。

sudo adduser USER_NAME

作成したユーザをグループに属させる。やらないとsudoできないなどの問題が発生する。 以下のコマンドで作成したユーザを、piユーザが属していたpiグループ以外のグループに属させる。

groups pi | cut -d' ' -f 4- | tr ' ' , | xargs -I{} sudo usermod -aG {} USER_NAME

次のコマンドで新しいユーザに切り替える。ユーザが変わればここまでのユーザ設定が上手くいっている。

sudo su - USER_NAME

ssh接続している場合、新しいユーザでsshできるよう設定する。 すでに公開鍵のみでログインできよう設定しているなら、~/.ssh/authorized_keysのコピーを忘れずに。

ここからはpiユーザを始末する。 まず、piユーザに紐づいているプロセスをすべてkillする。これはpkillコマンドの-uオプションでできる。

sudo pkill -u pi

piユーザ、piグループ、ホームディレクトリをまとめて削除する。

sudo deluser -remove-home pi

sudo実行時にパスワードを要求する

デフォルトではsudoを実行する際にパスワードの入力を求められない設定になっている。 コマンドインジェクションに対する防御や攻撃者にsshされた場合の対策としてパスワードを要求する設定にしておく。

sudo visudo /etc/sudoers.d/010_pi-nopasswd

以下のように書き換える。

USER_NAME ALL=(ALL) PASSWD: ALL

SSH接続をちゃんと設定する

まずは公開鍵でログインできるようにする。 まだ鍵ペアを作成していなかったらssh-keygenで作る。 作成した公開鍵はssh-copy-idでラズパイへ送ると手間が少ない。

ssh-copy-id -i PUBLIC_KEY_PATH USER_NAME@HOST

ラズパイにsshしてsudo vi /etc/ssh/sshd_configSSHサーバの設定を修正する。 最低限のセキュリティを確保するために以下だけは設定する。

# 公開鍵認証を明示的に有効化
PubkeyAuthentication yes
# rootユーザへ直接sshできないようにする
PermitRootLogin no
#パスワード認証を無効化(必要に応じて)
PasswordAuthentication no

sudo sshd -tして設定に構文エラーなどがないか確認する。 エラーがなければ何も表示されない。

細かい設定

HDMI無効化

SSH接続しかしないから、HDMIを無効化して省電力化を図る。 sudo vi /etc/rc.localを開き、以下の記述をexit 0の前に追記する。

tvservice --off

swapの拡張

ラズパイ3BはRAMが1GBしかない。 今回はストレージに500GBのポータブルHDDを使っていて、容量に余裕があるからswapを8GBまで拡張する。 sudo vi /etc/dphys-swapfile設定ファイルを開き、CONF_SWAPSIZEの値を編集する。 単位はKBである。 8GBにするなら8192と設定する。 CONF_MAXSWAPの値がCONF_SWAPSIZEよりも小さい場合、CONF_MAXSWAPも修正する。 さもないと、swapサイズがCONF_MAXSWAPに制限されてしまう。 編集後は以下のコマンドでswapサービスを再起動する。

sudo /etc/init.d/dphys-swapfile restart

再起動後にfree -hしてswapサイズが変わって入れば成功である。

パッケージのインストール

vimをインストール

sudo apt install vim-nox

nanoをアンインストール

sudo apt purge nano

時刻合わせ

sudo raspi-configでtimezoneをAsia/Tokyoにする。 sudo vim /etc/systemd/timesyncd.confで時刻同期の設定を開き、NTP=の行を編集する。 以下のコマンドで設定を反映する。

sudo systemctl restart systemd-timesyncd.service
sudo systemctl daemon-reload

時刻同期が成功しているか、以下のコマンドで確認できる。

sudo systemctl status systemd-timesyncd.service
date

mDNSを殺す

DNSサーバがあって利用可能ならmDNSは要らない。 結構依存ライブラリがあるからautoremoveもした方が良い。

sudo apt purge avahi-daemon
sudo apt autoremove

不要なサービスを停止する

  • オーディオを使わないから、関連するデーモンも不要(alsa-utilsパッケージ)
  • Wi-Fiを使わないから関連するデーモンも不要(wpasupplicantパッケージ)
sudo apt purge alsa-utils wpasupplicant
sudo apt autoremove

ヘッドレスで運用してUSBキーボードを直接挿さないなら

sudo systemctl disable keyboard-setup.service

docker-composeを使えるようにする

dockerのインストール

docker公式のインストール手順に従う。

dockerコマンドをsudoなしで使えるようにする。 公式のインストール後の手順に従って、ユーザをdockerグループに属させる。

透過HTTPSプロキシのバイパス設定

もし、LAN内に透過HTTPSプロキシを立てていたら、以下のドメインへのリクエストはバイパスするよう、設定する。

registry-1.docker.io
auth.docker.io
production.cloudflare.docker.com

docker-composeのインストール

aarch64(arm64)用のビルド済みバイナリが用意されていないようだ。 docker公式のドキュメントに従うと失敗する。 aptでインストールする。

sudo apt install docker-compose

依存パッケージも自動でインストールしてくれるから、pipでインストールする方法より簡単だ。

その他のメモ

インストール先のUSBメモリは古すぎないものをつかう。 4 GBの古いUSBメモリにインストールしたら、ラズパイのブートに失敗し、奇妙な動作をした。 恐らく、USBメモリのチップに対するドライバがインストールされていないのだろう。