Linuxのカーネルに入った仮想化技術「KVM」


 Linuxの仮想化技術(ハイパーバイザー)としては、Xenが有名だが、レッドハットがRed Hat Enterprise Linux(RHEL)にKVM(Kernel-Based Virtual Machine)を標準採用したことで、一気にKVMに注目が集まっている。

 そこで仮想化道場では、数回にわたり、KVMの解説を行っていく。今回は、KVMとどんなハイパーバイザーかということを解説していこう。次回以降に、KVM上で実際に仮想環境を動かして、テストしていく予定だ。

 

KVMはどんな仮想化技術か?

 KVMの最大の特徴は、Linuxカーネルに統合されていることだ。これにより、Xenのように、LinuxにXenという仮想化専用のモジュールを登載するのではなく、Linux自体がハイパーバイザーとして動作する。

 KVMは、Linuxカーネルに統合されていることにより、Linuxカーネルの進化を十分に享受することができる。KVM自体にスケジューラやメモリ管理、省電力対応などの機能を付け加えなくても、Linuxカーネルが持つ機能をそのまま利用できる。つまり、Linuxカーネルの進化が、直接KVMの進化に反映してくる。

 Xenは、独自のスケジューラやメモリ管理をXen自身の中に持っているため、Linuxカーネルの進化にキャッチアップするのが難しい。ただし、KVMより先行して開発されたXenは、多くのユーザーが採用しているため、さまざまな開発や改良がXenコミュニティを行われている。

 KVMでは、Linuxカーネルと統合されているので、多くのアプリケーションにおいてKVMを前提に開発してもらえる。このため、わざわざKVM用のアプリケーションを開発する必要はない。Linux用のアプリケーションがすべてKVM上で動作するというのが理想だが、残念あがら現状では、完全にKVMに対応しているとは言い難い(テストが済んでいなかったり、動作に問題があったりする)。ただ、将来的には多くのアプリケーションがKVMをサポートしていくことになるだろう。

XenとKVMの歴史

 KVMは、イスラエルのQumranetという会社が開発したハイパーバイザーだ。当初は、Xen用の仮想化関連のソフトウェアを開発していたが、Xenでは実現できない機能が数多くあったため、自社でハイパーバイザーを作ることにした。それが、KVMのルーツである。

 KVMの開発自体は、2006年から始まり、2006年10月にオープンソースとして公開した。なんと、その2カ月後の12月にはLinuxのアップストリームにKVMが受け入れられている。そして2007年2月にリリースされたLinux 2.6.20からは、KVMがLinuxカーネルに統合されリリースされている。その後、多くのLinuxディストリビューションでKVMが標準採用されたことで、ハイパーバイザーのKVMに注目が集まった。

 Qumranetは、2008年にRed Hatが買収して、自社の仮想化戦略の中核テクノロジーにしている。実際、RHEL 6からはXenが同梱されずに、KVMがRHELの標準ハイパーバイザーとしてインストールできるようになっている。

 KVMでは、XenやWindows Hyper-Vのような管理ドメイン(Dom0)のような仕組みはない。Linuxカーネル自体にKVMが入っているため、仮想マシンは通常のプロセスとして動作する。また、Xenでは独自にスケジューラーや仮想メモリ機能などを登載しているが、KVMはLinuxのスケジューラーやメモリ管理などの機能をそのまま利用できるため、ハイパーバイザーとしてはライトウェイトなソフトウェアになっている。

 ただ、KVMはハイパーバイザーだけのモジュールのため、実際に仮想マシンを動かすには、QEMUというエミュレータが必須になる。このQEMU各種ハードウェアのエミュレーションなどを行っている。

KVMのアーキテクチャ。カーネルでサポートされているので、通常のLinuxアプリケーションをそのまま動かすことができるXenのアーキテクチャ。Xenは、Linuxカーネルが提供しているさまざまな機能が利用できないため、Xen自身にスケジューリングなどの機能をインプリメントしなければならない
KVMで採用しているメモリモデルKVMとXenのパフォーマンス比較。KVMの方がXenの数倍速い

 

KVMの動作環境は?

 KVMは、CPUの仮想化支援機能が前提となっている。インテルであればIntel VT、AMDであればAMD-Vをサポートがこれに該当するので、CPUをきちんとチェックしておこう。またRHELのKVMは64ビットCPUのみで動作する。

 ただし、KVMの性能を十分に発揮するためには、第2世代の仮想化支援機能(仮想メモリと物理メモリのアドレス空間変換機能)が望ましい。このため、Intel系ならXeon5500以降のCPU(もしくは、第1世代のCore iシリーズ)以降、AMD系ならOpreron 2360/8360/1356以降(Shanghai世代以降。デスクトップCPUではPhenom II以降)のCPUがベストだ。

 動作メモリに関しては、最低2GB、推奨は2GB+VMに割り当てるメモリ総量、となっている。サーバー上の仮想CPU数としては、推奨は実CPUのスレッド数-1がベスト。最大数としては実CPUのスレッド数×10となっている。ただし、Linuxディストリビューションによって、いくつかの制限がある。

 RHEL 6では、仮想CPUの上限が64個(RHEL 5.4は最大16)と機能拡張されている。さらに、KVM利用時のホスト側CPUも256CPUにアップしている(RHEL 6では最大4096CPUをサポートしているが、KVM利用時には256に制限される)。RHEL 6では、メモリ容量は16TBに拡張されている(RHEL 5.4は最大16GB)。メモリ容量の制限は、KVMの制限ではなく、RHEL自体の制限からきている。

 また、仮想NICの数に関しては、RHEL 6では無制限に拡張されている。しかし、仮想NICは、PCIデバイスとして動作するため、PCIデバイスの上限が32のため、これ以上の数は拡張できない(実際は、OS側で4つのPCIデバイスが利用済みのため、28デバイスまでしか拡張できない)。仮想IDEデバイスは、最大4つとRHEL 6とRHEL 5.4で変わらない。

 サポートされるゲストOSとしてRHEL 6では、RHEL3/4/5/6(32/64ビット版)、Windows Server 2003 R2/2008(32/64ビット版)、Windows Server 2008 R2(64ビット版)、Windows 7(32/64ビット版)、Windows XP(32ビット版)などが準仮想化ドライバ(Para-Virtualized Drivers)でサポートされている。準仮想化ドライバにより仮想マシンでも高い性能が発揮できる。Windows Vista(32/64ビット版)に関しては、準仮想化ドライバが用意されていないため、完全仮想化により動作する。ただし、性能的には、準仮想化に比べると大幅に低下する。

 やはり、KVM環境でも、仮想マシンの動作は準仮想化ドライバが必須といえる。準仮想化ドライバに対応していないOSだと、ハードウェアの負荷が高くなり、多数の仮想マシンを性能的に動かすのが難しくなる。

 

RHEL 6での機能強化

CFSでは、各タスクに公平にCPUタイムを割り当てるようにしている
Transparent HugePageを使えば、KVMにおいても性能が向上する

 KVMの機能拡張というわけではないが、RHEL 6ではカーネルの機能を仮想環境にチューニングされている。

 例えば、RHEL 6に登載されたCFS(Completely Fair Scheduler)という新しいスケジューラは、新しいアルゴリズムによって、タスクごとに公平にCPU時間を割り当てる。これにより、ヒューリスティックなインプリメントを廃止している。

 さらに、スケジュールクラスとして、リアルタイムタスククラス、リアルタイムでないタスククラス、アイドルタスククラスの3つのクラスが用意されている。

 もう1つRHEL 6のカーネルにおいて拡張されているのは、HugePageのサポートだ。RHEL5では1ページの大きさは4KBとなっている。しかし、HugePageでは4MBもしくは1GBという大きなサイズになっている。

 HugePageのメリットは、仮想化において大きなメリットがある。仮想メモリアドレスを物理メモリアドレスに変換する場合、CPUのハードウェア支援機能を利用しても、1ページが4KBの場合は4回変換する必要がある。しかし、2MBの場合は3回、1GBの場合は2回で行うことができる。変換回数が少なくなることは仮想化の性能に直結してくる。特に、仮想メモリと物理メモリの変換に関しては、仮想環境上でOSやアプリケーションを動作させるときに、必ず関係してくるため、回数が少なくなればなるほど、仮想マシンを動かす負荷が小さくなる。

 RHEL 6では、NICのドライバに関する改良が行われている。RHEL 6では、DriverとCPU間に複数のポートを用意することで、NICがアイドルにならないようにして、NICの性能が十分に出るように改良されている。これは、今後利用されてくる10Gbpsなどの高速なNICにおいては、大きなメリットがある。

 また、RHEL 6では、Single Root I/O Virtualization(SR-IOV)をサポートしたチップセットとNICカードをサポートしている。SR-IOVにより、NICの仮想化をNIC側で処理してくれる。これにより、サーバー側の負荷が小さくなっている。


Multi Queueにより、NICとDriveが複数のパイプを持つことで、NICの効率がアップするRHEL5と6のネットワーク性能の比較。RHEL 6では、並列度がアップしても、スループットがアップしていく
SR-IOVによりネットワークの性能が向上しているvHost-netにより、仮想環境でネットワークを利用する時に、性能が向上している

 もう1つは、QEMMにvhost-netという機能が追加されている。vhost-netでは、カーネルのコンテキストスイッチがないため、10Gbpsなどの高速のNICを利用する場合、高い性能向上と安定したパフォーマンスを得ることができる。

 またディスクアクセスもNative AIO(NAIO)という機能により、非同期IOの性能を大幅に向上させている。特に、複数の仮想環境を動かした場合、ホストから見れば、ディスクアクセスが非同期になってしまう。これをネイティブでサポートすることで、仮想マシン上でのディスクアクセスの性能を大幅に向上している。


RHEL 6では、SR-IOV、KSMなどにより仮想化を機能強化している今までのvirtioと新しいvHost-netの比較。vHost-netの方が高いパフォーマンスを示しているNAIOにより、仮想化におけるディスクアクセスの性能が向上している

 RHEL 6では、KVMにKernel Samepage Merging(KSM)という機能が用意されている。これは、同じ内容のメモリページは、1つにまとめて、使用する物理メモリを圧縮する機能だ。

 ページサイズが大きくなると、1バイトでも内容が異なとページをまとめることができない。このため、KSMのメリットがあまりでない可能性もある。ただし、KVM上で数多くのRHEL 6を起動した場合は、KSMのメリットが出てくる。


同じ内容のページを1つにまとめるKSMは、同じOSを仮想環境で動かすときにメリットがあるKSMを使えば、同じOSを数多く起動すればするほど、仮想マシンが必要とするメモリが少なくなるこれにより、より多くの仮想マシンが起動できる

 もう1つRHEL 6では、Control Groups(以下C Groups)と機能が追加されている。C Groupsは、プロセスが消費するハードウェアリソースを制限することができる。これにより、優先度の低いネットワークアクセスでネットワークリソースが消費されてしまうのを制限して、優先度の高いネットワークアクセスに高いリソースを割り当てることができる。

 このようなLinuxカーネルの改良により、RHEL 6ではKVMを使った仮想環境の動作性能がアップしている。このように考えれば、RHEL5.xでKVMを利用しているユーザーは、ぜひともRHEL 6ベースにアップした方がいいだろう。


SMPでの性能がRHEL 6は向上している。ベンチマークを行うと、RHEL 6のKVMは数%のオーバーヘッドで動作する。ここまでくると仮想も物理もあまり変わらないかもしれないRHEL 6では、RoCE(RDMA over Converged Ethernet)でRHEL 5.5のInfiniBandを超えるパフォーマンスを、10Gigabit Ethernetで実現している。特に、多くの仮想マシンを起動した環境では、パフォーマンスの差がよくわかる

 次回は、実際にKVMをインストールして、仮想マシンにOSをインストールして動かしてみたいと考えている。

 なおレッドハットでは、KVMに関するセミナーを行っている。KVMに関する機能を紹介する「KVMスタートアップ」(1日)、ハンズオン形式でKVMを使用した仮想マシンのインストール、管理までを紹介する「KVMワークショップ」(2日間)があるので、興味を持たれた方は、受講を検討してみるといいだろう。

 スケジュールに関しては、レッドハットのWebサイトを参照のこと。

関連情報