🤖

Raspberry Piをヘッドレスでセットアップする手順

2021/06/05に公開

Raspberry PI をヘッドレスでセットアップする機会が多くなってきたので、自分用の手順をまとめます。

https://zenn.dev/asataka/scraps/d45c78e7b400b4
https://zenn.dev/asataka/scraps/85a3692a908345

のスクラップの内容をまとめており、今後は本記事を随時更新していきます。

作業環境

macOSから作業する。

asa-taka@tailmoon ~ % sw_vers
ProductName:	macOS
ProductVersion:	11.3.1
BuildVersion:	20E241

対象モデル

以下のモデルに対して Raspbian GNU/Linux 10 (buster) をインストールする。

  • Raspberry Pi 4B
  • Raspberry Pi Zero W
pi@raspberrypi:~ $ cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
NAME="Raspbian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
pi@raspberrypi:~ $ uname -a
Linux raspberrypi 5.10.17+ #1403 Mon Feb 22 11:26:13 GMT 2021 armv6l GNU/Linux

イメージ作成

https://www.raspberrypi.org/software/ の通りRaspberry Pi Imagerで32bit Liteを選んでmicro SDに書き込む。5分ほどで完了しイジェクトされるが追加の設定を行うためSDカードを抜き差ししてもう一度認識させる。

初回起動時用の設定

macOSではディスクは /Volumes にマウントされる。Raspberry Piは初回起動時に /boot を参照してイメージを作成するらしい。初回起動時に無線LANが繋がりSSHが有効になっているようにするため、以下のファイルを追加する。

touch /Volumes/boot/ssh # 空ファイルを作成
vi /Volumes/boot/wpa_supplicant.conf

wpa_supplicant.conf の内容は以下のようにした。私の場合は他のセットアップ済みのRaspberry Piから設定を持ってきてmacOSのKeychainのメモに丸ごと保存している。

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=JP
network={
	ssid="YourSSID"
	psk=xxxxxxxxxxxxxx
}

wpa_supplicant.confの詳細は https://www.raspberrypi.org/documentation/configuration/wireless/wireless-cli.md を参照する。

ここまで設定したらディスクを取り出してRaspberry Piに挿して起動する。

ログイン

初回起動時は何度かOSが再起動を繰り返して4Bなら1分、Zeroなら5分程度でログイン可能になる。wpa_supplicant.conf が正しく設定されていれば無線LANにも自動で繋がり、無事ヘッドレスでSSH可能になるまでのセットアップが完了する。

起動したOSではmDNSサービスである avahi-daemon が自動で起動しているので、同一ネットワークかつmDNSが利用できるホスト上(macOSならそうなっている)であれば .local ドメインでアドレスが解決できる。初期のホスト名は raspberrypi、パスワードとユーザ名は pi:raspberry になっている。

ssh-keygen -R raspberrypi.local # 再セットアップ時用
ssh pi@raspberrypi.local # password: raspberry

ログインできたら成功。

パスワードとホスト名を設定

ログインしてパスワードとホスト名を設定する。

passwd

sudo -i
PINAME=myraspi # ← Your new Raspberry Pi name
echo ${PINAME} > /etc/hostname
sed -i -e "s/raspberrypi/${PINAME}/" /etc/hosts
reboot # 不要かもしれない

これで pi@myraspi.local でログインできるようになるのでmacOSから鍵を登録する。

PINAME=myraspi # ← Your new Raspberry Pi name
KEYFILE=~/.ssh/id_${PINAME}

ssh-keygen -R ${PINAME}.local # 再セットアップ時用

ssh-keygen -t ed25519 -f ${KEYFILE}
ssh-copy-id -i ${KEYFILE} pi@${PINAME}.local
ssh-add -K ${KEYFILE} # 必要であれば
ssh -i ${KEYFILE} pi@${PINAME}.local

これでパスワードなしでログインできるようになる。

パッケージの更新

sudo apt update -y
sudo apt full-upgrade -y

色々入れる

監視系やユーティリティなんかを色々入れていく。以下でマスターノードと言っているのは他のノードを監視させたりする機能を集中させた特別なホスト程度の意味。公式の手順が用意されているものはそれに従い、追加でsystemdの設定を行っている。

Docker

RaspbianはDebianの手順を使えないようなので https://docs.docker.com/engine/install/debian/#install-using-the-convenience-script で入れる。

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user も行う。

sudo groupadd docker
sudo usermod -aG docker $USER # join 'docker' as a supplementary group
newgrp
docker run hello-world

無事通常ユーザで実行できた。手順が整っていてとても良い。

node_exporter

ホストのCPUやディスク容量、ネットワーク通信量、温度などの情報をPrometheusが取得できるようにする。可視化することでハードウェア的なリソースが一気に身近に感じられるようになるのでRaspberry Piを入手したら是非入れてほしい。

sudo -i

# Pi 4B: armv7, Pi Zero: armv6
ARCH=armv7
wget https://github.com/prometheus/node_exporter/releases/download/v1.1.2/node_exporter-1.1.2.linux-${ARCH}.tar.gz
tar xvfz node_exporter-1.1.2.linux-${ARCH}.tar.gz
cp node_exporter-1.1.2.linux-${ARCH}/node_exporter /usr/local/bin
node_exporter --version

cat << EOF > /etc/systemd/system/node_exporter.service
[Unit]
Description=Prometheus Node Exporter
Wants=network-online.target
After=network-online.target

[Service]
User=root
Group=root
Type=simple
ExecStart=/usr/local/bin/node_exporter

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl start node_exporter && systemctl status node_exporter

# 確認してメトリクスが帰ってこれば enable
curl localhost:9100/metrics
systemctl enable node_exporter

Prometheus

マスターノードのみ。prometheus ユーザを作って実行する流儀もあるみたいだけれど、面倒なのでとりあえず root にしている。

# Pi 4B: armv7, Pi Zero: armv6
ARCH=armv7
wget https://github.com/prometheus/prometheus/releases/download/v2.26.0/prometheus-2.26.0.linux-${ARCH}.tar.gz
tar xvfz prometheus-2.26.0.linux-${ARCH}.tar.gz

mkdir /etc/prometheus /var/lib/prometheus

cd prometheus-2.26.0.linux-${ARCH}/
cp prometheus /usr/local/bin/
cp promtool /usr/local/bin
cp -r consoles /etc/prometheus/
cp -r console_libraries/ /etc/prometheus/

cat << EOF > /etc/systemd/system/prometheus.service
[Unit]
Description=Prometheus
Wants=network-online.target
After=network-online.target

[Service]
User=root
Group=root
Type=simple
ExecStart=/usr/local/bin/prometheus \
	--config.file /etc/prometheus/prometheus.yml \
	--storage.tsdb.path /var/lib/prometheus \
	--web.console.templates /etc/prometheus/consoles \
	--web.console.libraries /etc/prometheus/console_libraries

[Install]
WantedBy=multi-user.target
EOF

cat << EOF > /etc/prometheus/prometheus.yml
global:
  scrape_interval: 15s
scrape_configs:
  - job_name: 'prometheus'
    scrape_interval: 5s
    static_configs:
      - targets: ['localhost:9090']
  - job_name: 'node_exporter'
    scrape_interval: 5s
    static_configs:
      - targets: ['localhost:9100']
EOF

systemctl daemon-reload
systemctl start prometheus && systemctl status prometheus
systemctl enable prometheus

ローカルネットワークから http://myraspi.local:9090/ でUIが表示されれば成功。

注意点としてPrometheusはmDNSの .local を解決できないようなので(prometheus#2537)、上記の設定では監視対象を localhost としている。他のホストを名前で監視させるには /etc/hosts に名前を登録しておくか、ローカルネットワークにDNSを立てる必要がある。

mDNSを使っている環境でローカルDNSを立てる場合には .local は使わない方が良いとされているようなので、私の場合は .home でローカルDNSを立てている。

Grafana

マスターノードのみ。PrometheusのUIは素朴なのでGraphanaでよりそれらしくメトリクスを眺められるようにする。https://grafana.com/grafana/download?platform=arm に従いインストールする。

sudo apt-get install -y adduser libfontconfig1
wget https://dl.grafana.com/oss/release/grafana_7.5.7_armhf.deb
sudo dpkg -i grafana_7.5.7_armhf.deb

systemctl daemon-reload
systemctl start grafana-server && systemctl status grafana-server
systemctl enable grafana-server

ローカルネットワークから http://myraspi.local:3000/ でUIが表示されれば成功。

その他

無線LANのマニュアルセットアップ

/boot/wpa_supplicant.conf を作らず、初回起動時に無線LANを有効にしなかった場合のセットアップ手順も書いておく。その場合は wlanrfkill でソフトウェアロックがかかっていることがあるので、rfkill unblock しておく。

rfkill # 表示
rfkill unblock <number>

wpa_passphrase ${YOUR_SSID} $(systemd-ask-password) | grep -v '#' >> /etc/wpa_supplicant/wpa_supplicant.conf
# hidden network の場合は `network={}` の中に scan_ssid=1 を書き加えるといいらしい。

wpa_cli -i wlan0 reconfigure

# 繋がらなかったのでデーモンを再起動したら繋がった
systemctl reload-or-restart wpa_supplicant

wpa_cli -i wlan0 status | grep state
# wpa_state=COMPLETED と出たらOK
ip -br link show wlan0
# wlan0            UP             xx:xx:xx:xx:xx:xx <BROADCAST,MULTICAST,UP,LOWER_UP>

Discussion