Hiroaki Mizuguchi: The Offical Site

Cloud Init on Libvirt

2021-11-01 21:51

Debianのcloud imageをLibvirt上にて利用し、cloud-initでログイン可能にする

実行環境

以下のような構成の仮想化用途のホストにてDebian VMをデプロイします。

  • Intel® NUC Kit NUC5i3RYH
    • CPU: Intel Core i3-5010U CPU
    • Memory: 16GB
    • Storage 1TB
  • CentOS Linux release 8.4.2105

実現したいこと

  • VMのセットアップはVMイメージに組み込まれたcloud-initを用いる
  • VMはDHCPに依存せず静的設定の基づいてNWを立ち上げること
  • cloud-initセットアップ後は指定したSSH鍵を用いてログイン可能なこと

方法

必要なソフトウェアのインストール

  • Virtual Machineの動作に必要なパッケージ
    • libvirtd
    • qemu-kvm
  • cloud-init用のNoCloud ISOの作成に必要な物
    • genisoimage

VMイメージのダウンドード

Debianの公開サイトからVMイメージをダウンロードします。

cd /var/lib/libvirt/images
curl -LO https://cloud.debian.org/images/cloud/bullseye/20211011-792/debian-11-genericcloud-amd64-20211011-792.qcow2

VMインスタンス用のストレージを作る

backing storage機能を使うベースとなるVMイメージの差分を保持するストレージを作る。

qemu-img create -f qcow2 -b debian-11-genericcloud-amd64-20211011-792.qcow2 test.qcow2

仮想ストレージのサイズも元の2GBから40GBに拡張する

qemu-img resize -f qcow2 test.qcow2 40G

cloud-init用のISOを作る

cloud-initのNoCloud Datasouceの使用に従ったISOを作成する。

genisoimage -output /var/lib/libvirt/images/test.iso -volid cidata -joliet -rock user-data meta-data network-config

user-datameta-datanetwork-configのファイルについては以下を参照ください

meta-data

instance-id: test-1
local-hostname: test

user-data

書き方はAWSのドキュメントcloud-initのドキュメントを参照してください。 再起動設定を入れている理由はnetwork-configの設定と内部で設定されるDHCPの設定が衝突する事へのworkaroundです。

#cloud-config
chpasswd: {expire: False}
ssh_pwauth: False
ssh_authorized_keys:
  - ssh-ed25519 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
power_state:
  mode: reboot

network-config

cloud-initのドキュメントを参照ください

version: 2
ethernets:
  enp1s0:
    match:
      macaddress: "aa:00:00:01:00:00"
    addresses:
      - 10.48.1.101/24
    gateway4: 10.48.1.253
    nameservers:
      addresses: [10.48.1.253]

VMの設定ファイルを定義する

  • USBは利用しないので無効化する
  • VGA周りの設定も無効化する
  • virtio関連
    • virtio-scsiを用いてStorageとISOを繋ぐ
    • virtio-netを用いてNICを繋ぐ
    • virtio-rngを用いて乱数生成器をVMに繋ぐ
    • virtio-balloonを繋ぐ
    • Q35を用いる
  • userserialを用いてシリアルコンソールを使えるようにする
<domain type='kvm'>
  <name>bgp</name>
  <memory unit='GiB'>2</memory>
  <currentMemory unit='GiB'>2</currentMemory>
  <vcpu placement='static'>2</vcpu>
  <resource>
    <partition>/machine</partition>
  </resource>
  <os>
    <type arch='x86_64' machine='q35'>hvm</type>
    <boot dev='hd'/>
    <bios useserial='yes'/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <vmport state='off'/>
  </features>
  <cpu mode='host-model'>
  </cpu>
  <clock offset='utc'>
    <timer name='rtc' tickpolicy='catchup'/>
    <timer name='pit' tickpolicy='delay'/>
    <timer name='hpet' present='no'/>
  </clock>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <pm>
    <suspend-to-mem enabled='no'/>
    <suspend-to-disk enabled='no'/>
  </pm>
  <devices>
    <emulator>/usr/libexec/qemu-kvm</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2' cache='none' io='native'/>
      <source file='/var/lib/libvirt/images/test.qcow2'/>
      <target dev='sda' bus='scsi'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw' cache='none' io='native'/>
      <source file='/var/lib/libvirt/images/test.iso'/>
      <target dev='sdb' bus='scsi'/>
      <readonly/>
    </disk>
    <controller type='scsi' index='0' model='virtio-scsi'>
    </controller>
    <controller type='usb' index='0' model='none'>
    </controller>
    <controller type='virtio-serial' index='0'>
    </controller>
    <interface type='direct'>
      <mac address='aa:00:00:01:00:00'/>
      <source dev='enp0s25' mode='vepa'/>
      <model type='virtio'/>
    </interface>
    <serial type='pty'>
      <target type='isa-serial' port='0'>
        <model name='isa-serial'/>
      </target>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
    <channel type='unix'>
      <target type='virtio' name='org.qemu.guest_agent.0'/>
      <address type='virtio-serial' controller='0' bus='0' port='1'/>
    </channel>
    <memballoon model='virtio'>
    </memballoon>
    <rng model='virtio'>
      <backend model='random'>/dev/urandom</backend>
    </rng>
  </devices>
  <seclabel type='dynamic' model='selinux' relabel='yes'/>
  <seclabel type='dynamic' model='dac' relabel='yes'/>
</domain>

作成したXMLを読み込ませる

virsh define test.xml

VMを起動させる

virsh start --console test