KVM/LibvirtからVagrant Boxを自作する:ITチーム向けラボ環境の最適化ソリューション

Virtualization tutorial - IT technology blog
Virtualization tutorial - IT technology blog

なぜ既存のBoxが豊富にあるのに、Vagrant Boxを自作する必要があるのか?

実際のプロジェクトでは、Vagrant CloudにあるデフォルトのVagrant Boxでは不十分なことが多々あります。UbuntuやCentOSの「素」の状態では、Dockerや社内プロキシ、調整済みのカーネルモジュールといった特定のツールが不足しています。同僚に vagrant up の後で長いコマンドを実行させるのは苦痛です。時間の無駄であるだけでなく、ミラーリポジトリやネットワーク環境の違いによるエラーも発生しやすくなります。

Linuxに完全に移行して以来、VirtualBoxよりも優れたパフォーマンスを持つKVM/Libvirtを愛用しています個人のホームラボでは、Proxmox上で約15台のVMを管理し、本番環境にデプロイする前の機能テストを行っています。 セットアップが完了したものを .box ファイルにパッケージ化することで、新しいメンバーの導入時間を80%削減できます。ファイルをダウンロードして up するだけで、標準化された環境がすぐに手に入ります。

ラボ環境を構築する3つの一般的なアプローチ

1. パブリックBoxとシェルプロビジョナーの組み合わせ

最も簡単な方法です。OSイメージを取得し、インストールスクリプトを書きます。しかし、重いソースコードのコンパイルや数GBのツールセットが必要な場合、vagrant destroy してから再構築するたびに非常に時間がかかります。

2. Infrastructure as Code (Ansible/Terraform)

大規模システムの管理に適したプロフェッショナルな方法です。しかし、迅速なテストや個人のラボ環境において、Playbookを維持し続けることは、時に不要なリソース消費となります。

3. カスタムVagrant Boxのパッケージ化(最適な選択肢)

KVM上ですべてを一度だけ完璧に設定します。不要なファイルをクリーンアップした後、すべてを1つのファイルにまとめます。同僚は、あなたと全く同じ環境を数秒で手に入れることができます。

ソースとなるKVM仮想マシンの準備:暗黙のルール

Vagrantで仮想マシンを制御するには、システムを標準に従って構成する必要があります。このプロセスは非常にシンプルです。

ステップ1:vagrantユーザーの設定とSudo権限

Vagrantはデフォルトで vagrant ユーザーを使用してSSH経由でアクセスします。このユーザーを作成し、パスワードなしでsudoを実行できるように権限を付与します。

# ユーザーを作成し、デフォルトパスワードを 'vagrant' に設定
sudo useradd -m -s /bin/bash vagrant
sudo passwd vagrant 

# パスワードなしのsudo権限を付与
echo "vagrant ALL=(ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/vagrant
sudo chmod 0440 /etc/sudoers.d/vagrant

ステップ2:自動ログインのための不安全なキー(Insecure Key)の設定

パスワードの代わりに、Vagrantは初回接続時にデフォルトの公開鍵ペアを使用します。この鍵を仮想マシンの信頼済みリストに追加する必要があります。

mkdir -p /home/vagrant/.ssh
chmod 700 /home/vagrant/.ssh
# Hashicorpの公式リポジトリから公開鍵をダウンロード
curl -L https://raw.githubusercontent.com/hashicorp/vagrant/master/keys/vagrant.pub -o /home/vagrant/.ssh/authorized_keys
chmod 600 /home/vagrant/.ssh/authorized_keys
chown -R vagrant:vagrant /home/vagrant/.ssh

ステップ3:パッケージ化前のシステム「クリーンアップ」

Boxファイルが軽いほど、共有速度が上がります。一時ファイルや古いログを削除し、MACアドレスの重複エラーを避けるためにネットワーク構成をリセットします。

sudo apt-get clean
sudo rm -rf /var/lib/apt/lists/*
# Vagrantが新しいネットワークカードを認識できるようにudevルールを削除
sudo rm -f /etc/udev/rules.d/70-persistent-net.rules

仮想マシンを .box 形式にパッケージ化する手順

ソースの仮想マシンが Shut off(停止)状態であることを確認してください。Libvirtの場合、ファイル構造を最大限に制御するために手動で実行します。

Libvirt用Vagrant Boxの構造を解明する

実際、.box ファイルは、以下の3つのコア要素を含む tar.gz 圧縮アーカイブです。

  • metadata.json: プロバイダーとしてlibvirtを指定します。
  • Vagrantfile: Boxのデフォルト設定が含まれます。
  • box.img: 元の仮想マシンから取得したqcow2形式のディスクファイルです。

詳細な実装手順

1. 作業スペースの初期化:

mkdir my-custom-box && cd my-custom-box

2. Libvirtのストレージ(デフォルトは /var/lib/libvirt/images/)からイメージファイルをコピーします:

sudo cp /var/lib/libvirt/images/ubuntu22-template.qcow2 ./box.img
sudo chown $USER:$USER ./box.img

3. 実際の容量(例:20GB)を指定して metadata.json ファイルを作成します:

{
  "provider": "libvirt",
  "format": "qcow2",
  "virtual_size": 20
}

4. ドライバを定義するための内部 Vagrantfile を作成します:

Vagrant.configure("2") do |config|
  config.vm.provider :libvirt do |libvirt|
    libvirt.driver = "kvm"
    libvirt.storage_pool_name = "default"
  end
end

5. すべてを圧縮します:

tar cvzf my-ubuntu-k8s.box metadata.json Vagrantfile box.img

成果の確認:数秒でゼロから環境構築

my-ubuntu-k8s.box ファイルができたら、社内サーバーにアップロードしたり、Slackでチームに送信したりできます。使い方は非常に簡単です。

# Boxを管理リストに追加
vagrant box add --name team-alpha/ubuntu-k8s my-ubuntu-k8s.box

# 新規プロジェクトを開始
mkdir dev-env && cd dev-env
vagrant init team-alpha/ubuntu-k8s
vagrant up

Vagrantは自動的にイメージをLibvirtのプールにインポートし、SSHを設定します。パスワードを入力することなく、仮想マシンに直接ログインできるはずです。

失敗を避けるための「血の教訓」

作業を進める中で、Boxファイルをよりプロフェッショナルにするための3つの重要な注意点を見つけました。

  • スパースファイル(Sparse files)技術: イメージをコピーする際は常に cp --sparse=always を使用してください。これにより、20GBのファイルでも実際には数GBの容量しか消費せず、ストレージを大幅に節約できます。
  • Virt-sysprepの活用: FedoraやCentOSを使用している場合は、virt-sysprep を実行してください。このツールは自動的にmachine-idやSSHホストキーを削除し、複数のVMを同時に実行した際の識別子の競合を防ぎます。
  • プラグインのインストール: チームメンバーにあらかじめ vagrant-libvirt をインストールするように伝えてください。このプラグインがないと、VagrantはVirtualBoxを探しに行き、すぐにエラーになります。

Vagrant Boxの作成方法をマスターすることは、単なる技術スキルではなく、プロセス最適化の思考法でもあります。新人に環境構築を教えるのに午前中を潰す代わりに、リンクを1つ送るだけで済むようになります。パッケージ化の成功を祈っています!

Share: