雷禅サーバー構築記(KVMとqemu編)

2019/03/22 2020/05/23

KVM周りの最後の話になります。

ちょっと自分の備忘録も兼ねてまずはKVMのおさらいをします。
KVMによる仮想化によって大きく出てくるキーワードは以下の3つで、それぞれの役割についてもこんな感じです。

  • KVM(Kernel-based Virtual Machine) :
    Linux自体をハイパーバイザにする仮想マシンソフトウェア。
    具体的な構成としてはKVM Kernel Moduleとqemu-kvm が存在し、前者がCPU、後者がメモリとI/Oの仮想化を担当する。
  • qemu :
    これも仮想マシンソフトウェア。ただ、基本的にCPUも含めてPC構成要素を全てソフトウェアで仮想化する。
    WindowsノートにLinuxを入れて、その上でWindowsをゲストで動かせばLinuxもWindowsも動かせてラッキーみたいな甘い考えでXenで試したらあまりの遅さに閉口してqemuにしてみた所、Xenよりはまともに動いてスゲーと思った記憶があります。KVMと絡んでいい感じに成長した模様。
  • libvirt :
    仮想化における各種制御をAPI化したライブラリ。
    別にこれはKVMの為だけではなくこれを使えばXen, VirtualBox, VMwareも制御できる。
    これのCUIであるvirshさえ覚えておけば、統一した操作感でいろいろな仮想化基盤を制御できるという感じ。

で、現在のqemuなのですが、昔は確かqemuというコマンドだったはずだったのが、上記の絡みもあってかqemu-system-x86_64なんてえらく長い名前に変わってます。

おさらい終わったので本題。
ゲスト起動に際しては、qemuとvirsh(libvirt)どちらでも行える訳です。
qemuはqemu独自の起動方法、virshではlibvirtとして統一化された起動方法で。

今回は統一感のあるvirshベースで行こうと決めたのですが、大きな違いは

  • qemu :
    コマンドであるqemu-system-x86_64の後ろにつらつらパラメータを記述しまくるタイプ。
    とんでもなく長くなるパラメータをいちいち試行の為にゼロから打つのは厳しい & 可読性を良くする為、基本は起動用のShellを書くことになる。
  • virsh :
    qemuに相当するパラメータをXMLで用意しておき、これを事前にlibvirtに登録した上で動かすタイプ。
    virsh start macosみたいな感じで簡単に起動できる。

という感じとなります。

今回MacOSをゲスト起動する為に多大な参考となったOSX-KVMもそうなのですが、メインはqemuであってvirsh側(xml設定ファイル)にはあまり力を入れていない模様。
このサイト以外の海外の方もやっぱり設定周りの会話はqemuベースでvirshは殆ど無い。
しかもqmeu, virsh共にパラメータ自体の細かい設定記述が全然情報としてWebに流れてない。情報収集が断片的となり大分キツかったです。

一応動くかわかりませんが、お互いの記述内容を参考までに載せて一旦KVM編は終わりとしておきます。
とはいえこういう感じでバンと貼ってくれてるサイトもほとんど無いのよね…
※注意 : qemu側はvirsh化以降一切触っていないので、virsh側の定義とは一致していない部分も多いです

qemu側(OSX-KVMのboot-macOS-HS.shのカスタマイズ版)

qemu-system-x86_64 -enable-kvm -m 4096 -cpu Penryn,kvm=on,vendor=GenuineIntel,+invtsc,vmware-cpuid-freq=on,$MY_OPTIONS
	  -machine pc-q35-2.9
	  -boot menu=on
	  -smp 4,cores=2 
	  -device isa-applesmc,osk="ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc"
	  -drive if=pflash,format=raw,readonly,file=OVMF_CODE.fd
	  -drive if=pflash,format=raw,file=OVMF_VARS.fd
	  -smbios type=2
	  -device ich9-intel-hda -device hda-duplex
	  -device ide-drive,bus=ide.2,drive=Clover
	  -drive id=Clover,if=none,snapshot=on,format=qcow2,file=./HighSierra/Clover.qcow2
	  -device ide-drive,bus=ide.1,drive=MacHDD
	  -drive id=MacHDD,if=none,file=./mac_hdd.img,format=qcow2
	  -netdev tap,id=net0,ifname=tap0,script=no,downscript=no -device e1000-82545em,netdev=net0,id=net0,mac=52:54:00:c9:18:27
	  -device vfio-pci,host=08:00.0,bus=pcie.0,multifunction=on,x-vga=on,romfile=./HighSierra/vbios.rom
	  -device vfio-pci,host=08:00.1
	  -device vfio-pci,host=09:00.3
	  -vga none
	  -nographic

virsh(XML設定ファイル)

※一部パラメータの値がqemu側と同期取れていない箇所があります。

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
  <name>macos-hs</name>
  <uuid>2aca0dd6-cec9-4717-9ab2-0b7b13d111c3</uuid>
  <title>macOS High Sierra</title>
  <memory unit='KiB'>16777216</memory>
  <currentMemory unit='KiB'>16777216</currentMemory>
  <vcpu placement='static'>8</vcpu>
  <os>
    <type arch='x86_64' machine='pc-q35-2.11'>hvm</type>
    <loader readonly='yes' type='pflash'>/home/hrn/src/osxkvm/OVMF_CODE.fd</loader>
    <nvram>/home/hrn/src/osxkvm/OVMF_VARS.fd</nvram>
    <bootmenu enable='yes'/>
  </os>
  <features>
    <acpi/>
    <kvm>
      <hidden state='on'/>
    </kvm>
  </features>
  <clock offset='utc'/>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>restart</on_crash>
  <devices>
    <emulator>/usr/bin/qemu-system-x86_64</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2' cache='writeback'/>
      <source file='/home/hrn/src/osxkvm/mac_hdd.img'/>
      <target dev='sda' bus='sata'/>
      <boot order='2'/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2' cache='writeback'/>
      <source file='/home/hrn/src/osxkvm/HighSierra/Clover.qcow2'/>
      <target dev='sdb' bus='sata'/>
      <boot order='1'/>
      <address type='drive' controller='0' bus='0' target='0' unit='1'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <source file='/home/hrn/src/osxkvm/HighSierra/highsierra0128.iso'/>
      <target dev='sdc' bus='sata'/>
      <readonly/>
      <address type='drive' controller='0' bus='0' target='0' unit='2'/>
    </disk>
    <controller type='sata' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
    </controller>
    <controller type='pci' index='0' model='pcie-root'/>
    <controller type='pci' index='1' model='dmi-to-pci-bridge'>
      <model name='i82801b11-bridge'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x1e' function='0x0'/>
    </controller>
    <controller type='pci' index='2' model='pci-bridge'>
      <model name='pci-bridge'/>
      <target chassisNr='2'/>
      <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
    </controller>
    <controller type='pci' index='3' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='3' port='0x8'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0' multifunction='on'/>
    </controller>
    <controller type='pci' index='4' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='4' port='0x9'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
    </controller>
    <controller type='pci' index='5' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='5' port='0xa'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
    </controller>
    <controller type='usb' index='0' model='ich9-ehci1'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x7'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci1'>
      <master startport='0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x0' multifunction='on'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci2'>
      <master startport='2'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x1'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci3'>
      <master startport='4'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x2'/>
    </controller>
    <controller type='pci' index='6' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='6' port='0xb'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x3'/>
    </controller>
    <interface type='bridge'>
      <mac address='52:54:00:4d:2f:6e'/>
      <source bridge='br0'/>
      <target dev='tap0'/>
      <model type='e1000-82545em'/>
      <address type='pci' domain='0x0000' bus='0x02' slot='0x02' function='0x0'/>
    </interface>
    <input type='keyboard' bus='usb'>
      <address type='usb' bus='0' port='2'/>
    </input>
    <input type='mouse' bus='ps2'/>
    <input type='keyboard' bus='ps2'/>
    <hostdev mode='subsystem' type='pci' managed='yes'>
      <driver name='vfio'/>
      <source>
        <address domain='0x0000' bus='0x08' slot='0x00' function='0x0'/>
      </source>
      <rom bar='on' file='/home/hrn/src/OSX-KVM/vbios.rom'/>
      <address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
    </hostdev>
    <hostdev mode='subsystem' type='pci' managed='yes'>
      <driver name='vfio'/>
      <source>
        <address domain='0x0000' bus='0x08' slot='0x00' function='0x1'/>
      </source>
      <address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
    </hostdev>
    <hostdev mode='subsystem' type='pci' managed='yes'>
      <driver name='vfio'/>
      <source>
        <address domain='0x0000' bus='0x09' slot='0x00' function='0x3'/>
      </source>
      <address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/>
    </hostdev>
    <hostdev mode='subsystem' type='pci' managed='yes'>
      <driver name='vfio'/>
      <source>
        <address domain='0x0000' bus='0x0a' slot='0x00' function='0x3'/>
      </source>
      <address type='pci' domain='0x0000' bus='0x06' slot='0x00' function='0x0'/>
    </hostdev>
    <hub type='usb'>
      <address type='usb' bus='0' port='1'/>
    </hub>
    <memballoon model='none'/>
  </devices>
  <qemu:commandline>
    <qemu:arg value='-device'/>
    <qemu:arg value='isa-applesmc,osk=ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc'/>
    <qemu:arg value='-smbios'/>
    <qemu:arg value='type=2'/>
    <qemu:arg value='-cpu'/>
    <qemu:arg value='Penryn,kvm=on,vendor=GenuineIntel,+invtsc,vmware-cpuid-freq=on,+pcid,+ssse3,+sse4.2,+popcnt,+avx,+aes,+xsave,+xsaveopt,check'/>
    <qemu:arg value='-vga'/>
    <qemu:arg value='none'/>
    <qemu:arg value='-nographic'/>
  </qemu:commandline>
</domain>

最後に

まぁ、こんな感じでvirshの方がXMLタグ形式という事もあって行が多くなるのでビックリするのと、qemuと同じことをしようとしても違う書き方になっているところが疲れたポイントです…
ちゃんと見ると以外に対して変わりないという事は分かってはきます。

もう一つ気づくまですごく悩まされていたのが、virshのXMLファイルはlibvirtに登録(virsh define xxx.xml)し、起動させた段階でXMLファイルの内容は書き換えらてしまうという事。
タグ外側にある、

<address bus="0x06" domain="0x0000" function="0x0" slot="0x00" type="pci"></address>

のようなaddressタグやNICのmac addressですが、書かなくても良いやつです。勝手に補完されます。
最初これの意味と何を設定したらいいのか分からずに悩まされたのですが、諦めて書かずに動かしたらどうなるかやってみたら勝手に書いてくれた…と。
一応ゲスト稼働中に仮想的にそのデバイスをどのスロットに刺したことにするかの定義みたいです。
なので、どうしても何を書いていいか分からないパラメータは一旦書かないとどうなるか見たほうが早いかもしれません。

あと、qemu→virshへのパラメータ変換に悩むものは、<qemu:commandline>の中にqemuのパラメータのまま書けます。
一部怒られる事もありますが、怒られた内容を見れば大体virsh側の記述で書けるようになります。

これ、スラスラ書ける人いるんだろうか…

ということでKVM編は最後はすごく長くなっちゃいましたがここまでにします。
次はゲストOSでmacOSを入れるに対してのネタ話を。

関連記事

コメントとトラックバック

    コメントはありません

    コメントを残す

    CAPTCHA


    トラックバックURLhttps://e-tune-mt.net/ylab/2282/trackback