Raspberry Pi 3B+にUbuntu Server 18.04をインストール

# 概要
##モチベーション
[公式](https://wiki.ubuntu.com/ARM/RaspberryPi#Download)にUbuntu Server 18.04のイメージがアップロードしてあり，Raspberry Pi 3B+に簡単インストールできそうだったので．あとROSで遊びたくて．

##ネットワーク環境の変動に対する考え方
raspberry piの場合，使用状況が色々変わる．持ち運びも考慮に入る．これにより状況によってネットワーク環境が変わることが想定される．

###無線LANの場合
無線LANで接続できる場合，IPが自動で割り振られる状況のみを想定する．IPが自動で割り振られない場合，そもそも無線サービスが使えないと考え，IPが割り振られれず利用できないままにしておく．

- 対処
 - ネットワーク設定にてdhcpによる割り振りを行う(netplanのyaml設定ファイルでdhcp4: trueとする)．
 - IPが変わる可能性があるので，ssh接続などは名前解決で行う．dnsがない可能性も考え，avahi-daemonによる名前解決を行う．

###有線LANの場合
有線LANの場合，以下の状況が考えられる．
1. LANケーブルが刺さっていない
2. ad-hockな接続である
3. dhcpサーバによりIPが自動で割り振られる
4. dhcpサーバのないネットワークに接続しちゃった
5. 固定IPを設定しなければならないネットワークである

このうち，5.は考えず，1.,2.,3.と4.で適当にIP割り振っちゃっていい状況を対象とする．
わりとraspberry piを持ち運んだりして状況が変わると，1.になったり3.になったり途中で状況が変わるけど，それでも動くようにしたい．

- 対処
 - link-localによるプライベートIPの自動割り振り(169.254.0.0/16)を行う(netplanのyaml設定ファイルでlink-local: [ipv4]を使う)
 - avahi-daemonによる名前解決を行う(無線LANと同じ)

# microSDにインストール
## Ubuntu ServerのOSイメージファイル

[公式](https://wiki.ubuntu.com/ARM/RaspberryPi#Download)からARM64のイメージファイル(xzファイル)をダウンロード[^armhf_arm64]

- イメージファイルは二種類
 - ARMHFは32bit
 - ARM64は64bit

## Windowsでのインストール方法

[Win32 Disk Imager](https://forest.watch.impress.co.jp/docs/review/1067836.html)でmicroSDにimgファイルを書き込む．

## Mac, Ubuntu, etc.
頑張る

# 設定
## 最初の起動
1. microSDカード，HDMI，キーボード，マウスをつなげてRaspberry Pi 3B+を起動
2. username/password = ubuntu/ubuntu でログイン
3. パスワードの変更を求められるので変更[^login_with_ssh]

## LAN設定[^netplan]

 - 設定ファイル
  - /etc/netplan/50-cloud-init.yaml
 - 今回の例
  - 有線・無線両方ともDHCPにて自動割り当て
  - 無線LANのssidをmyssid，セキュリティキーをmypassとして説明
  - renderer: networkdを使用[^renderer_link-local]

### yamlの編集

```50-cloud-init.yaml
network:
    version: 2
    renderer: networkd
    ethernets:
        eth0:
            dhcp4: true
            dhcp6: true # 使わないならfalse
            link-local: [ ipv4, ipv6 ] # v6いらないなら [ ipv4 ]でおけ
    wifis:
        wlan0:
            dhcp4: true
            dhcp6: true # 使わないならfalse
            access-points: # 複数のssidを登録可
                "myssid":
                    password: "mypass"
```

### ネットワーク設定の有効化

```Bash:terminal
$ sudo netplan apply
```

## avahi-daemon[^avahi]

```Bash:terminal
$ sudo apt install avahi-daemon
$ sudo systemctl enable avahi-daemon
$ sudo systemctl start avahi-daemon
```

- /etc/hostnameで名前を指定[^hostnamectl]
 - 同じネットワーク内で名前が被らないように気を付ける
 - 以下はとりあえずの例

```:/etc/hostname
pi001
```

これでホスト名.localでアクセス可能となる．この例の場合，pi001.localでアクセスできるようになる．

## その他通常の設定
### 時刻合わせ
- 設定ファイル編集

```:/etc/systemd/timesyncd.conf
NTP=ntp.nict.jp
FallbackNTP=ntp.ubuntu.com # 複数指定する場合にはスペース区切りで続けて記述
```

```Bash:terminal
$ timedatectl set-ntp true
$ sudo systemctl enable systemd-timesyncd.service
$ sudo timedatectl set-timezone Asia/Tokyo
$ sudo systemctl restart systemd-timesyncd.service
```

### ロケール・キーボード・スワップファイルの設定
[ここ](https://gihyo.jp/admin/serial/01/ubuntu-recipe/0564)を参考．

```Bash:terminal
$ sudo locale-gen ja_JP.UTF-8
$ sudo dpkg-reconfigure -f noninteractive locales
$ echo "LANG=ja_JP.UTF-8" | sudo tee /etc/default/locale
```
/etc/default/keyboardを編集
- XKBLAYOUT="jp"にする

スワップファイルはメモリの使用状況をみて必要なら行う．

```Bash:terminal
$ sudo fallocate -l 1g /swapfile
$ sudo chmod 600 /swapfile 
$ sudo mkswap /swapfile 
$ echo '/swapfile swap swap defaults 0 0' | sudo tee -a /etc/fstab
$ sudo swapon -a
```

2行目で1GBのスワップファイルを作成している．

### システムアップデート[^system_update]

```Bash:terminal
$ sudo apt update && sudo apt upgrade
```


[^armhf_arm64]: ここで使用したのは64bitだけど，Raspberry Piではまだまだ32bitがメインらしい([新しい地図](https://ameblo.jp/mongol-sky/entry-12413849956.html))．

[^login_with_ssh]: この時点でsshによるログイン可能となる．

[^netplan]: Ubuntu 18.04なのでLANの設定はnetplanの形式となる．詳しくは[公式](https://netplan.io/)のmenuからreferenceやexampleが参考になる．

[^renderer_link-local]: netplanの場合，rendererにnetworkdとNetworkManagerを選択できる．しかしNetworkManagerの場合，dhcp4: trueにするとlink-localのオプションが無効化されてしまう([netplan referenceのlink-localの項](https://netplan.io/reference))．よってlink-localのオプションを使う場合，networkdにしないといけない．

[^avahi]: dhcp割り当てなのでIPが変わる可能性があり，IPによるssh接続は面倒となる．そこでホスト名による接続のためavahi-daemonを使う([手持ちのRaspberryPiをサクッとmDNSに対応させる](https://qiita.com/takish/items/1a640576caa2d0dfefc4))．

[^hostnamectl]: 有効化のためのリブートが面倒ならhostnamectlコマンド使おう([server world](https://www.server-world.info/query?os=Ubuntu_16.04&p=hostname))

[^system_update]: 本当はインストール直後にも行う．というか隙あらば行う．