前回は qemu (kvm) の画面周りを設定し、Host と Guest の間で Cut & Paste できるようにした。また、初期状態の「ユーザーモードネットワーク」だと Host から Guest に接続できない事が分かった。
hiro20180901.hatenablog.com
Windows10 Hyper-V 仮想マシンだと ssh で入って色々出来ていた。このままだと不便なのと、ArchLinux Wiki でオススメされているようなのと、Guest 間や Host との通信を一度ちゃんと理解しておきたかった事から、virtio を試してみた。
virtio (block, network)
準仮想化 (Paravirtualization) された I/O framework が virtio である。真面目に全部を仮想化すると無駄が多いので、Guest 側に driver (Windows 版もある) を入れて Host 側と協調する事で効率的に動かそう、という技術だと理解した。仮想環境について調べていると英語の記事が見つかり Paravirtualization という単語がよく出てきて、その時には理解できなかったが、やっと意味が分かった。
次の Qiita の記事が、リンク先を含めて参考になった。
qiita.com
ArchLinux Wiki も日本語で助かっている。
wiki.archlinux.jp
「9 virtio ドライバーのインストール」の項に記載がある。
debian、ubuntu 共に kernel module が入っていた。
$ find /lib/modules | grep -i virtio_blk.ko /lib/modules/4.9.0-8-amd64/kernel/drivers/block/virtio_blk.ko
block device
virtual disk image を指定するのに、-hda の代わりに -boot order=c -drive file=filename,if=virtio を使用する。今回は Guest は Ubuntu 18.04 なので、grub も fstab も UUID で指定されているので、何も変更しなくても OK。
Host:
$ kvm -vga qxl -spice port=5930,disable-ticketing -device virtio-serial-pci -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 -chardev spicevmc,id=spicechannel0,name=vdagent -boot order=c -drive file=./qemu_image/ubuntu_test_minimal,if=virtio -m 2048 -smp 2 -monitor stdio
体感で分かる位、向上した。
Guest:
$ sudo lsmod | grep virtio virtio_blk 20480 2 $ sudo dmesg -t | grep vda vda: vda1 EXT4-fs (vda1): mounted filesystem with ordered data mode. Opts: (null) EXT4-fs (vda1): re-mounted. Opts: errors=remount-ro input: spice vdagent tablet as /devices/virtual/input/input5
sda の代わりに vda で認識していた。
network
Guest の default では e1000 で動作していた。
Guest:
$ sudo dmesg -t | grep eth0 e1000 0000:00:03.0 eth0: (PCI:33MHz:32-bit) 52:54:00:12:34:56 e1000 0000:00:03.0 eth0: Intel(R) PRO/1000 Network Connection e1000 0000:00:03.0 ens3: renamed from eth0
www.nexia.jp
こちらを参考に、bridge を作成、接続してイチから network を作ってみた。以下、記載なき場合は Host 側での作業となる。
bridge-utils install
bridge を作成するための brctl を入れる。
$ sudo apt install bridge-utils
Host 側の物理 NIC を bridge に接続する
Host の NIC は eth0 ではなく enp3s0 になっている。
# ifconfig enp3s0 0.0.0.0 promisc up # brctl addbr br0 # brctl addif br0 enp3s0 # ifconfig br0 up # dhclient br0
やっている内容は以下の通り。
- enp3s0 の ip address を無効にして、promiscuous mode(Wikipedia) にする
- bridge br0 を作成する
- br0 に enp3s0 を追加
- br0 を up
- br0 に ip address を割り当てる (お家LAN の dhcpd = router から)
だが、LXDE Desktop 環境では、これだけではダメ。上記 1 の段階で、ip address を無効にしても勝手に ip address が振られ、br0 と重なって通信できなくなる。どうしようか...たぶん、dhclient が掴みっぱなしなのか。
# ps x | grep dhclient 1010 ? Ss 0:00 /sbin/dhclient -v -cf /var/lib/wicd/dhclient.conf enp3s0 2278 pts/0 S+ 0:00 grep dhclient # dpkg -S /var/lib/wicd wicd-daemon: /var/lib/wicd # apt list --installed | grep wicd python-wicd/stable,now 1.7.4+tb2-5~deb9u1 all [インストール済み、自動] wicd/stable,now 1.7.4+tb2-5~deb9u1 all [インストール済み、自動] wicd-daemon/stable,now 1.7.4+tb2-5~deb9u1 all [インストール済み、自動] wicd-gtk/stable,now 1.7.4+tb2-5~deb9u1 all [インストール済み、自動] # apt show wicd-daemon ... 略 ... Description: wired and wireless network manager - daemon Wicd is a general-purpose network configuration server which aims to provide a simple but flexible interface for connecting to networks. ... 略 ...
なので、wicd が network の設定を掴んでいそう。
# dpkg -L wicd-daemon | grep etc /etc /etc/dbus-1 /etc/dbus-1/system.d /etc/dbus-1/system.d/wicd.conf /etc/default /etc/default/wicd /etc/init.d /etc/init.d/wicd ... 略 ...
system.d と init.d の2つあるけど、どちらが停止 script かな...
www.debian.org
debian のネットワーク設定を見ると、おそらく init.d の方だろう。
# /etc/init.d/wicd stop
で停止できた。この後で上記の1〜5の設定を行えば、Host は外界と接続された状態となった。最近の新しいやり方で、bridge を自動で設定する方法は後で調べよう。
Guest の virtio-net を bridge に接続する
tap を使うには sudo で実行しないとダメだった。
Host:
$ sudo kvm -vga qxl -spice port=5930,disable-ticketing -device virtio-serial-pci -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 -chardev spicevmc,id=spicechannel0,name=vdagent -boot order=c -drive file=./qemu_image/ubuntu_test_minimal,if=virtio -net nic,model=virtio -net tap,ifname=tap0 -m 2048 -smp 2 -monitor stdio
前回のように spicy で接続すると、お家 router から ip address を渡されて network に接続された状態となった。
Host:
# brctl show bridge name bridge id STP enabled interfaces br0 8000.20cf30877f51 no enp3s0 tap0
ちゃんと bridge に接続されている。Guest 側でも外界に接続できている。ICMP も通るので ping や traceroute も通った。Host -> Guest へ ssh で接続できた。
spicy が落ちた時の error message
GSpice-Message: main channel: opened (spicy:3888): Gdk-ERROR **: The program 'spicy' received an X Window System error. This probably reflects a bug in the program. The error was 'BadMatch (invalid parameter attributes)'. (Details: serial 3384 error_code 8 request_code 139 (RENDER) minor_code 27) (Note to programmers: normally, X errors are reported asynchronously; that is, you will receive the error a while after causing it. To debug your program, run it with the GDK_SYNCHRONIZE environment variable to change this behavior. You can then get a meaningful backtrace from your debugger if you break on the gdk_x_error() function.) Trace/breakpoint trap
殆ど毎回のように起動直後に落ちる。やっぱり不安定だなぁ。2回目からは大丈夫なのだが。変更したoption が悪影響しているのか。別の接続ソフトも探してみる。
結果
- block device (virtual disk image) は体感できる程速くなった。
- network は host 側の bridge に tap で接続できた。TCP/UDP/ICMP も双方向に通り、ssh で Host -> Guest へ接続できた。
調べる事:
- 最近の「新しい」やり方で network、bridge を設定する。起動時から有効に出来るようにする。
- 最近の daemon 起動方法について調べる。
- spycy が落ちる件を調べる。代替があれば試してみる。
libvirt や virt-manager を使うと楽なのは分かっているが、基礎からやらないと身につかない性分だし、裏で動いている事を理解しないで進めるのは気持ち悪いので、今回は qemu (kvm) の command line から直接 option を設定してみた。もう少し試してから virt-manager を使ってみる。