Ubuntu Weekly Recipe

第777回Raspberry Pi Zero 2 WにUbuntuサーバーをインストール

世界的なパンデミックと前後して発生した「半導体不足」もようやく出口が見えてきました。まだまだ足りない状態でありますが、⁠全然ない」という状況は脱しつつあるようです。これは教育向けからホビー用途・IoT・産業用に至るまで幅広く使われるようになったRaspberry Piについても同じで、一時期ほとんど手に入らない状態ではありました。しかしながら最近は、モデルによっては普通にもしくは運が良ければ購入できる状態になっています。

今回はリリース後もなかなか入手できない状態が続いていた、Raspberry Pi Zero 2 WにUbuntuをインストールしてみましょう。

図1 高性能でフットプリントが小さいRaspberry Pi Zero 2 W
図1

Wi-Fi/BTに対応しUbuntuも使えるRaspberry Pi Zero 2 W

Raspberry Piには様々なモデルが存在します。そのうちいわゆるPi Zeroと呼ばれるRaspberry Pi Zeroシリーズは、よくRaspberry Piとして紹介されるModel Bに比べると、三分の一近いサイズになっており[1]、消費電力も小さく、低価格であるため、有線LANやUSBのコネクタが不要な用途において非常に重宝されるデバイスです。

しかしながら従来のZeroはSoCとして初代Raspberry PiとBroadcom BCM2835を採用していました、これはArmv6世代のCPUが使われています。それに対してUbuntuのリポジトリで提供されるArm向けバイナリは、Armv7-A以降のCPUしか想定しておらず、Zeroの上でUbuntuを動かすことは叶わなかったのです[2]

そんな中で2021年に登場したのがRaspberry Pi Zero 2 Wです(以下、Zero2とします⁠⁠。これは次のような機能を持っています。

  • SoC:RP3A0/BCM2710A1
  • CPU:Cortex-A53(1GHz x 4コア:Armv8-A)
  • GPU:VideoCore IV
  • DRAM:512MB
  • Wi-Fi:802.11 b/g/n(2.4GHz)
  • Bluetooth:4.2 BLE
  • ディスプレイ:Mini HDMI
  • 給電:USB MicroB or GPIO
  • USB:USB 2.0 MicroB(OTG)
  • カメラ:MIPI CSI-2
  • ストレージ:microSDHC
図2 Zero2のSoC等が実装されている面
図2
図3 Zero2のロゴやテストポイントがある面
図3

CPUが1コアから4コアに増え、さらにArmv7-A世代であり、Raspberry Pi 3系列と同じCortex-A53となりました。これによりUbuntuのバイナリもそのまま動くようになっています。サイズやコネクタに関しては既存のZeroシリーズとなるべく同じになっており、結果的にZero向けのケース類はほぼそのまま使えます。純粋にCPUが増強された(負荷をかけたときの消費電力が増えた)と考えれば良いでしょう。

ちなみにWi-Fi/Bluetoothについては、リリース後の2022年ぐらいに電波法に基づいた認証を取得しているため、国内の正規代理店から購入すれば問題ありません。手元にあるZero2だと「技適マーク」が袋にのみ印刷されていたため、そちらも合わせて保管しておきましょう。

いずれにせよ人気のZeroシリーズでもUbuntuが動くようになったわけなのですが、冒頭にお伝えした「半導体不足」が直撃します。とても魅力的なデバイスにも関わらず、ほぼ入手できない状況が続いていたのです。幸い昨年末から今年にかけて少し改善し、現在ではタイミングが良ければ買えるようになっています。

そろそろ国内でもZero2で遊ぶ人がどんどん増えてきたようなので、今回はあらためてUbuntuをインストールする方法を紹介します。

Zero2にUbuntuをインストールするためには

Raspberry PiにUbuntuをインストールする方法はいくつかありますが、一番かんたんな方法はUbuntuが公式に提供するイメージを使用する方法です。Ubuntu公式のRaspberry Pi向けイメージとしては次のように8種類のイメージが存在します。

  • Ubuntu 22.04 LTS Desktop(64ビット)
  • Ubuntu 23.04 Desktop(64ビット)
  • Ubuntu 22.04 LTS Server(64ビット)
  • Ubuntu 22.04 LTS Server(32ビット)
  • Ubuntu 23.04 Server(64ビット)
  • Ubuntu 23.04 Server(32ビット)
  • Ubuntu Core(64ビット)
  • Ubuntu Core(32ビット)

ざっくり分類するとデスクトップ版かサーバ版かLTSか通常リリースか64ビット/arm64か32ビット/armhfかUbuntuかUbuntu Coreかにわかれます。

Zero2の場合「デスクトップ版」を動かすのはDRAMサイズやUSBコネクタの状況を考えると、あまり向いていません。もちろんいろいろ工夫すれば動かないこともないですが、そこまでするならRaspberry Pi 3や4を使うことをおすすめします。実際Ubuntuのデスクトップ版イメージも、Zero向けの設定が入っていません。またデスクトップ版は64ビットのみを提供しています。

LTSか通常リリースかは好みがわかれるところです。サーバーとして運用するのであればLTSが好ましいのですが、新しいハードウェアでいろいろなHATを接続したりツールを使ってみたりするなら通常リリースにしておくのもひとつの手でしょう。

同様に64ビットか32ビットかも、使い方次第でしょう。64ビットにするとCPUの機能を最大限活用できますが、そもそもZero2はDRAMが512MiBなのでそこまでメリットが得られるわけでもありません。64ビットにすることで各バイナリサイズ(フットプリント)は大きくなってしまい、ストレージが原則microSDと「遅い」デバイスであるため、プログラムのロード時間が長くなるという問題もあります。

Ubuntu Coreに関しては、IoTデバイスとして大量運用・長期運用を視野にメンテナンスコストを減らしたいといった用途でなければ、選ぶ必要はありません。⁠とりあえずUbuntuを動かしてみる」のであれば、通常のUbuntuをおすすめします。

今回は他のRaspberry Piと合わせて「Ubuntu 22.04 LTS Server(64ビット⁠⁠」を選択して説明しますが、基本的にUbuntu Coreを除いて手順は同じです。

これらのイメージは、いずれもUbuntuのサイトでダウンロード可能です。しかしながら第624回のRaspberry Pi 4にデスクトップ版Ubuntuをインストールでも紹介したように、 Raspberry Piの公式イメージ書き込みツールであるRaspberry Pi Imagerからも、これらのイメージをダウンロード&インストール可能ですので、そちらを使うなら手動でダウンロードする必要はないでしょう。

ちなみに最近のRaspberry PiはUSBブート・ネットワークブートにも対応しています。しかしながらPi Zero 2の場合はUSBはMicroBのOTGコネクタですし、ネットワークはWi-Fiのみです。よってもしmicroSDカード以外から起動したいなら、HATを繋ぐなどしてポートの拡張を検討したほうがいいでしょう。今回は単純にmicroSDから起動します。

そこでZero2を使う上で必要なハードウェアをまとめておきましょう。

  • Raspberry Pi Zero 2 W
  • USB MicroBの充電ケーブル
  • microSDカード(4GiB以上)
  • USB電源:5V2Aぐらいに対応したものであればOK
  • 802.11 b/g/n(2.4GHz)に対応したWi-Fiアクセスポイント
  • Mini HDMIケーブル(ディスプレイ用)
  • HDMIディスプレイ
  • USB MicroB - USB-A変換コネクター(キーボード用)
  • USBキーボード

後半のディスプレイとキーボードに関しては、なくてもインストールは可能ではあるのですが、用意しておくと何かトラブルがあったときに便利です。前世代のZeroで使っていたものを流用できます。

Ubuntuをインストールする

さて実際にインストール手順を紹介しましょう。今回はmicroSDカードからのブートを行います。よってまず最初にUbuntuのイメージをmicroSDカードに書き込む必要があります。今回はRaspberry Pi Imagerを使用しましょう。これはsnapパッケージから次の手順でインストールできます。

$ sudo snap install rpi-imager

あとは「raspberry」とか「imager」で検索して、インストールしたアプリケーションを起動しましょう。ここからは画面の指示に従って進めていくだけです。

図4 Raspberry Pi Imagerの起動画面
図4
図5 ⁠OSを選ぶ」から「Other general-purpose OS」を選択
図5
図6 ⁠Ubuntu」を選択
図6
図7 ⁠Ubuntu Server 22.04.3 LTS (64-bit)」かそれに類いするものを選択
図7

OSの準備が整ったら次は書き込み先のストレージです。Raspberry Pi Imagerを起動しているマシンに、microSDカードを接続した上で「ストレージを選ぶ」ボタンを押してください。該当するストレージが選択するはずですので、それを選びます。安全のためにシステムがインストールされているストレージは表示されません。もしPCのSDカードスロットが表示されない場合は、microSDカードスロットが付いたUSBデバイスを接続してみてください。一般的にそのタイプのデバイスはUSBマスストレージとしてmicroSDカードが表示されるはずです。

図8 イメージを書き込む適切なストレージを慎重に選ぼう
図8

なお、イメージを書き込むとmicroSDカードの中身はすべて消えてしまう点に注意しましょう。

今回はさらにもうワンポイント必要です。現在のRaspberry Pi Imagerは画面の右下に歯車アイコンが表示されています。これをクリックすると、インストール後の自動設定ができるようになっているのです。アカウントだけでなく、Wi-Fiの設定なども行いavahi-daemonがインストールされるため、ディスプレイやキーボードを繋ぐ必要もなく、インストール後のシステムにログインできます。早速設定してみましょう。

図9 ⁠詳細な設定」ダイアログではインストール後の様々な設定が行える
図9

これはUbuntu的にはcloud-initを利用して、上記の設定を行うというものです。具体的な設定内容について説明しましょう。

ホスト名はチェックマークを入れておくと、avahi-daemonをインストールし、インストール完了後に外部から「ホスト名.local」でアクセスできるようになります。ただし「ホスト名.local」を解決するためにはクライアント側にもavahi関連のパッケージのインストールが必要です。デスクトップ版のUbuntuなら最初からインストールされていますが、サーバー版の場合は「avahi-daemon」パッケージ等をインストールしておくと良いでしょう。

SSHについては、サーバー版のUbuntuにリモートログインするなら必須です。パスワード認証を選んだ場合は、初回ログイン後に~/.ssh/authorized_keysを設定して公開鍵ログインできるようにしておきましょう。GitHubなどに公開鍵を登録しているなら、ssh-import-id gh:GitHubのアカウント名がおすすめです。公開鍵認証を確認した後にパスワード認証を無効化したいのであれば、/etc/ssh/sshd_config.d/50-cloud-init.confを削除して、sudo systemctl reload ssh.serviceしておくと良いでしょう。

Zero2の場合はメインのネットワーク接続がWi-Fiになってしまいます。よってコンソールなしで設定したいなら、Wi-Fiの設定は必須です。SSIDやパスワードは/etc/netplan/50-cloud-init.yamlに保存されます。

ロケール設定についてはタイムゾーンだけでも設定しておくと良いでしょう。キーボードに関しては、Zero2の場合は直接キーボードを繋ぐ機会が少ないため未設定でもそこまで問題はありません。ちなみにいわゆるLinuxにおける「ロケール」C.UTF-8のままです。日本語ロケールにしたい場合は、インストール後にログインして次のように実行してください。

$ sudo locale-gen ja_JP.UTF-8
$ sudo update-locale LANG=ja_JP.UTF-8

ただし、Zero2をUbuntu端末として「普段使い」することはあまりないでしょうから、C.UTF-8のままでも問題ないでしょう。

ここまでの設定が完了したら、ようやく「書き込む」ボタンを押せます。押した後は完了するまでしばらくかかるので待っていてください。書き込み完了のダイアログが表示されたら、microSDカードを取り外して、Zero2に接続しましょう。あとはコネクタに向かって右側のUSB MicroBコネクタに、充電ケーブルを接続するだけです。緑色のLEDが少し点滅したらインストール開始となります。

インストール完了までしばらく待ってください。手元のZero2の実測値(下記)だと起動してからインストール(という名前の各種設定)が完了するまでに、15分以上必要でした。消費電力も大きくありませんし、しばらく放置して別の作業をすることをおすすめします。

$ journalctl |grep -E -C1 "Booting Linux|Cloud-init.*finished|Clock change"
Aug 08 00:34:33 ubuntu kernel: Booting Linux on physical CPU 0x0000000000 [0x410fd034]
Aug 08 00:34:33 ubuntu kernel: Linux version 5.15.0-1034-raspi (buildd@bos01-arm64-032) (gcc (Ubuntu 11.3.0-1ubuntu1~22.04.1) 11.3.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #37-Ubuntu SMP PREEMPT Mon Jul 17 10:02:14 UTC 2023 (Ubuntu 5.15.0-1034.37-raspi 5.15.99)
--
Aug 08 00:37:05 zero2 systemd[1]: Starting Wait until snapd is fully seeded...
Aug 27 18:01:40 zero2 systemd-resolved[705]: Clock change detected. Flushing caches.
Aug 27 18:01:40 zero2 systemd-timesyncd[530]: Initial synchronization to time server [2620:2d:4000:1::40]:123 (ntp.ubuntu.com).
--
Aug 27 18:13:24 zero2 cloud-init[2561]: #############################################################
Aug 27 18:13:24 zero2 cloud-init[1640]: Cloud-init v. 23.2.1-0ubuntu0~22.04.1 finished at Sun, 27 Aug 2023 09:13:24 +0000. Datasource DataSourceNoCloud [seed=/dev/mmcblk0p1][dsmode=local].  Up 873.62 seconds
Aug 27 18:13:27 zero2 systemd[1]: Finished Execute cloud user/final scripts.

無事にインストールが完了したら、Wi-Fiと同じネットワークに繋がっているマシンからssh ホスト名.localでログインできるはずです。もしログインできないようなら、HDMIディスプレイとUSBキーボードを用意して原因調査を行うことになります[3]

ちなみにcloud-init用の設定は、microSDカードの先頭パーティションに「user-data」というファイル名で書かれています。まずは期待通りの設定になっているか、特にWi-FiのSSIDが間違っていないか調べてみると良いかもしれません。

Zero2の動作確認

無事にログインできたら、動作確認を兼ねて情報を収集してみましょう。たとえばCPUに関しては次のように表示されます。

$ lscpu
Architecture:            aarch64
  CPU op-mode(s):        32-bit, 64-bit
  Byte Order:            Little Endian
CPU(s):                  4
  On-line CPU(s) list:   0-3
Vendor ID:               ARM
  Model name:            Cortex-A53
    Model:               4
    Thread(s) per core:  1
    Core(s) per cluster: 4
    Socket(s):           -
    Cluster(s):          1
    Stepping:            r0p4
    CPU max MHz:         1000.0000
    CPU min MHz:         600.0000
    BogoMIPS:            38.40
    Flags:               fp asimd evtstrm crc32 cpuid
Caches (sum of all):
  L1d:                   128 KiB (4 instances)
  L1i:                   128 KiB (4 instances)
  L2:                    512 KiB (1 instance)
Vulnerabilities:
  Itlb multihit:         Not affected
  L1tf:                  Not affected
  Mds:                   Not affected
  Meltdown:              Not affected
  Mmio stale data:       Not affected
  Retbleed:              Not affected
  Spec store bypass:     Not affected
  Spectre v1:            Mitigation; __user pointer sanitization
  Spectre v2:            Not affected
  Srbds:                 Not affected
  Tsx async abort:       Not affected

コア数などは期待通りの結果になっているようです。次にハードウェアのリストを見てみましょう。

$ sudo lshw -short
H/W path   Device          Class       Description
==================================================
                           system      Raspberry Pi Zero 2 W Rev 1.0
/0                         bus         Motherboard
/0/0                       processor   cpu
/0/0/0                     memory      32KiB L1 Cache
/0/1                       processor   cpu
/0/1/0                     memory      32KiB L1 Cache
/0/2                       processor   cpu
/0/2/0                     memory      32KiB L1 Cache
/0/3                       processor   cpu
/0/3/0                     memory      32KiB L1 Cache
/0/4                       processor   l2-cache0
/0/5                       memory      415MiB System memory
/1         usb1            bus         DWC OTG Controller
/1/1                       input       USB Receiver
/1/1/0     input10         input       Logitech K400
/2         mmc0            bus         MMC Host
/2/1234    /dev/mmcblk0    disk        61GB SA64G
/2/1234/1                  volume      256MiB Windows FAT volume
/2/1234/2  /dev/mmcblk0p2  volume      57GiB EXT4 volume
/3         mmc1            bus         MMC Host
/3/1                       generic     SDIO Device
/3/1/1     mmc1:0001:1     network     43430
/3/1/2     mmc1:0001:2     generic     43430
/4         card0           multimedia  b1
/5         /dev/fb0        display     BCM2708 FB

LogitechのそれはUSBキーボードです。Wi-FiはBCM43430ですが、Bluetoothは見えていないようです。bluetoothdを起動したりhcitool等を使っても表示されていないので、認識するための何かが足りていないと思われるのですが、今回は原因解明までには至りませんでした。

$ sudo hcitool dev
Devices:
$ sudo dmesg|tail
[ 7243.339178] Bluetooth: Core ver 2.22
[ 7243.339369] NET: Registered PF_BLUETOOTH protocol family
[ 7243.339381] Bluetooth: HCI device and connection manager initialized
[ 7243.339413] Bluetooth: HCI socket layer initialized
[ 7243.339429] Bluetooth: L2CAP socket layer initialized
[ 7243.339459] Bluetooth: SCO socket layer initialized
[ 9016.299391] loop3: detected capacity change from 0 to 121368

9月13日追記この記事では「⁠Bluetoothは見えていないようです」と言及しましたが、第779回でBluetoothの認識方法とその使い方を説明する記事を公開しました。

ちなみに起動時間にかかる処理は次のような結果になりました。

$ systemd-analyze blame | head
 9min 3.998s cloud-final.service
2min 31.982s snapd.seeded.service
1min 35.387s cloud-init-local.service
     52.385s snap.lxd.activate.service
     23.395s snapd.service
     19.093s apparmor.service
     16.330s systemd-machine-id-commit.service
     15.986s cloud-config.service
     15.572s user@1000.service
     15.258s dpkg-db-backup.service

cloud-initを実行するサービスでは、apt updateやavahi-daemonパッケージのインストールを行っており、Zero2のmicroSDへのアクセス速度の都合でそこは時間がかかってしまうようです。2回目の起動以降のcloud-initは数十秒以内に収まります。その代わり、snapdは相変わらず遅いので、起動時間を重視するならsnapdとLXDは削除してしまったほうが良いかもしれません。

体感的にも何かを実行しようとするとしばらく待たされる感じです。おそらくmicroSDカードからの読み込みがボトルネックになっているのでしょう。もしそうだとすると32ビット版であれば「まし」になる可能性があります。また、Ubuntuの場合は「SSHでログイン時」はいろいろなコマンドを実行したりファイルをロードしていたりしており、ログインする際に余計な時間がかかってしまう傾向があります。たとえば第755回のUbuntuにおけるMOTDの仕組みのすべてでは、このあたりについて詳しく書いていますのでぜひ参考にしてみてください。

ここでは一通り抑制する方法のみを列挙しておきましょう。

$ sudo sed -i 's/\(.*motd.dynamic\)/#\1/' /etc/pam.d/sshd
$ sudo systemctl disable update-notifier-motd.timer
$ sudo rm /var/lib/ubuntu-release-upgrader/release-upgrade-available
$ sudo systemctl disable motd-news.timer
$ sudo rm /var/cache/motd-news
$ sudo mkdir /etc/apt/apt.conf.d/old
$ sudo mv /etc/apt/apt.conf.d/{,old/}20apt-esm-hook.conf
$ sudo touch /etc/apt/apt.conf.d/20apt-esm-hook.conf
$ sudo pro config set apt_news=false

また、Ubuntuにはcommand-not-foundという、⁠実行したコマンドが見つからなかった時に、適切なパッケージを提案してくれる」という大変便利な仕組みが存在します[4]

たとえば「ls」のつもりで「sl」コマンドを実行すると、次のように表示して、slパッケージをインストールし忘れていたことに気づかせてくれるのです。

$ sl
Command 'sl' not found, but can be installed with:
sudo apt install sl

この機能は第516回のcommand-not-found再発見でも紹介しているのですが、そこそこの量のI/O処理が走るため、Zero2のようなストレージアクセスが遅いシステムとは相性が悪いものです。よってZero2を使うなら無効化してしまいましょう。

$ cat<<'EOF' >> ~/.bashrc

# disable command-not-found
function command_not_found_handle {
    printf "%s: command not found\n" "$1" >&2
    return 127
}
EOF

反映するためにbashコマンドを実行するか、一度ログインしなおしてください。これでコマンドを間違えても余計なお仕置き時間で待つ必要がなくなりました。

CPUのコア温度とサーマルスロットリング

Zero2はZeroと比べてCPUの機能が増強され、またコア数も増えました。これは消費電力、つまり発熱も増える可能性を示唆しています。最後はCPUに負荷をかけて、どれくらいの温度でサーマルスロットリング(発熱を抑えるための周波数の低下処理)が動くかを確認してみましょう。

Raspberry Piの場合であればstressberryという便利なツールが存在します。これはstressコマンドを使ってCPU負荷をかけながらコア温度を計測するツールです。主に数多あるRaspberry Pi向けケースの評価やファンの有無による違いを調べるために使われているようです。

Ubuntuの場合、stressberryはパッケージ化されていないためpipxでインストールしましょう。

$ sudo apt install pipx stress
$ pipx install stressberry

どちらのコマンドも少し時間がかかるため、気長に待っていてください。

pipxは~/.local/bin/以下にラッパースクリプトをインストールします。Ubuntuの場合、⁠ログイン時」にこの~/.local/bin/ディレクトリが存在すれば自動的に環境変数$PATHに追加してくれますので、インストールしたコマンドもすぐに使えるようになります。ただし、ログインの時点でディレクトリがなく、その後作られた場合は$PATHには設定されませんので、パスを指定するか一度ログインし直してください。

stressberry自体はとてもかんたんに使えます。まずstressberry-runで計測し、その後stressberry-plotコマンドで計測結果をグラフにするだけです。

$ stressberry-run -n pizero2 -d 600 pizero2.dat

-n pizero2はデータセットの名前です。グラフ化した際に凡例としても使われます。-d 600は温度が安定して計測を開始してからの秒数です。初期値は500秒ですが、少し長くしてみました。

Awaiting stable baseline temperature...
Current temperature: 49.4°C - Previous temperature: 53.2°C
Current temperature: 47.2°C - Previous temperature: 49.4°C
(中略)
Preparing to stress [4] CPU Cores for [600] seconds
Idling for 150 seconds...
Current temperature: 44.5°C - Frequency: 1000MHz
Current temperature: 44.0°C - Frequency: 1000MHz
(後略)

stressberryはまず最初に定期的にCPUのコア温度を計測し、安定するまで待ちます。次に150秒間のアイドル時間(コマンドラインオプションで変更可能)を設けた上で、計測を開始するのです。また計測終了後にさらに150秒間のアイドル時間を設けて終了です。

出力したデータは、stressberry-plotでグラフに変換できます。

$ stressberry-plot pizero2.dat -o pizero2.png

複数のデータファイルを指定することで、合成したグラフも生成できます。

今回計測した結果は次のようになりました。

図10 室温27度の部屋で、ケースなどない状態で計測
図10

150秒を超えたあたりから計測が開始し、その後どんどん温度があがっていきます。ただし80度付近でサーマルスロットリングが動き、80度を大きく超えないよう周波数を落としているようです。750秒を超えたあたりで計測は完了し、温度ががくんと下がっています。

よって手元のZero2は全力で動かしたいなら、何かヒートシンクかファンがあったほうが良さそうです。ただしサーマルスロットリングが起きていても900MHz程度で駆動はしていたので、実運用上はそこまで差は出ないでしょう。

ちなみにstressberry実行時の電圧・電流は最大でも5V/530mA(2.65W)でした。アイドル時は110mA程度まで下がるようです。もちろん周辺機器等の接続状況によっても変わります。

Raspberry Pi Zero 2 Wは、待望のUbuntuが動くPi Zeroです。Ubuntuのノウハウを流用しつつ、消費電力が低くフットプリントも小さい何かを作りたい場合に役に立つことでしょう。いや、別にRaspberry Pi OSを使えば良いって話ではあるのですけどね。

ちなみに今回のUbuntu Weekly Recipeは第777回です。ただし残念ながら「777」にちなんだ話題は思いつけませんでした。次のラッキーセブンである第7777回をご期待ください。このまま順調に行けば、およそ140年後に掲載される予定です。

おすすめ記事

記事・ニュース一覧