手当たり次第に書くんだ

飽きっぽいのは本能

Ubuntu 26.04 KVM VM の作成 – テンプレート qcow2 から libvirt domain を定義する

Ubuntu 26.04 の KVM 環境で、テンプレート qcow2 から個別 VM を作成する手順を整理します。前の記事で作成したテンプレートディスクを複製し、VM 名、CPU / メモリ、NVRAM、ディスク、仮想 NIC、libvirt XML を個別 VM として定義します。

この記事では、virt-install で毎回インストールするのではなく、テンプレートから VM を増やす運用を前提にします。実際の環境では構成管理で定義していますが、ここでは手動で何を作っているのかを追える形に分解します。

参考
書籍
参考書籍

作って理解する仮想化技術 ── ハイパーバイザを実装しながら仕組みを学ぶ

ハイパーバイザ、CPU 仮想化支援、メモリ仮想化、割り込み、仮想デバイスなど、VM の性能設計を低レイヤから理解したい場合の参考書籍です。価格や在庫はリンク先で確認してください。

Amazon で見る

このリンクは Amazon アソシエイトリンクです。

VM 作成で決めること

テンプレートから VM を作る場合でも、VM ごとに決める値があります。ここを曖昧にすると、同じテンプレートから作った VM 同士で名前、MAC、OVN port、NVRAM、ディスクが衝突します。

  • VM 名
  • 複製元テンプレート qcow2 と作成先ディスクパス
  • CPU / メモリのリソース profile
  • UEFI NVRAM の個別ファイル
  • 接続する bridge または logical switch
  • MAC アドレスと OVN interface ID

テンプレートディスクを確認する

まず、複製元となるテンプレートディスクが存在することを確認します。テンプレートは直接起動せず、個別 VM のディスクへ複製して使います。

sudo qemu-img info /var/lib/libvirt/images/ubuntu-template-40g.qcow2
sudo test -f /var/lib/libvirt/images/ubuntu-template-40g.qcow2
virsh --connect qemu:///system list --all

VM 用ディスクを作成する

VM 用ディスクはテンプレート qcow2 から作成します。単純な cp でも作れますが、ここでは形式を明示するために qemu-img convert を使います。

VM_NAME="ubuntu-test-g01-n001-v.mgmt.s01.example.com"
BASE_IMAGE="/var/lib/libvirt/images/ubuntu-template-40g.qcow2"
VM_IMAGE="/var/lib/libvirt/images/${VM_NAME}.qcow2"

sudo qemu-img convert \
  -f qcow2 \
  -O qcow2 \
  -o preallocation=off \
  "$BASE_IMAGE" \
  "$VM_IMAGE"

sudo qemu-img info "$VM_IMAGE"

テンプレート方式では、この時点で OS の中身は複製されています。hostname、machine-id、cloud-init 状態などをどの段階で個別化するかは、テンプレート設計と初回起動時の処理に依存します。

UEFI NVRAM を VM ごとに用意する

UEFI 起動の VM では、NVRAM も VM ごとに分けます。複数 VM で同じ NVRAM ファイルを共有してはいけません。

VM_NAME="ubuntu-test-g01-n001-v.mgmt.s01.example.com"
NVRAM_DIR="/var/lib/libvirt/qemu/nvram"
NVRAM_TEMPLATE="/usr/share/OVMF/OVMF_VARS_4M.fd"
NVRAM_PATH="${NVRAM_DIR}/${VM_NAME}_VARS.fd"

sudo mkdir -p "$NVRAM_DIR"
sudo cp -n "$NVRAM_TEMPLATE" "$NVRAM_PATH"
sudo chown root:root "$NVRAM_PATH"
sudo chmod 0644 "$NVRAM_PATH"

OVN logical switch port を用意する

OVN を使う構成では、VM の仮想 NIC に対応する logical switch port を作成します。interface ID は UUID 形式で一意にし、libvirt XML の virtualport と対応させます。

LOGICAL_SWITCH="ls3032"
INTERFACE_ID="$(uuidgen | tr 'A-Z' 'a-z')"

sudo ovn-nbctl --may-exist lsp-add "$LOGICAL_SWITCH" "$INTERFACE_ID"
sudo ovn-nbctl lsp-set-addresses "$INTERFACE_ID" unknown
sudo ovn-nbctl clear Logical_Switch_Port "$INTERFACE_ID" port_security

echo "$INTERFACE_ID"
sudo ovn-nbctl show

通常の Linux bridge だけで VM を接続する場合、この OVN port 作成は不要です。この手順は、VM の NIC を OVN logical switch と対応させるためのものです。

libvirt XML を作成する

VM は libvirt XML として定義します。ここでは、host-passthrough、HugePages、UEFI、qcow2、io_uring、virtio NIC、Open vSwitch virtualport を含む例を示します。

VM_NAME="ubuntu-test-g01-n001-v.mgmt.s01.example.com"
VM_IMAGE="/var/lib/libvirt/images/${VM_NAME}.qcow2"
NVRAM_PATH="/var/lib/libvirt/qemu/nvram/${VM_NAME}_VARS.fd"
INTERFACE_ID="replace-with-interface-uuid"

mkdir -p "$HOME/work/libvirt/qemu"

cat > "$HOME/work/libvirt/qemu/${VM_NAME}.xml" <<EOF
<domain type='kvm'>
  <name>${VM_NAME}</name>
  <memory unit='MiB'>4096</memory>
  <currentMemory unit='MiB'>4096</currentMemory>
  <vcpu placement='static' current='2'>2</vcpu>
  <cpu mode='host-passthrough' check='none' migratable='on'>
    <topology sockets='1' cores='2' threads='1'/>
  </cpu>
  <memoryBacking>
    <hugepages/>
  </memoryBacking>
  <os>
    <type arch='x86_64' machine='q35'>hvm</type>
    <loader readonly='yes' type='pflash'>/usr/share/OVMF/OVMF_CODE_4M.fd</loader>
    <nvram template='/usr/share/OVMF/OVMF_VARS_4M.fd'>${NVRAM_PATH}</nvram>
    <boot dev='hd'/>
  </os>
  <features>
    <acpi/>
  </features>
  <devices>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2' io='io_uring' cache='none' discard='unmap' detect_zeroes='unmap'/>
      <source file='${VM_IMAGE}'/>
      <target dev='vda' bus='virtio'/>
    </disk>
    <interface type='bridge'>
      <source bridge='br-int'/>
      <model type='virtio'/>
      <virtualport type='openvswitch'>
        <parameters interfaceid='${INTERFACE_ID}'/>
      </virtualport>
    </interface>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
    <serial type='pty'>
      <target port='0'/>
    </serial>
  </devices>
</domain>
EOF

この XML は、この環境寄りの構成です。一般的な KVM では HugePages、io_uring、Open vSwitch virtualport まで最初から入れない場合もあります。まず単純な VM を作る場合は、Linux bridge と通常の disk driver から始めても構いません。

VM を define して起動する

XML を作成したら、virsh define で libvirt に登録し、状態を確認してから起動します。

VM_NAME="ubuntu-test-g01-n001-v.mgmt.s01.example.com"
XML_PATH="$HOME/work/libvirt/qemu/${VM_NAME}.xml"

sudo virsh --connect qemu:///system define "$XML_PATH"
sudo virsh --connect qemu:///system dominfo "$VM_NAME"
sudo virsh --connect qemu:///system start "$VM_NAME"
sudo virsh --connect qemu:///system list --all

起動後に確認する

VM が起動したら、libvirt、OVS / OVN、console の順に確認します。疎通できない場合でも、まず VM が起動しているのか、NIC が bridge に接続されているのか、OVN port と対応しているのかを分けて見ます。

VM_NAME="ubuntu-test-g01-n001-v.mgmt.s01.example.com"

sudo virsh --connect qemu:///system domstate "$VM_NAME"
sudo virsh --connect qemu:///system domiflist "$VM_NAME"
sudo virsh --connect qemu:///system console "$VM_NAME"

sudo ovs-vsctl show
sudo ovn-nbctl show

リソース profile を分ける

VM の CPU / メモリは、都度ばらばらに決めるより、small / medium のような profile に分けておくと管理しやすくなります。

  • small: vCPU 2、memory 4096 MiB
  • medium: vCPU 4、memory 8192 MiB
  • CPU topology は sockets / cores / threads を明示する
  • ホストの NUMA や用途に応じて profile を増やす

確認ポイント

  • テンプレート qcow2 から VM 用ディスクを作っている
  • UEFI NVRAM を VM ごとに分けている
  • OVN を使う場合、interface ID が UUID 形式で一意になっている
  • libvirt XML の disk / interface / cpu / memory が意図通りになっている
  • VM 起動後に virshovs-vsctlovn-nbctl で状態を確認している

まとめ

Ubuntu 26.04 の KVM VM 作成では、テンプレート qcow2 を複製して終わりではありません。VM ごとの NVRAM、libvirt XML、仮想 NIC、OVN logical switch port、リソース profile をそろえて初めて、個別 VM として管理できる状態になります。

次は、VM の操作権限や interface 単位の制御を整理するために、KVM VM の ACL へ進みます。

関連記事

Ubuntu 26.04 KVM VM の作成 – テンプレート qcow2 から libvirt domain を定義する

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

トップへ戻る