おうちMAAS(Metal as a Service)導入メモ

# はじめに
自宅の環境の管理のためにCANONICAL社の[MAAS](https://maas.io/)を導入してみた時のメモです。
自宅で使う範囲なのでごく小規模での利用を前提とし、極力既存NWに手を入れずお手軽な導入を目指します。

導入に当たってはUbuntu公式Blogの[MAAS for the home](https://ubuntu.com/blog/maas-for-the-home)の記事を大いに参考にさせていただきました。

# MAASとは？
Ubuntuで有名なCANONICAL社が提供している、物理サーバの管理・デプロイ用ツールです。
(KVMなどの仮想マシンの管理もできるので、ちょっと語弊がありますが)
最近MaaSというと「Mobility as a Service」の方がメジャーかと思うので、ググラビリティが低いのが難点。

# 環境
MAASのインストール環境は以下のとおり。
・Raspberry pi 4B(メモリ8GBモデル) + USB SSD(60GB)
・Ubuntu 20.04 arm64
・MAAS 2.9

また、ネットワーク環境は以下のようになっています。
・192.168.24.0/24 の単一のサブネットのみを使用。
・ルーターとしてOpenWRTを使用しており、 DHCP・DNSの機能を持っている。MAAS導入後もDNS・DHCPはOpenWRTで管理する。
・サーバー機は全てDHCPでIPアドレスを固定化している。


# MAASセットアップ
### LXD環境準備
今回はLXDでMAASをコンテナとして構築します。
参考： 公式ドキュメントの[Install with LXD](https://maas.io/docs/install-with-lxd)

LXDのストレージプールとしてZFSを利用します。
USB接続のSSDを既に別用途でZFSとして利用していたので、ここにLXD用のZFSを新たに作成しました。

```bash
# 既に「tank」というZPoolと「tank/opt」というZFSが存在している
$ zpool list
NAME   SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
tank  59.5G   109M  59.4G        -         -     0%     0%  1.00x    ONLINE  -
$ zfs list
NAME       USED  AVAIL     REFER  MOUNTPOINT
tank       109M  57.5G       24K  none
tank/opt   108M  57.5G      108M  /opt
# LXDのストレージプール用にZFSを作成
$ sudo zfs create -o atime=off -o mountpoint=none tank/lxd
# 「tank/lxd」が追加された
$ zfs list
NAME       USED  AVAIL     REFER  MOUNTPOINT
tank       109M  57.5G       24K  none
tank/lxd    24K  57.5G       24K  none
tank/opt   108M  57.5G      108M  /opt
```
次にネットワークブリッジの作成。
「/etc/netplan/60-lxd-bridge.yaml」として以下のファイルを作成し、

```yaml
network:
    bridges:
        br0:
            dhcp4: true
            interfaces:
            - eth0
            macaddress: <実機のMacアドレス>
            parameters:
                stp: false
    ethernets:
        eth0:
            dhcp4: false
            dhcp6: false
    version: 2
```
以下コマンドで反映させます。

```bash
$ sudo netplan apply
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br0 state UP group default qlen 1000
    link/ether dc:a6:32:bb:8e:d5 brd ff:ff:ff:ff:ff:ff
3: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether dc:a6:32:bb:8e:d6 brd ff:ff:ff:ff:ff:ff
4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether dc:a6:32:bb:8e:d5 brd ff:ff:ff:ff:ff:ff
    inet 192.168.24.6/24 brd 192.168.24.255 scope global dynamic br0
       valid_lft 43199sec preferred_lft 43199sec
    inet6 fe80::dea6:32ff:febb:8ed5/64 scope link tentative 
       valid_lft forever preferred_lft forever
```
ストレージプールとブリッジの準備ができたらLXDの設定を行います。

```bash
$ lxd init
Would you like to use LXD clustering? (yes/no) [default=no]: 
Do you want to configure a new storage pool? (yes/no) [default=yes]: 
Name of the new storage pool [default=default]: 
Name of the storage backend to use (lvm, zfs, ceph, btrfs, dir) [default=zfs]: 
Create a new ZFS pool? (yes/no) [default=yes]: no #新規ZPool作成はしない
Name of the existing ZFS pool or dataset: tank/lxd #先ほど作成したZFSを指定
Would you like to connect to a MAAS server? (yes/no) [default=no]: 
Would you like to create a new local network bridge? (yes/no) [default=yes]: no #新規ブリッジは作成しない
Would you like to configure LXD to use an existing bridge or host interface? (yes/no) [default=no]: yes #既存のブリッジを指定する
Name of the existing bridge or host interface: br0 #先ほど作成したブリッジを指定
Would you like the LXD server to be available over the network? (yes/no) [default=no]: 
Would you like stale cached images to be updated automatically? (yes/no) [default=yes] 
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]: 
```
設定が完了したら、MAAS用のコンテナを作成します。

```bash
$ lxc launch ubuntu:20.04 maas
Creating maas
Starting maas
$ lxc list
+------+---------+-----------------------+------------------------------------------+-----------+-----------+
| NAME |  STATE  |         IPV4          |                   IPV6                   |   TYPE    | SNAPSHOTS |
+------+---------+-----------------------+------------------------------------------+-----------+-----------+
| maas | RUNNING | 192.168.24.206 (eth0) | 240f:76:8641:1:216:3eff:fe91:cf7b (eth0) | CONTAINER | 0         |
+------+---------+-----------------------+------------------------------------------+-----------+-----------+
```
以下のコマンドでコンテナのbashを起動します。

```bash
$ lxc exec maas bash
root@maas:~#
```
以降のMAASインストール作業は、このコンテナ上のbashで実施します。

### MAASインストール

概ね[公式ドキュメントの手順](https://maas.io/docs/deb/2.9/cli/installation)に沿って進めます。
個人的な好みで、Snapではなくdebパッケージでインストールします。

というわけで、まずは使わないSnapを削除。
参考：[Disabling Snaps in Ubuntu 20.10 (and 20.04 LTS)](https://www.kevin-custer.com/blog/disabling-snaps-in-ubuntu-20-04/)

```bash
root@maas:~# snap list
Name    Version   Rev    Tracking       Publisher   Notes
core18  20201210  1949   latest/stable  canonical✓  base
lxd     4.0.5     19206  4.0/stable/…   canonical✓  -
snapd   2.48.2    10709  latest/stable  canonical✓  snapd
root@maas:~# sudo snap remove lxd
lxd removed
root@maas:~# sudo snap remove core18
core18 removed
root@maas:~# sudo snap remove snapd
snapd removed
root@maas:~# sudo apt purge snapd
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following package was automatically installed and is no longer required:
  squashfs-tools
Use 'sudo apt autoremove' to remove it.
The following packages will be REMOVED:
  snapd*
0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded.
After this operation, 0 B of additional disk space will be used.
Do you want to continue? [Y/n] 
(Reading database ... 31405 files and directories currently installed.)
Purging configuration files for snapd (2.48+20.04) ...
Final directory cleanup
Discarding preserved snap namespaces
Unmount /snap inside a container
umount: /snap: no mount point specified.
Removing extra snap-confine apparmor rules
Removing snapd cache
Removing snapd state
root@maas:~# rm -rf ~/snap
```

MAASのリポジトリを追加しインストール。

```bash
root@maas:~# add-apt-repository ppa:maas/2.9
root@maas:~# apt install maas
```
インストールが完了したら、管理者ユーザーを作成します。
ユーザー作成時に、[LaunchPad](https://launchpad.net/)かGithubからSSH公開鍵のインポートができます。
LaunchPadの場合は「lp:<ユーザー名>」、Githubの場合は「gh:<ユーザー名>」を入力します。
SSH公開鍵は後で設定可能なので、省略しても構いません。

```bash
root@maas:~# sudo maas createadmin --username=admin --email=admin@example.com
Password: 
Again: 
Import SSH keys [] (lp:user-id or gh:user-id): gh:ussvgr
```
ユーザーの作成が終わったら、ブラウザで「http://<maasコンテナのIPアドレス>:5240/MAAS/」を開いてみましょう。
![スクリーンショット 2021-02-07 17.46.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/9d9ffd88-9269-a55a-f736-d1c4fa1088b5.png)

### MAAS初期設定

作成した管理者ユーザーでログインすると初期設定画面に遷移します。
ネットワーク周りで特別な事情がなければデフォルトでいいでしょう。
![スクリーンショット 2021-02-07 17.48.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/9541baed-6e49-c3e3-7ce0-f4c57730c7d6.png)

管理対象の機器で使用するためのOSイメージを選択し、「Update selection」ボタンを押下します。
今回ダウンロードするイメージは20.04、amd64のみにしておきました。
![スクリーンショット 2021-02-07 17.49.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/809d6129-175b-ff04-0bd5-651e379e46c2.png)
設定が終わったら下部の「Continue」ボタンを押下します。

SSH公開鍵の設定画面に遷移します。管理者ユーザー作成時に公開鍵を設定してない場合はここで設定します。
![スクリーンショット 2021-02-07 17.54.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/a266e3ed-5bb9-1596-c8da-00424731a569.png)
完了したら「Go to dashboard」をクリックします。

これでダッシュボードが見えるようになりました。
![スクリーンショット 2021-02-07 17.57.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/5a8f6c25-e410-1fd0-8ec3-8422bdea2df6.png)

上部「Settings」から「Network」 -> 「Proxy」と進み、「Don't use a proxy」を選択し保存しておきました。管理下のサーバでのパッケージインストールなどにProxyを使うオプションのようですが、私の環境では不要なので。
![スクリーンショット 2021-02-07 18.05.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/d162a077-3e70-b849-fd19-62d4cc318484.png)
あとはイメージのダウンロードが終わるのを待ちましょう。
（上部のImagesから進捗が確認できます）

# DHCP設定（OpenWRT）
MAASは管理対象の機器のセットアップにPXEを利用します。
通常の構成ではMAAS内のDHCPサーバを利用することになるのですが、今回は上にも書いたように既存のOpenWRTのDHCPを利用するのでそれに合わせて設定します。
OpenWRTの設定画面から Network -> DHCP and DNS -> TFTP Settings を以下のように設定します。
![スクリーンショット 2021-02-07 18.55.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/7de8bd91-41eb-aa64-d44a-920f265c143f.png)
OpenWRT自体がTFTP Serverになるわけではないのですが、「Network boot image」欄を設定するために「Enable TFTP Server」にチェックを付けています。
「Network boot image」欄は[参考にした記事](https://ubuntu.com/blog/maas-for-the-home)では『pxelinux.0』としていましたが、UEFIを利用する場合は上記のとおり『bootx64.efi』を指定します。

# 管理対象サーバの設定
今回はASRockのB85M Pro4というちょっと古めのマザーボードで作成した自作PCを管理対象サーバとして使用します。
BIOS設定画面のBootメニューにて以下のように設定します。
(他の機種でも同様の項目を設定すれば問題ないかと思います)

- CSM(Compatibility Support Module): Disabled
- Boot From Onboard LAN: Enabled
- 起動順: UEFI IP4 を先頭にする

# 物理サーバへのOSデプロイ
### マシンの登録とCommissioning
上記の設定を終え、MAASでのOSイメージダウンロードも完了していれば、OSデプロイができる状態になります。
管理対象サーバの電源を入れると、PXEでMAASサーバからイメージをダウンロードし起動します。
暫くすると自動で電源がシャットダウンされますが、それが正常な動作です。
MAASのメニューから「Machines」を選ぶと、以下のようにサーバが登録されています。（名前はMAASが勝手に付けた名前になっています）
![スクリーンショット 2021-02-07 19.59.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/104f768d-2fce-70c1-2923-a9ecacd9ed1f.png)
サーバ名をクリックし、メニューから「Configuration」を選択、「Power type」にて『Manual』を選択し保存します。
IPMIなどの管理機能を持ったマシンの場合は適した物を選択しましょう。
![スクリーンショット 2021-02-07 20.07.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/649f3942-f42c-ea07-f372-30f4e3ca6be7.png)
次に右上の「Take action」から「Commission」を選択、「Commissioning machine」をクリックします。
![スクリーンショット 2021-02-07 20.04.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/e9d5c6e8-afb9-00d7-b2d3-17f83bba53fe.png)

管理対象サーバの電源を入れるとPXEで起動し、Commissioning用のスクリプトが実行された後、自動でシャットダウンされます。
Commisioningが完了すると、サーバのStatus欄が『Ready』に変更されます。これでOSをデプロイする準備が整いました。
![スクリーンショット 2021-02-07 20.15.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/3374618c-7ac3-3857-fe5b-eefa6fc8565a.png)

### OSのデプロイ
デプロイ前にMAAS上でいくつか設定をしておきます。

上部の名前欄をクリックするとホスト名が変更できます。
![スクリーンショット 2021-02-07 20.18.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/fb57ff61-cd91-7927-406e-9f92b551892b.png)
NetworkタブでNICの設定を開き、IPアドレスの設定をします。
私の環境ではOpenWRTのDHCPで固定IPの払い出しをしているので「IP mode」を『DHCP』に変更しました。
また、Networkタブではブリッジの作成などもできます。
![スクリーンショット 2021-02-07 20.19.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/b185e2b5-1cea-59ec-1b12-265861dbc719.png)
Storageタブではパーティションの設定などができます。
![スクリーンショット 2021-02-07 20.22.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/42a383bd-b6be-b54e-ca52-4165eed0bd49.png)

設定が終わったら右上の「Take action」から「Deploy」を選択し、「Deploy machine」をクリックします。
![スクリーンショット 2021-02-07 20.26.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/01e96173-04c4-0b6a-bbd8-997b881741d7.png)

サーバのStatus欄が「Deploying」に変わったら再度サーバの電源を投入、OSのインストールが自動で始まります。
何度かの再起動を経て、デプロイが完了するとStatusが「Deployed」に変わり、ユーザー名：ubuntu、設定したSSHキーでログインできるようになります。

# おわりに
まだ使い始めたばかりですが、物理サーバのOSインストールを何度もやるときには便利そう、という感じです。
[PackerでMAAS用イメージを作る](https://github.com/canonical/packer-maas)なんてこともできそうなので、これからいろいろ触ってみよう。