ProxmoxでSysprepとVirtIOドライバーを使ったWindows VMテンプレートの作成:数分で仮想マシンを大量クローン

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

以前、開発チーム向けにWindowsマシンを1台ずつセットアップするのに午前中まるまるかかったことがある。ISOのコピー、再インストール、ライセンス認証、ドライバーのインストール、タイムゾーンの設定……。それ以来、一度だけ作業してあとはずっと使い回せるVMテンプレート+Sysprepの仕組みを取り入れることにした。

私のホームラボはProxmox VEで12台のVMとコンテナを管理している。本番環境に持ち込む前に何でもテストできるプレイグラウンドだ。このテンプレートワークフローは時間を大幅に節約してくれる。クリーンなWindows VMのクローンが2分以内で完成し、ホスト名とSIDは自動的に新たに生成される。

クイックスタート:5ステップでテンプレートを作成

これが核となるフロー。これを押さえれば即実践できる:

  1. 新しいVMを作成 → ISOからWindowsをインストール
  2. VirtIOドライバーをインストール(ストレージ、ネットワーク、balloon、Guest Agent)
  3. Generalize + ShutdownオプションでSysprepを実行
  4. VMシャットダウン後 → 右クリック → Convert to Template
  5. 必要なときにクローン → 新しいVMはクリーンな状態で新しいSIDが自動生成される

開始前に2つ準備しておく:

  • Windows ISO:Windows 10/11またはWindows Server
  • VirtIO ISO:FedoraリポジトリからStableリリースのvirtio-win.isoをダウンロード

テンプレート用VMの適切な作成

最初から最適なVM設定を行う

ProxmoxでVMを作成する際、テンプレートに長期的な影響を与えるいくつかの選択肢がある:

  • Machine typeq35を選択(PCIe対応、i440fxより優れている)
  • BIOS:Secure Bootを使用する場合はOVMF(UEFI)、旧来の互換性が必要な場合はSeaBIOS
  • ストレージコントローラー:VirtIO BlockまたはVirtIO SCSI singleを使ったSCSI
  • ネットワーク:VirtIO(準仮想化) — 最も優れたスループット
  • CPU:パフォーマンス最適化のためにhostまたはx86-64-v2-AES

重要な注意点:テンプレートにRAM/CPUを高く設定しすぎないこと。クローン時にユースケースに合わせて調整できる。テンプレートはインストールとSysprepの実行に必要な最低限のリソースで十分だ。

VMに2つのISOを同時にマウントする

Windowsをインストールする前に、VMに両方のISOをマウントする:

VM → Hardware → Add → CD/DVD Drive
  IDE 0: Windows.iso     (メインのブートドライブ)
  IDE 2: virtio-win.iso  (2枚目のCD/DVDドライブ)

VirtIOストレージコントローラーを使用する場合、インストール先を選択する際にWindowsインストーラーがハードディスクを認識できない。その場合はLoad driverを選択し、VirtIOディスクを指定する:viostor\amd64\w10(Windowsのバージョンに応じてw11/2k22など)。

VirtIOドライバーのインストール:省略できない重要なステップ

このステップを省略すると、クローン後にネットワークが使えなかったり、異常なほど動作が遅くなることがある。Windowsのインストール完了後にデバイスマネージャーを開くと、ドライバーが当たっていないデバイスが大量にある。これらはWindowsに認識されていないVirtIOデバイスだ。

Guest Toolsで一括ドライバーインストール

最速の方法:VirtIOディスクから統合インストーラーを実行する:

D:\virtio-win-guest-tools.exe

このファイルがすべてを一括インストールする:balloonドライバー、ネットワークアダプター(NetKVM)、ストレージコントローラー(viostor/vioscsi)、メモリバルーニング、QEMUゲストエージェント、シリアルドライバーなど。一度の実行で完了し、個別にインストールする必要はない。

ProxmoxでQEMU Guest Agentを有効化する

Guest Toolsのインストール後、Proxmox → VM → Options → QEMU Guest Agent → Enableと進む。この機能によりProxmoxはVMのIPアドレスを読み取り、ホストから安全なシャットダウンを実行でき、バックアップ時にファイルシステムをフリーズできる。本番環境では必須の設定だ。

# QEMU Guest Agentサービスが起動しているか確認
Get-Service QEMU-GA

Sysprep:すべてのクローンVMの「型」を作る

SysprepはMicrosoftのツールで、Windowsを一般化(generalize)するために使用する。マシン固有の情報(SID、ホスト名、アクティベーション状態、イベントログなど)を削除し、クローンするたびに完全に新しいIDを持つマシンを作り出す。このステップを省略すると、10台クローンしても全機同じSIDになり、ドメイン参加に失敗するかコンフリクトが発生する。

簡単な方法:GUI Sysprep

C:\Windows\System32\Sysprep\sysprep.exe

以下のオプションを選択する:

  • System Cleanup Action:Enter System Out-of-Box Experience (OOBE)
  • Generalize:✅ 必須チェック
  • Shutdown Options:Shutdown

Sysprepが完了するとVMは自動的にシャットダウンする。この時点で絶対にVMを再起動しないこと — すぐにテンプレートに変換する。

自動化する方法:Unattend.xml

クローン後のOOBE(初回セットアップ画面)を完全にスキップしたい場合は、unattend.xmlファイルを作成する:

<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
  <settings pass="specialize">
    <component name="Microsoft-Windows-Shell-Setup"
               processorArchitecture="amd64"
               publicKeyToken="31bf3856ad364e35"
               language="neutral" versionScope="nonSxS">
      <TimeZone>Tokyo Standard Time</TimeZone>
    </component>
  </settings>
  <settings pass="oobeSystem">
    <component name="Microsoft-Windows-Shell-Setup"
               processorArchitecture="amd64"
               publicKeyToken="31bf3856ad364e35"
               language="neutral" versionScope="nonSxS">
      <OOBE>
        <HideEULAPage>true</HideEULAPage>
        <HideLocalAccountSetupPage>true</HideLocalAccountSetupPage>
        <ProtectYourPC>3</ProtectYourPC>
        <SkipMachineOOBE>true</SkipMachineOOBE>
      </OOBE>
    </component>
  </settings>
</unattend>

このファイルをC:\Windows\System32\Sysprep\unattend.xmlに配置し、コマンドラインからSysprepを実行する:

C:\Windows\System32\Sysprep\sysprep.exe /oobe /generalize /shutdown /unattend:unattend.xml

VMをテンプレートに変換してクローンする

# ProxmoxシェルからVMの実際のIDを指定して実行
qm template 101

# またはWeb UIから:
# 右クリック → Convert to Template

VMのアイコンが変わり(紙のアイコン)、直接起動できなくなる — クローンのみ可能だ。デプロイが必要な場合:

# フルクローン — 完全に独立したVM(本番環境に推奨)
qm clone 101 201 --name win10-dev-01 --full true --storage local-lvm

# リンクドクローン — 高速でディスク節約だがテンプレートに依存
qm clone 101 202 --name win10-test-01

応用編:PythonでVMを一括自動デプロイ

5〜10台のVMを同時にデプロイする場合は、手動でクリックするよりProxmox APIを使う方が効率的だ:

import requests
import urllib3
urllib3.disable_warnings()

PVE_HOST = "https://proxmox.local:8006"
TOKEN_ID = "root@pam!deploy"
TOKEN_SECRET = "your-api-token-secret"

headers = {
    "Authorization": f"PVEAPIToken={TOKEN_ID}={TOKEN_SECRET}"
}

def clone_vm(template_id: int, new_id: int, name: str, storage: str = "local-lvm"):
    url = f"{PVE_HOST}/api2/json/nodes/pve/qemu/{template_id}/clone"
    data = {
        "newid": new_id,
        "name": name,
        "full": 1,
        "storage": storage,
    }
    resp = requests.post(url, headers=headers, json=data, verify=False)
    resp.raise_for_status()
    return resp.json()

# 5台のVMを並行してデプロイ
for i in range(1, 6):
    result = clone_vm(101, 200 + i, f"win10-worker-{i:02d}")
    print(f"Clone VM {200 + i}: task {result['data']}")

APIトークンはProxmoxで作成する:Datacenter → API Tokens → Add。パスワードの代わりにトークンを使うことで、権限を制限でき、簡単に無効化できる。

日々の運用で得た実践的なTips

1. テンプレートをスリムに保つ

すべてのVMに必要なもの(VirtIOドライバー、QEMU Guest Agent、重要なWindows Update)だけをインストールする。VM固有のソフトウェア(Visual Studio、SQL Server、IISなど)はクローン後にインストールする — テンプレートに詰め込まないこと。

2. バージョン管理付きのテンプレート名を付ける

win10-22h2-virtio-v1-template
win2022-dc-virtio-v2-template

大きなパッチ適用後にテンプレートを再ビルドする際は、古いバージョンを残しておく。新しいバージョンに問題があった場合に簡単にロールバックできる。

3. Generalize前に「pre-sysprep」スナップショットを作成する

# Sysprep実行前にスナップショットを作成
qm snapshot 101 pre-sysprep --description "Drivers installed, before sysprep"

Sysprepが失敗した場合やテンプレートに何か追加したい場合、このスナップショットに戻ることができる — 最初からインストールし直す必要はない。

4. Sysprep前にWindows Updateを適用する

すべてのパッチを適用し、必要な回数だけ再起動してからSysprepを実行する。最新パッチが適用済みのテンプレートからクローンしたVMは、アップデートが少なくて済む。複数台を同時にデプロイする際に大幅な時間節約になる。

5. 本番使用前にクローンをテストする

テンプレートを本番環境で使用する前に、1台のVMをクローンして起動し、詳しく確認する:

# SIDを確認 — 元のテンプレートのSIDと異なるはず
whoami /user

# ホスト名が変更されているか確認
hostname

# ネットワークアダプターがVirtIOドライバーを認識しているか確認
Get-NetAdapter

以前、SysprepでGeneralizeにチェックを入れ忘れたことがある。10台クローンしたところ全機同じSIDになり、ドメイン参加が全滅した。その後処理に半日かかった。一度しっかりテストすれば、後何度も節約できる。

6. ラボにはリンクドクローン、本番にはフルクローン

リンクドクローンは数秒で作成でき、ディスクを節約できる — ホームラボの一時的なテスト用VMに使う。フルクローンは完全に独立している — 本番環境や長期保存が必要なVMに使う。本番環境にリンクドクローンを使わないこと。テンプレートを削除するとそこからクローンしたすべてのVMが失われる

Share: