KVMとQEMU
プロセスメモリの仮想化、Java仮想マシン、RubyマシンYARV、ネットワークの仮想化などなど、とかくこの世の中仮想しまくっっている。ということでこの前ハードウェア(CPUと各デバイス)をまるごと仮想化する仕組みKVMとQEMUをCentOS7上で操作してみたので自分なりに用語などまとめてみた。
KVM
KVMってなに?
- カーネル・モジュール。カーネルの機能。ロードするだけで仮想化機能使える。
- 実体はこの
/dev/kvm
デバイスファイル?。これを各プロセスがオープンすることで各プロセスが独自のメモリそしてソフトウェア的なCPU
をもつこと。なのでKVMはこの一連の仕組の枠組みといえるはず。
タイプ
- ハイパーバイザ(完全仮想化)というタイプに分類。完全とはBIOSも含めたハードウェアを全部を仮想化すること。
- 同用語として仮想マシンモニタ
CPU
- KVMを使用するにはCPUが仮想化に対応してないとだめ。対応しているかどうかは簡単にコマンドで調べられる。
- ゲストOSの命令はセンシティブ命令。CPUの仮想化機能はこれを感知するようになっている。
- 仮想化に対応しているCPUはカーネルモード、ユーザーモードの他にゲストモードがある。
- ゲストモード
- 仮想マシン上のOSが動作している間はCPUはこのモードっぽい
- VMX non-root
- 仮想マシン上のOSがユーザーモードの時
- VMX root
- 仮想マシン上のOSがカーネルモードの時。この時CPUは仮想マシン上のOSの命令を感知して
KVMに制御を渡す
。KVMモジュールからソフトウェア的に作成したCPUが実行されるみたいなイメージをもっている。
- 仮想マシン上のOSがカーネルモードの時。この時CPUは仮想マシン上のOSの命令を感知して
- ゲストモード
/dev/kvm
$ qemu-img create -f qcow vm-disk.img 4G
↑例えばこんな感じで実行すると、内部で/dev/kvmが使用されるよう。他にもvirt-managerやvirt-installなどすると/dev/kvmをオープンしてるはずたぶん。要するに仮想マシンを起動?、生成する際に/dev/kvmをオープンしているみたい。あとはオープンで取得したfd(オープンしたプロセスと結びついているファイル構造体など)をもとにkvm_create関数(仮想CPU(その情報を表わせ構造体のこと)を作成)したり、load_file関数によって、指定されたVMのアドレス空間に仮想マシンイメージがロードされるみたい。
詳しくは(こういう詳しい本欲しい)
https://www.ibm.com/developerworks/jp/linux/library/l-linux-kvm/
- 下をみれば起動のイメージが湧く!!
./linux-2.6.20/drivers/kvm/kvm_main.c
int main()
{
void *vm_mem;
kvm = kvm_init(&test_callbacks, 0);
if (!kvm) {
fprintf(stderr, "kvm_init failed\n");
return 1;
}
if (kvm_create(kvm, 128 * 1024 * 1024, &vm_mem) < 0) {
kvm_finalize(kvm);
fprintf(stderr, "kvm_create failed\n");
return 1;
}
if (ac > 1)
if (strcmp(av[1], "-32") != 0)
load_file(vm_mem + 0xf0000, av[1]);
else
enter_32(kvm);
if (ac > 2)
load_file(vm_mem + 0x100000, av[2]);
kvm_show_regs(kvm, 0);
kvm_run(kvm, 0);
return 0;
}
QEMU
KVMは上で述べた様に複数のオペレーティング・システム用にソフトウェア的にメモリ、CPUを仮想化するもの。これに対してQEMUはゲストOSからの入出力I/O(ディスク、ネットワークetc)を仮想化するもの。KVMはこのQEMUの力を借りている。QEMUにもCPUを仮想化する機能があるが、KVMはこの機能を使用せずにCPUの仮想機能を使用して仮想化を実現している。KVMはCPUを仮想化、QEMUはI/Oを仮想化といった具合に分担してマシンを仮想化している。
DOCKER
今度はDOCKER!!!!