ぽよメモ

レガシーシステム考古学専攻

MAASでストレージレイアウトのカスタマイズを探求したがよくわからなかった話

MAASとは

maas.io

Metal as a Service の略で、Ubuntuの開発元であるCanonicalが開発している、オープンソースのベアメタルサーバ管理ソリューションです。
以下の様な機能を提供しています。

  • OSのインストール自動化
    • PXEブートして curtin + cloud-init でプロビジョニング
  • VLAN管理
  • DNSおよびDHCPの提供
  • 各種Bare Metal Controller(IPMI、HP iLOIntel AMTなど)との連携による電源管理*1
  • 物理マシンのインベントリ
  • KVM・LXDホストおよび仮想マシン管理

Web UIからこれらの一連の操作を行うことが出来ます。例えばAWSのWebコンソールのように、ボタンをぽちぽちしたりAPI経由で仮想マシンおよび物理マシンの構築がオンプレミスでもできるようになります。

環境

pudding@maas-master:~$ snap list | grep maas
maas      2.9.2-9165-g.c3e7848d1  12555  2.9/stable     canonical*  -
maas-cli  0.6.5                   13     latest/stable  canonical*  -

MAASのストレージレイアウトつらい問題

2021年6月現在の最新安定版である v2.9 では、デフォルトで以下のレイアウトがサポートされています*2

  • Flat layout
  • LVM layout
    • パーティションレイアウトはFlat layoutと同じ。ただし、LVMによる論理ボリューム(LV)管理ができるようになっている。
    • ボリュームグループの空き容量全てが単一のLVによって占有されており、レイアウトを変えるためにはunmountしてresize2fsしてlvresizeする必要があるが、ルートにマウントされているのでいじるのが大変。
  • bcache layout
    • HDDのような遅いデバイスSSDなどをキャッシュとして噛ませるモード。
    • SSDが搭載されていない場合は自動でFlat layoutにフォールバックされる。
  • VMFS6 layout
    • VMWare ESXiをデプロイする際に自動で選択されるモード。よく知らない。
  • Blank layout
    • 手動でのパーティションレイアウト作成が必要なモード。そのままではOSのインストールができない。

これ以外のレイアウトをUIから指定したい場合、MAASでCommissionしてそのマシンの構成情報を取得・UI上からデバイスパーティションレイアウト・ファイルシステム手動で編集するしかありません。

f:id:pudding_info:20210619153034p:plain
CommissionしてReadyになったらこのUIでストレージレイアウトを編集出来る

数台程度しかマシンがない一般的なご家庭ならまだしも、逸般的な誤家庭とか、企業のプロダクション環境のサーバは単一のディスクしかないシンプルな環境とはほど遠いはずです。デフォルトで用意されているストレージレイアウトはどう見ても機能不足で、一台ずつ手動設定というのはさすがに目も当てられません。

curtin

Ubuntuの有名さに対して、curtinは驚くほど知られていません。例えばQiitaで curtin を検索してみても、軽く読んだ限り明示的に利用しているのは以下の記事だけのようでした。

qiita.com

公式ドキュメントを見ても何ができて何を目指しているのか全然分からないというのが正直な感想でした。

curtin.readthedocs.io

curtinのconfigを抽出する

とにかく、MAASは内部的にはこのcurtinを利用してマシンのセットアップを行っています。以下のドキュメントで説明されています。

maas.io

MAASは選択したストレージレイアウトに従って動的にcurtinの設定を生成し、デプロイしているようです。一度手動でストレージのレイアウトを編集してデプロイし、MAAS CLIからその設定を抜き出すことで、独自のレイアウトを再利用することができます。

$ MAAS_USER=MAASのログインユーザ名
$ MAAS_URL=MAASのURL(例:http://localhost:5240/MAAS/)
# API KeyはWeb UIから入手可能
$ maas login ${MAAS_USER} ${MAAS_URL}
API key (leave empty for anonymous access):
# ホスト名と紐付けて目的のノードのsystem idを探す
$ maas ${MAAS_USER} machines read | jq -r '.[] | .hostname + ": " + .system_id'
maas-node1: xh4xrn
maas-node3: qbyswd
maas-node2: t3f4ba
# 今回はmaas-node1のcurtin configを適当なファイルに吐く
$ maas ${MAAS_USER} machine get-curtin-config xh4xrn > /tmp/curtin-config-lvm

重要なのは storage: から始まるセクションだけなので他は消してしまって良いです。以下の様なマシンでLVM layoutを選択した場合のストレージレイアウトです。

storage:
  config:
  - grub_device: true
    id: sda
    model: Virtual Disk
    name: sda
    ptable: gpt
    serial: 6002248094595034c40f053014e7387d
    type: disk
    wipe: superblock
  - device: sda
    flag: boot
    id: sda-part1
    name: sda-part1
    number: 1
    offset: 4194304B
    size: 536870912B
    type: partition
    uuid: 33524d54-d698-43e5-985e-cc68b470f720
    wipe: superblock
  - device: sda
    id: sda-part2
    name: sda-part2
    number: 2
    size: 68174217216B
    type: partition
    uuid: 9d681714-39ad-42e2-a555-84f52b9cb216
    wipe: superblock
  - devices:
    - sda-part2
    id: vgroot
    name: vgroot
    type: lvm_volgroup
    uuid: 280744d7-d041-40e2-98c8-4d4810d780f2
  - id: vgroot-lvroot
    name: lvroot
    size: 68170022912B
    type: lvm_partition
    volgroup: vgroot
  - fstype: fat32
    id: sda-part1_format
    label: efi
    type: format
    uuid: 4314dc3b-b93a-4d9f-a0f2-68c167f6bb03
    volume: sda-part1
  - fstype: ext4
    id: vgroot-lvroot_format
    label: root
    type: format
    uuid: d422bd61-cd28-473e-ad17-7e80fc51a241
    volume: vgroot-lvroot
  - device: vgroot-lvroot_format
    id: vgroot-lvroot_mount
    path: /
    type: mount
  - device: sda-part1_format
    id: sda-part1_mount
    path: /boot/efi
    type: mount
  version: 1

公式ドキュメントを読むとおおよその意味は分かります。

curtin.readthedocs.io

この設定でmaas-node1を固定するには以下の様にします(storageセクション以外は消しておくこと)*3

$ sudo cp /var/snap/maas/current/preseeds/curtin_userdata.sample /var/snap/maas/current/preseeds/curtin_userdata_ubuntu_amd64_generic_focal_maas-node1
$ cat /tmp/curtin-config-lvm | sudo tee -a /var/snap/maas/current/preseeds/curtin_userdata_ubuntu_amd64_generic_focal_maas-node1

抽出したconfigを流用する

現在の設定には2つつらみがあります。

  • uuidやserialが指定されている
  • ボリュームのサイズが指定されている

前者を解決するために、とりあえずそれらの値を全部削除します。type: partition および type: format についてはuuidが無くても動く*4ようですが、 type: disk では serial もしくは path の指定が必要なようです*5。よって以下の様にpathを指定します。

  storage:
    config:
    - grub_device: true
      id: sda
      model: Virtual Disk
      name: sda
      ptable: gpt
-     serial: 6002248094595034c40f053014e7387d
+     path: /dev/sda
      type: disk
      wipe: superblock

この設定はかなりハードウェアの変更に弱いです。全然良い方法とは思えませんが共通化するためにはこれくらいしか方法が無いように思われました。

後者は解決できませんでした。

https://curtin.readthedocs.io/en/latest/topics/storage.html#partition-command

Note Curtin does not adjust size values. If you specific a size that exceeds the capacity of a device then installation will fail.

このように書いてあり「残り全部」みたいな指定ができません。管理するマシンのストレージ容量の最低値を基準にすれば一応動くはず……*6

この設定を Ubuntu 20.04 かつ amd64 なマシンのセットアップに利用するためには、ノードごとの設定と同じようにファイルを配置します。

$ sudo cp /var/snap/maas/current/preseeds/curtin_userdata.sample /var/snap/maas/current/preseeds/curtin_userdata_ubuntu_amd64_generic_focal
$ cat /tmp/curtin-config-lvm | sudo tee -a /var/snap/maas/current/preseeds/curtin_userdata_ubuntu_amd64_generic_focal

ノードごとの設定が無い場合、デフォルトの設定を無視してこのストレージレイアウトが読まれます。

疑問点

さて、全ノードが全て同容量の単一ディスクしか持っていない場合はこれでもうまくいきそうです。しかし現実には、

  • 導入した世代によって容量が違う
  • 導入した世代によってはSATAではなくNVMe SSDを搭載している
  • ディスクが2本以上搭載されている

など様々なケースが考えられそうです。果たしてこれをプロダクション環境で利用している人たちはどうやっているんでしょうか……

ホストごとに設定を作ることは出来ますが、ホスト名のプレフィクスなどで読み込むconfigを変えるようなロジックは無さそう*7であり、

  • インストールするOSのバージョン・マシンのアーキテクチャの組ごとにマシンの構成の方を固定化してしまう
  • 全ホストで独自の設定ファイルを生成するようにする

のいずれかの対策をとらなければいけないように思われます。

まとめ

おうちでベアメタルクラウドをやる第一歩としてMAASでPoCしていたところ、ストレージ周りの工夫が必要なことが判明したため少し調べました。

現状では一度手動で設定し、その設定を流用することで以降独自のストレージレイアウトでプロビジョニングできそうです。ただしノードごとに構成が揃っていることが必要そうです。

これをプロダクション環境で使っている人たち、どうしているんですかおしえてください 🙏

参考


*1:いずれもそのマシンがサポートしていない場合、手動で電源をオンにしたりする必要があります

*2:maas.io

*3:https://maas.io/docs/snap/2.9/ui/custom-machine-setup#heading--template-naming

*4:そもそもpartitionのドキュメントには uuid の項目がありません。このパラメータがどう使われているのかは不明です。 https://curtin.readthedocs.io/en/latest/topics/storage.html#partition-command

*5:https://curtin.readthedocs.io/en/latest/topics/storage.html#disk-command

*6:使えない領域が出来ます

*7:https://github.com/maas/maas/blob/1aa6276c0b6d7d702f1ed3036fd11d30e879c285/src/maasserver/preseed.py#L614