[Raspberry pi4] Ubuntu 20.10 のヘッドレスインストール。 キーボード、ディスプレイなしでインストールする方法

RaspberryPi
RaspberryPi Ubuntu 自宅サーバ

概要

ラズパイ4にUbuntu 20.10をインストールしたという話。MicroHDMIを持っていなかったので、キーボードやディスプレイを接続せずに、インストールと初期設定を行います。
Ubuntuをインストールして、PCからSSHでログインできるようにしていますが、 Cloud-init(user-data)の仕組みを活用して、起動後の作業がなるべく発生しないようにしています。

以前の記事ではUbuntuのインストール、起動後にいろいろ設定が必要でしたが、その辺を自動化した手順となっています。:[Raspberry pi3] Ubuntu 18.04 LTS のインストール(キーボード、ディスプレイ不要)

用意するもの

Raspberry Pi 4 8GB RAM
ラズパイケース
USB Type-Cの電源
MicroSDカード 128GB

アルミ製のケースは見た目もオシャレで、ヒートシンクの役割もするので良いですね。トラブルがあったときに備えてMicroHDMIのケーブルもあったほうが良さそうです。

インストールした環境

Ubuntu Server 20.10 64bit (arm64)
RAM容量が増えてるので64bit版を選びます。
用途によっては Ubuntu Server 20.04.1 LTS (arm64) を選ぶのも良いですね。

Ubuntu のダウンロードとインストール

Raspberry Pi Imager を公式サイトからダウンロードして、作業用PCにインストールします。Raspberry Pi Imager は、OSのダウンロードからSDカードへの書き込みまでやってくれます。Raspbianだけでなく、UbuntuなどのOSにも対応しているすぐれものです。

Raspberry Pi Imagerを起動したら、Ubuntu Server 20.10 64-bit (arm64) と書き込み先のSDカードを選んで、「Write」をクリックするだけです。

しばらく待つとSDカードへの書き込みが完了します。以前までは自分でOSイメージと書き込みツールを用意する必要がありこの作業も面倒でした。

起動前の設定

まだRaspberryPiは使いません。UbuntuのOSイメージが書き込まれたSDカードをもう一度、作業用PCに差し込みます。
SDカードのSystem-bootにあるファイルに、事前設定を加えることで、初回の起動時から自宅サーバーとしての下地を作っておきます。

ネットワークの設定 : network-config

SDカードにある network-config というファイルを編集することで、あらかじめネットワークの設定をすることができます。私の環境では、ここにWIFIの設定(SSID、パスワード、固定IP、DNS、デフォルトゲートウェイ)を設定しました。有線LANを使う場合は、eth0を固定IPにすれば良いかと思います。

(公式ドキュメント) https://cloudinit.readthedocs.io/en/latest/topics/network-config-format-v2.html

# network-config の設定例

version: 2 ethernets: eth0: # Rename the built-in ethernet device to “eth0” match: driver: bcmgenet smsc95xx lan78xx set-name: eth0 dhcp4: true optional: true

wifis: wlan0: access-points: MYWIFI-SSID: password: “MYWIFI-PASSWORD” addresses: - 192.168.68.20/24 gateway4: 192.168.68.1 nameservers: addresses: - 192.168.68.1 dhcp4: no dhcp6: no optional: true

ネットワークに詳しくない人は、DHCP + 有線LAN が敷居が低いです。
ただ、モニタがないとラズパイに割り当てられたIPアドレスが簡単にわからないので、user-data のパッケージインストールのところで、avahi-daemon を入れしまうと良いかもしれません。そうしておけば、IPアドレスがわからなくても、「ホスト名.local」(例:pi4.local)でアクセスできるようになります。

## パッケージのインストール
packages:
- emacs-nox
- avahi-daemon

初期設定 : user-data

今回は user-data を使って以下の設定を行いました。
ホスト名をセット:pi4.your.hostname
タイムゾーンを"Asia/Tokyo"にセット
ロケールを"ja_JP.UTF-8"にセット
SSHのパスワードでのログインを禁止
デフォルトユーザ(ubuntu)は作成しない
自分用のユーザ(myuser)を作成
SSHの公開鍵をインポート(.ssh/authorized_keysに書き込む)
Emacsをインストール
SDカードの延命措置(/tmp、/var/tmp、/var/logのRAMDISK化)

Dockerをインストール
ファイアウォールの設定

#cloud-config
 の設定例

ホスト名の設定

hostname: pi4.your.hostname # タイムゾーン、ロケールの設定 timezone: “Asia/Tokyo” locale: “ja_JP.UTF-8”

SSH でのパスワードログインを禁止

ssh_pwauth: false

グループの作成

groups:

  • docker

ubuntuユーザの作成を止めて、自分用ユーザーを作る。複数ユーザ作りたい場合は、-name 以下をユーザ分追記する。

users:

- default # ここのコメントを外すと、デフォルトユーザ(ubuntu)が作られます。

  • name: myuser gecos: I am an user. primary_group: myuser groups: [adm, audio, cdrom, dialout, dip, floppy, lxd, netdev, plugdev, sudo, video] shell: /bin/bash sudo: ALL=(ALL) NOPASSWD:ALL

    パスワードログインは使わない

    lock_passwd: true

    githubのアカウントに設定してある公開鍵をインポートする(とても便利!)

    ssh_import_id:
    • gh:my_github_account

    githubに設定していない場合は、直接公開鍵を書いておけば良い。

ssh_authorized_keys:

- ssh-rsa AAAAB3NzaC1yc2EXXXXXXXXXXXXXXXXXXXXXXXXXXXX

初回起動時にパッケージのアップデートを行う。お好みで設定する。

#package_update: true #package_upgrade: true

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

packages:

  • emacs-nox

- avahi-daemon # pi4.local みたいな感じで名前解決ができる

サーバー用途ではSDカードがすぐ壊れるので、RAMDISKを使って対策をする

/tmp,/var/tmp,/var/logをRAMDISK化する

mounts:

  • [ tmpfs, /tmp, tmpfs, “defaults,size=256m”, “0”, “0” ]
  • [ tmpfs, /var/tmp, tmpfs, “defaults,size=256m”, “0”, “0” ]
  • [ tmpfs, /var/log, tmpfs, “defaults,size=128m”, “0”, “0” ]

Docker のインストールとfirewallの設定をする

Docker はお好みで。Firewall は必須。

runcmd:

ラズパイを起動する

SDカードをラズパイにさしたら電源を入れましょう。数分待てばラズパイが使用できるようになります。SSHでログインできたらOKです。設定例に書いた User-data だとdockerのインストールも行なっているので、cloud-init の final ステージが終わるまでに10分程度かかりました。

.ssh/authorized_keys に公開鍵がセットされていますし、ufwの設定もされています。デフォルトの ubuntu ユーザは作られなくなりました。

$ sudo ufw status
Status: active

To Action From


22/tcp LIMIT Anywhere 22/tcp (v6) LIMIT Anywhere (v6)

最初からRAMDISKも使われています。

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           782M   20M  762M   3% /run
/dev/mmcblk0p2  116G  3.5G  107G   4% /
tmpfs           3.9G     0  3.9G   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           4.0M     0  4.0M   0% /sys/fs/cgroup
tmpfs           256M     0  256M   0% /tmp
tmpfs           128M  660K  128M   1% /var/log
tmpfs           256M     0  256M   0% /var/tmp
/dev/mmcblk0p1  253M  153M  100M  61% /boot/firmware
tmpfs           782M  4.0K  782M   1% /run/user/1000

user-data についての補足

お勧めはしませんが、SSHでパスワードログインを行いたい場合は、user-dataは以下の設定をします。

# パスワードの
変更
chpasswd:
  expire: false
  list:
  - myuser:MYUSER_PASSWORD

SSHのパスワード認証を有効にする

ssh_pwauth: true

あと、ssh_import_idで、githubの公開鍵をインポートする場合、下記のURLで自分の公開鍵が見れます。公開鍵にアクセスできるかどうか、事前にチェックしておくと良いでしょう。

https://api.github.com/users/xxxx/keys
(アカウントxxxxのところは自分のGITHUBIDに置き換えてください。)

github等の仕組みが使えない場合は、ssh_import_id の部分を消して、代わりにssh_authorized_keys に直接公開鍵を書いてしまえばOKです。

  ssh_authorized_keys:
  - ssh-rsa AAAAB3NzaC1yc2EXXXXXXXXXXXXXXXXXXXXXXXXXXXX

cloud-config(user-data)のデバッグ

user-dataの設定については、下記の公式ドキュメントを見て追記・変更をしました。

https://cloudinit.readthedocs.io/en/stable/topics/examples.html
https://cloudinit.readthedocs.io/en/latest/topics/modules.html

user-dataのトライ・アンド・エラーのやり方

cloud-initについて、知識がなかったので、設定が固まるまではトライ・アンド・エラーの繰り返しでした。自分は下記の順序で設定を作りました。

・ネットワークの設定だけは済ませて、ラズパイにログインできるようにしておく。とりあえずはubuntu/ubuntuでも良い。

・公式ドキュメントで、できそうなことを調べる

・ラズパイにログインしてからもuser-data はいじれるので、適宜編集する。

$ sudo vi /boot/firmware/user-data

・cloud-initをリセットする。

$ sudo cloud-init clean
$ cloud-init status
status: not run

・cloud-init を再実行する。

$ sudo cloud-init init
$ sudo cloud-init modules --mode config
$ sudo cloud-init modules --mode final

cloud-init には、init/config/final の3つのステージがあり、各ステージは別々に実行することができます。どのステージでどのモジュールが実行されるかは、/etc/cloud/cloud.cfg で定義されています。

# init で実行されるモジュール
cloud_init_modules:
 - migrator
 - seed_random
 - bootcmd
 - write-files
 - growpart
 - resizefs
 - disk_setup
 - mounts
 - set_hostname
 - update_hostname
 - update_etc_hosts
 - ca-certs
 - rsyslog
 - users-groups
 - ssh

cloud-init modules –mode config で実行されるモジュール

The modules that run in the ‘config’ stage

cloud_config_modules:

Emit the cloud config ready event

this can be used by upstart jobs for ‘start on cloud-config’.

  • emit_upstart
  • snap
  • ssh-import-id
  • locale
  • set-passwords
  • grub-dpkg
  • apt-pipelining
  • apt-configure
  • ubuntu-advantage
  • ntp
  • timezone
  • disable-ec2-metadata
  • runcmd
  • byobu

cloud-init modules –mode final で実行されるモジュール

The modules that run in the ‘final’ stage

cloud_final_modules:

  • package-update-upgrade-install
  • fan
  • landscape
  • lxd
  • ubuntu-drivers
  • puppet
  • chef
  • mcollective
  • salt-minion
  • reset_rmc
  • refresh_rmc_and_interface
  • rightscale_userdata
  • scripts-vendor
  • scripts-per-once
  • scripts-per-boot
  • scripts-per-instance
  • scripts-user
  • ssh-authkey-fingerprints
  • keys-to-console
  • phone-home
  • final-message
  • power-state-change

・うまく行かなかったら /var/log/cloud-init.log を見る

まとめ

電源を入れば、基本設定の済んだUbuntuが使えるようになりました。いままでインストール後にゴニョゴニョしていた作業がなくなりとても便利です。
cloud-init は汎用的な仕組みなので、AWSでの運用にも応用ができると思います。

ぜひお試しください。

今回使った設定ファイルはGithubに。https://github.com/kitter11/RaspberryPi

わし
わし

pi3のときには、インストール後の作業が盛りだくさんだったのに、ずいぶんとスッキリしたな。次はDockerでWordpressやPostfixなどを立ち上げてラズパイ4をメインの自宅サーバーへ置き換えるべし。

わし
わし

avahi-daemon も最初に入れちゃえば、DHCPでもとりあえずホスト名でアクセスできるようになるのかなぁ。試してみるべし。

RaspberryPi ubuntu
スポンサーリンク
☆Geha☆をフォローする