KVM/QEMU上の仮想マシンに対して,libvmiを使ってみる
環境
- Debian 9.4.0
やっていくこと
- libvmiとは
- KVM/QEMUとは
- VirtualBoxでNested Virtualizationはできない
- 仮想化でない(USBブートした)Debianの上で,KVM/QEMUを動かす.
- libvmiのサンプルプログラムを実行.
libvmiとは
libvmiとは,virtual machine introspection
の略である.
monitor the low-level details of a running virtual machine
このライブラリは,実行中の仮想マシンに対して,低いレイヤー,メモリの状態や,プロセスの状態などを監視することを実現するためのAPIを提供しているライブラリである.
サンプルコードも提供されており,これを実行することで,大雑把な動きを理解することができる.
対応している仮想化のプラットフォームは,KVM/QEMU
及び,Xen
.
今回の記事では実際にこれを実行して結果を得られるところまで書く.
KVM/QEMUとは
もともと,この記事で扱っているテーマは,自分が今期やっていく研究の準備として行ったものである.今までは,VirtualBoxとDocker以外での仮想化をやったことがなかった.
KVM/QEMUという単語すら聞いたことない状態でのスタートだったため,まずはこれらの前提知識を調べるところから始まった.libvmiがどこでどのように動いているものなのかを大雑把に把握するためにも,KVM/QEMUについて簡単にまとめる.
KVMとは,Linuxカーネルに実装された仮想化の方法である.この機能を使うためにはいくつか条件がある.詳細については,後々解説する.
マシンの構成は,主にプロセッサ,メモリ,I/Oがあるが,KVMはこれらのうち,プロセッサの仮想化を担当している.
KVMは単体では動作せず,QEMUと組み合わせて使う.QEMUは,このアーキテクチャにおいては,メモリとI/Oを担当している.(QEMU自身でプロセッサの仮想化をすることもできるが,遅い)
単語の関係性として,仮想化の手段として,VirtualBox
と,KVM/QEMU
,QEMU
は並列に考えることができる.その中で,今回はlibvmiを動かすために,KVM/QEMUという方法を選択するというだけ.
また,これらはVirtualBoxのように仮想マシンをGUIで簡単に操作・管理できるソフトウェアが存在しない(正確に言えば普通にあるが,名前が違い,それらの関係性を把握するのも初見だと難しいので,下で解説)
virt-manager/virshとは
virt-manager
とは,KVM/QEMU
で起動している仮想マシンを操作・作成・管理などを行えるソフトウェアである.VirtualBoxは,KVM/QEMUのような,実際に仮想化を担当する部分と,virt-managerのようにそれらを管理する機能を一つのソフトウェアとしてまとめたものであると考えることができる.
virsh
は,あまりちゃんと使ってないのでうまく説明ができないが,これらの管理をシェルで実行できるようにしたもの,というイメージが正しそう.
関係性をシンプルにまとめた図として,以下のページの画像が非常に参考になる.
「Virtual Machine Manager で VM を管理する」の「図 1. QEMU を使用した virt-manager スタックの概略図」
VirtualBoxでNested Virtualizationはできない
今回の環境は,仮想化されたLinuxではなく,USBブートしたLinux上としている.
これはKVMが動くかどうかに依存しており,結論からいうとVirtualBoxの上では,KVMは動作しない
引用になってしまうが,
これらのうち,Intel VT
を搭載したプロセッサというのが,ハマるポイントになりうる.自分の調査不足かもしれないが,VirtualBoxで起動したマシンでは,プロセッサはこの機能を搭載していない(ように見える).
これをチェックする方法は以下.
cat /proc/cpuinfo | grep vmx # flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch epb invpcid_single kaiser tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid rdseed adx smap intel_pt xsaveopt dtherm ida arat pln pts # etc...
このコマンドを叩いて,出力が得られれば,とりあえずKVMは動くという認識.
VirtualBox上のDebianでは出力を得られなかった,
よって,USBブートという選択をした.研究用だし壊れたら作り直せばいい
Debianの上で,KVM/QEMUを動かす.
では,実際にこれらを動かすために必要なツールを入れていく.
前提として必要なツール
sudo apt install make automake gcc git vim
KVM/QEMU
sudo apt install -y qemu-kvm libvirt0 virt-manager bridge-utils qemu-system-x86 sudo reboot sudo gpasswd libvirt -a debian # debianというユーザー名
これが入ったら,qemuのバージョンを確認しておく.
qemu-x86_64 --version # qemu-x86_64 version 2.8.1(Debian 1:2.8+dfsg-6+deb9u4) # Copyright (c) 2003-2016 Fabrice Bellard and the QEMU Project developers
この結果が,2.8.0以上だった場合,libvmiをビルドする前に少しコードをいじる必要がある.
libvirt
参考:libvmiで仮想マシン内部のプロセス一覧を取得...できなかった
apt install
でこける場合は,一旦そのパッケージはスルー.
sudo apt install libyajl-dev libnl-3-dev libnl-route-3-dev libdevmapper-dev libpciaccess-dev wget http://libvirt.org/sources/libvirt-3.0.0.tar.xz xz -d libvirt-3.0.0.tar.xz tar xf libvirt-3.0.0.tar cd libvirt-3.0.0 ./configure make sudo make install sudo systemctl start libvirtd sudo systemctl enable libvirtd
libvmi
参考:libvmiで仮想マシン内部のプロセス一覧を取得...できなかった
apt install
でこける場合は,一旦そのパッケージはスルー.
sudo apt install kvm libtool m4 check bison flex libglib2-dev
git clone https://github.com/libvmi/libvmi.git
cd libvmi
デバッグを有効にする.
vim libvmi/debug.h
// 56行目付近のコメントアウトを外す #define VMI_DEBUG __VMI_DEBUG_ALL
また,qemuのバージョンが2.8.0以上だった場合は,以下を編集
vim libvmi/driver/kvm/kvm.c
// 1482行目付近 // before if (major >= 2 && minor >= 8) { // after if (major >= 2 && minor > 8) {
完了したら,ビルド.
./autogen.sh ./configure --enable-xen=no export CPATH='/usr/include/glib-2.0:/usr/lib/x86_64-linux-gnu/glib-2.0/include:glib-2.0' make sudo make install
which vmi-dump-memory
# /usr/local/bin/vmi-dump-memory
この表示が出ればインストールは成功.
ISO
起動するDebianのISOファイルを引っ張ってきて,任意の場所に配置する.
D=https://cdimage.debian.org/debian-cd/current/amd64/iso-cd wget ${D}/debian-9.4.0-amd64-netinst.iso sudo mkdir /var/lib/libvirt/iso sudo mv debian-9.4.0-amd64-netinst.iso /var/lib/libvirt/iso/ sudo chown libvirt-qemu:libvirt /var/lib/libvirt/iso/debian-9.4.0-amd64-netinst.iso
virt-manager # or sudo virt-manager # を実行すると,ソフトウェアが立ち上がる.
この記事に従って,先ほど作成した,/var/lib/libvirt/iso
を表示されるディレクトリに追加し,マシンを作成していく.
自分の設定では,ストレージにあまり余裕がなかったので,以下の設定とした.
- メモリ1024MB
- コア数1
- ストレージ14GB
これで作成を押すと,仮想マシンが作成できる.
libvmiのサンプルプログラムを実行
おそらくKVM/QEMU
が立ち上がっていると思うので,以下のコマンドで確認し,実行する.
# ドメインを取得 sudo virsh list --all # Id 名前 状態 # ---------------------------------------------------- # 3 debian9 実行中 touch ~/memory_dump_1GB sudo vmi-dump-memory debian9 ~/memory_dump_1GB # 時間がかかる
完了すると,およそ1GBのファイルができていると思うので,それを確認してみる
xxd ~/memory_dump_1GB
それっぽい文字列が大量に出てきたら,メモリダンプ成功.
結果
libvmiを動かすことができた.