お疲れ様です、サイオス 那賀です。突然ですが、今どきの仮想マシンにの実現方法としては、おおざっぱに以下の 3 種類があります。
- CPU エミュレーション (インタプリタや、全部バイナリ変換 (Binary Translation))
- QEMU, Bochs など。超重いが、他 CPU の命令実行もできて柔軟。実装が大変
- トラップ実行 (Trap and Execute。TAE とでも?) + 部分バイナリ変換
- (Workstation など、昔ながらの) VMware (実は ESXi でもできるんですが), (昔ながらの) VirtualBox, KQEMU (きわめて残念なことに開発終了) など。ハードウェア支援が不要。CPU 命令をネイティブで走らせるので、そこそこ速い。実装が大変
- ハードウェア支援仮想化 (Hardware-Assisted Virtualization, HAV)
- QEMU virtualizer (QEMU-KVM), Xen-HVM, HAV モードの VMware (ESXi とか), HAV モードの VirtualBox など。intel VT-x や AMD-V が必要。速い、と言われている。実装が(比較的に)簡単
# 何かと面倒な準仮想化 (Para-virtualization, PV) や、OS 仮想化のコンテナ方式については脇に置きます
一般に、前者ほど遅くて後者ほど速いです(初期の VT-x は root, non-root 移行のコストが高くて、むしろ TAE の方が速かったりもしたらしいですが)。最近の実用環境では HAV が主流なのですが、HAV 方式の欠点として、VM 環境上では VM が動かせないことがあります。
# AMD-V だと、VM のスタックができるというウワサを聞きましたが、よく知りません →「Running OpenStack under VirtualBox « System Administration and Architecture Blog」
何がしたいかと言うと、Eucalyptus や OpenStack のような IaaS プラットフォームをお手軽にテストしたいのですが、実マシンをそうそうゴロゴロと用意できない時に、VM 上でテストをできるようにしたいのです。しかし、それらのプロットフォームは、最近の流行からして、開発のプライマリに据えているハイパーバイザが KVM なのです。
これらは、実装的には libvirt 配下で VM ハイパーバイザを動かすようになっているので、理屈上は Xen や VirtualBox でも動きそうなものですが、KVM が開発のプライマリなので、何かと動きません。そもそも、RHEL6 だと Xen の Dom0 も動きませんし、RHEL5 だと Python その他が古すぎて IaaS プラットフォームが動かなかったりもします。
そこで、KVM も動作には QEMU-KVM を使っているので、かわりに QEMU を使うと結構動きます。しかし残念なことに、以前はあった KQEMU による TAE 方式は開発が止まってしまったので、泣く泣く QEMU の CPU エミュレーションモードを使います。
RHEL6 に入っている "qemu-kvm" というコマンドは、実態としては "qemu-system-x86_64" であり、ビルド時に名前を変えているだけです。このバイナリは、KVM のオプションをつければ KVM を利用した HAV 方式で動きますが、KVM を切っておけば、CPU エミュレーションでも動きます。KVM virtualizer 推しのために、emulator をわざと使えなくしているようです。
libvirt-0.8.7/src/qemu/qemu_capabilities.c:
static int
qemuCapsInitGuest(virCapsPtr caps,
virCapsPtr old_caps,
const char *hostmachine,
const struct qemu_arch_info *info,
int hvm)
{
...
if (STREQ(info->arch, hostmachine) ||
(STREQ(hostmachine, "x86_64") && STREQ(info->arch, "i686"))) {
if (access("/dev/kvm", F_OK) == 0) {
...
const char *const kvmbins[] =
{ "/usr/libexec/qemu-kvm", /* RHEL */
"qemu-kvm", /* Fedora */
"kvm" }; /* Upstream .spec */
...
}
if (access("/dev/kqemu", F_OK) == 0)
haskqemu = 1;
}
上記のように、libvirt は、コマンドのパスとモジュールのロード状況に基づいて、その環境上で利用可能なハイパーバイザーを判断しています。よって、RHEL6 でもリンクを張るだけで、libvirt 経由で QEMU のエミュレーションモードが使えるようになります。
# ln -sf /usr/libexec/qemu-kvm /usr/bin/qemu-system-x86_64
これで、VM 上で QEMU の完全仮想化エミュレーションが動くようになります。Virt-Manager 上での表示としては、以下のようになります。
| \ | 「Hypervisor」 | 「Architecture」 |
|---|---|---|
| KVM 有効の virtualizer | 「KVM」 | 「x86_64」 |
| QEMU emulator | 「qemu」 | 「x86_64」 |
以下は、Windows 版の VMware Workstation 上の Scientific Linux 6 (x64) 上の Virt-Manager 上で Scientific Linux (IA32) を動かした例です。
もちろん、とっても遅いです。しかし、動かないよりはマシですので、テスト用に使っています。
では。

0 コメント:
コメントを投稿