ホームラボにCanonical MaaSを導入する方法:ネットワーク経由でベアメタルOSプロビジョニングを自動化する

HomeLab tutorial - IT technology blog
HomeLab tutorial - IT technology blog

クイックスタート:5分でMaaSを動かす

ホームラボに物理マシンが2台以上あれば、あの苦労は身に覚えがあるはずだ――USBドライブを引っ張り出して、インストーラーを起動して、同じ画面を何度もクリックし続ける。私も数えきれないほどその儀式を繰り返してきた。CanonicalのMaaS(Metal as a Service)は、そのUSBドライブを完全に引退させてくれたツールだ。

マシンをラックに差し込んで電源を入れれば、あとはMaaSがすべて処理してくれる――PXEブート、ディスクパーティショニング、OSインストール、ネットワーク設定、インストール後のスクリプト実行まで。データセンターが大規模に使っている仕組みだが、ホームラボの控えめなハードウェアでも驚くほどうまく動く。

Ubuntu 22.04上でMaaSリージョンコントローラーを動かすための最速の手順はこちら:

# 公式snapからMaaSをインストール
sudo snap install maas

# MaaSをリージョン+ラックコントローラーとして初期化
sudo maas init region+rack \
  --database-uri "postgres://maas:maaspassword@localhost/maasdb" \
  --maas-url "http://192.168.1.10:5240/MAAS"

# 管理者アカウントを作成
sudo maas createadmin \
  --username admin \
  --email [email protected] \
  --password yourpassword

ブラウザで http://192.168.1.10:5240/MAAS を開く。ダッシュボードが表示されれば、もうほぼ完成だ。

詳細解説:MaaSのアーキテクチャを理解する

最初のマシンを登録する前に、内部で何が起きているかを把握しておくと役に立つ。MaaSにはホームラボで重要な2つの主要コンポーネントがある:

  • リージョンコントローラー ― 頭脳。API、データベース、Web UIを担当。1台あれば十分。
  • ラックコントローラー ― 手足。特定のサブネット上のDHCP、TFTP、PXEを処理する。物理ネットワークセグメントごとに1台必要。

ほとんどのホームラボでは、両方を1台のマシンで動かすで十分だ。

前提条件とネットワーク設定

MaaSはベアメタルマシンが接続するサブネットのDHCPを管理する必要がある。ここでつまずく人が一番多い。すでにpfSenseやOPNsenseを使っている場合、選択肢は2つある:そのサブネットのDHCPを完全に無効にするか、MaaSプロビジョニング用の専用VLANを切り出すかだ。私はVLANルートを選んだ――他に影響を与えずMaaSを分離できるからだ。

私の構成では専用の 192.168.50.0/24 プロビジョニングVLANを使っている。そこのDHCPはMaaSが管理し、メインLANはそのまま使い続けている。

データベースのセットアップ

MaaSにはPostgreSQLが必要だ。MaaSを初期化する前にインストールして設定しておこう:

# PostgreSQLをインストール
sudo apt update && sudo apt install -y postgresql

# MaaS用データベースとユーザーを作成
sudo -u postgres psql <<EOF
CREATE USER maas WITH PASSWORD 'maaspassword';
CREATE DATABASE maasdb OWNER maas;
\q
EOF

OSイメージのインポート

ログイン直後、サイドバーのImagesへ移動する。MaaSはOSイメージをダウンロードしないとプロビジョニングできない。必要なUbuntuバージョンを選択し――22.04 LTSが無難な選択だ――Update sourceを押して同期させる。100 Mbps回線では初回ダウンロードに約10〜15分かかる。回線が遅いと20分以上かかることもある。

# CLIからイメージの同期をトリガーすることも可能
maas admin boot-resources import

# 同期ステータスを確認
maas admin boot-resources read

DHCPとDNSの設定

MaaS UIのNetworking → Subnetsへ移動する。プロビジョニング用サブネットを見つけてMaaS管理のDHCPを有効にする。ゲートウェイとDNSサーバーをネットワーク設定に合わせて入力する。これ以降、MaaSにPXEブートするすべてのマシンのIPアドレス割り当てはMaaSが管理する。

最初のマシンを登録する

ここからが本番だ。対象マシンのBIOSブート順をPXEファーストに設定する。電源を入れる。30秒以内にMaaSがマシンを検出し、ダッシュボードのMachinesNewステータスで表示される。

クリックしてCommissionを押す。MaaSは小さなRAMディスクをブートしてハードウェア(CPU、RAM、ディスク、NIC)を調査し、その後マシンの電源をオフにする。ステータスがReadyに変わる。このマシンはデプロイ可能な状態になった。

応用編:マシンのデプロイとCloud-Initの活用

コミッショニングはMaaSにマシンのスペックを教えるプロセスだ。デプロイは実際にOSをインストールする。UIから数クリックで実行できるが、CLIを使う方が自動化の面でMaaSの真価を発揮できる。

CLIからデプロイする

# Ready状態のマシンをすべて一覧表示
maas admin machines read | jq '.[] | select(.status_name == "Ready") | {hostname, system_id}'

# 特定のマシンにUbuntu 22.04をデプロイ
maas admin machine deploy <system_id> \
  distro_series=jammy \
  hwe_kernel=ga-22.04

<system_id> は直前のコマンドで取得したIDに置き換える。デプロイは通常5〜10分で完了する。マシンが起動した時点でSSHキーが設定済みで、すぐに使える状態になっている。

インストール後の自動化にCloud-Initを使う

MaaSはcloud-initユーザーデータをサポートしているため、OSインストール後にスクリプトを自動実行できる。私が標準パッケージとSSH設定を新しいマシンに適用する方法はこちら:

maas admin machine deploy <system_id> \
  distro_series=jammy \
  user_data=$(base64 -w 0 <<'EOF'
#cloud-config
packages:
  - vim
  - htop
  - curl
  - git
  - docker.io
runcmd:
  - systemctl enable docker
  - usermod -aG docker ubuntu
  - echo 'MaaSによってプロビジョニング済み' > /etc/motd
EOF
)

役割ごとにマシンにタグを付ける

ホームラボのノードが6台を超えてくると、タグが欠かせなくなる。私はマシンを役割でタグ付けしている――storagecomputek8s-worker――これにより毎回system IDを探し回らずに目的のハードウェアを指定できる。

# マシンにタグを追加
maas admin tag create name=k8s-worker
maas admin machine add-tag <system_id> k8s-worker

# 特定のタグを持つマシンをすべて一覧表示
maas admin machines read | jq '.[] | select(.tag_names[] == "k8s-worker") | .hostname'

MaaSとAnsibleを連携させる

MaaSとAnsibleは相性がいい。MaaSがデプロイを完了すると、既知のIPを持つクリーンなマシンが用意され、Ansibleで設定する準備が整っている。私はDeployedステータスを待機して自動的にプレイブックを実行する小さなポーリングスクリプトを使っている:

import subprocess
import time
import json

SYSTEM_ID = "abc123"

while True:
    result = subprocess.run(
        ["maas", "admin", "machine", "read", SYSTEM_ID],
        capture_output=True, text=True
    )
    data = json.loads(result.stdout)
    if data["status_name"] == "Deployed":
        ip = data["ip_addresses"][0]
        print(f"{ip} にマシンがデプロイされました。Ansibleを実行中...")
        subprocess.run(["ansible-playbook", "-i", f"{ip},", "site.yml"])
        break
    print(f"ステータス: {data['status_name']}、待機中...")
    time.sleep(15)

実際のホームラボ運用から得た実践的なヒント

MaaSを本番環境――ホームラボの本番でも――で動かしていると、ドキュメントがさらっと流している落とし穴にいくつかぶつかる。実際に私がハマったものを紹介しよう:

IPMI / BMCは革命的だ

MaaSはIPMIをネイティブでサポートしている。サーバーにIPMIやiDRACがあれば、マシンのPower設定に登録しよう。MaaSはコミッショニングとデプロイの際にマシンの電源を自動でオン・オフできるようになり、物理的な操作が一切不要になる。これが真のライツアウト自動化を実現する鍵だ。

# マシンのIPMI電源パラメーターを設定
maas admin machine update <system_id> \
  power_type=ipmi \
  power_parameters_power_address=192.168.50.101 \
  power_parameters_power_user=admin \
  power_parameters_power_pass=ipmiadminpass

サブネットとファブリックの落とし穴

MaaSはVLANとサブネットを自動検出する。複数のVLANを運用している場合、MaaSが各サブネットを正しいファブリックにマッピングしているか確認しよう。ファブリックのミスマッチはPXEの無言の失敗を引き起こす――マシンがPXEで起動してIPを要求しても、MaaSから何も返ってこない。

再デプロイ前にリリースする

マシンを使い終わって別のOSを入れたい場合は、まずリリースしよう。これでディスクが消去され、Ready状態に戻る。すでにデプロイ済みのマシンにそのままデプロイすることはできない――リリースは必須だ。

maas admin machine release <system_id>
# ステータスが "Ready" に戻るのを待ってから再デプロイ

snap版とパッケージ版の違い

snap版はアップグレードが sudo snap refresh maas 一発で済むため管理が楽だ。ただし注意点がある:snapはMaaSをサンドボックス化されたプロセスとして実行する。カスタムスクリプトや外部ツールでパーミッションエラーが発生する場合は、aptベースのインストールの方がアップグレード管理のコストはかかるが柔軟性は高い。

ディスクパーティショニングの制御

デフォルトでは、MaaSはOS用に最初のディスク全体を使う。より細かい制御――専用の /data パーティション、LVM、ZFSなど――が必要な場合は、デプロイ前にマシンの詳細ページでカスタムストレージレイアウトを設定しよう。Storageの奥に隠れているが、大切なデータが入ったディスクを誤って消去する前に必ず確認しよう。

MaaSが安定稼働し始めると、マシンの再プロビジョニングにかかる時間が45分の手作業から、CLIコマンド1つとコーヒー休憩の時間に縮まる。Kubernetes、TrueNAS、複数のVMを抱えたホームラボにとって、それは些細なことではない。

Share: