エンジニアなら知っておきたい仮想マシンのしくみ

第1回x86仮想マシンことはじめ

ここ数年、インテルx86系プロセッサを使ったコンピュータ(以下x86システム)で仮想マシンを利用する機会が増えています。

x86システムの上で仮想マシンを使うのはこれまで開発者をはじめITエンジニアが多かったように思いますが、企業のサーバ統合などに広く使われるようになり、今ではWindows 7にXP Modeが搭載されるなど、デスクトップ環境においても広く見かけるようになりました。このように仮想マシン技術はとても身近なものとなってきています。

また、仮想化は、コンピュータリソースの柔軟かつ効率的な運用管理を実現するために用いられ、クラウドコンピューティングの基盤にも用いられる重要な技術のひとつとなっています。

このように、x86システムの仮想化技術はたいへん注目されていますが、その仮想マシン技術がどのようなギミックで実現されているのかを知っているITエンジニアの方は、まだまだ少ないように思います。仮想マシン技術に限ったことではありませんが、その技術のしくみを理解していなければ、⁠これは仮想化できるのか?」⁠これは仮想化して大丈夫なのだろうか?」といった類いの疑問を持った際、適切な判断ができません。

今回、⁠エンジニアなら知っておきたい仮想マシンのしくみ」というテーマで、多くの方のx86仮想マシンの裏側について理解していただくべく、⁠知る人ぞ知る」という状況になっている動作ギミックに光をあてて解説していきたいと思います。

仮想化とはなにか

仮想化とは、1つのコンピュータリソースを分割して複数のように見せたり、逆に複数のコンピュータリソースをまとめて1つのリソースに見せたりする手法を指します。

仮想化(Virtualization)という考え方のはじまりは、1970年ごろのことになります。その頃、コンピュータは非常に高価で、多数の利用者が1つのコンピュータをシェアする運用が一般的でした。しかし、利用者ひとりひとりが別々のOSを使いたいなど、ニーズは多様化していきました。その結果、ひとつのコンピュータを単に共有するのではなく、複数のコンピュータのように分割して利用できるような仕組みが検討、考案されました。それが仮想化のはじまりです。

図1 仮想化前と仮想化後
図1 仮想化前と仮想化後

x86プロセッサの歴史

x86の仮想マシンについて解説するにあたり、まずはインテルCore iプロセッサやCore2プロセッサなどに代表されるx86系のプロセッサについて紹介しておきましょう。

x86系プロセッサの起源は、1978年まで遡ります。1978年に、インテルは、最初のx86系プロセッサとなったIntel 8086を発表しました。このプロセッサは16ビットのプロセッサでした。

x86系プロセッサの元祖 Intel 8086
x86系プロセッサの元祖 Intel 8086

その後、Intel 8086は改良を繰り返され、1983年にはIntel 80386と呼ばれる32ビットのプロセッサを発表します。このプロセッサでは8086互換の機能(リアルモード)に加えて、新たに追加された機能群を利用できる「プロテクトモード」が使えるようになりました。現在わたしたちが使っているx86系のアーキテクチャは、ソフトウェア側から見てIntel 80386の頃に大方完成したと言っても過言ではないでしょう。

その後も、x86系プロセッサのアーキテクチャは何度も刷新されましたが、今でもなお80386の頃の機能を踏襲しています。現在のプロセッサは、過去のものと互換性を維持したまま、より多機能で、より高速で、よりたくさんメモリなどのハードウェアリソースを利用できるようになりました。また、当初は1プロセッサあたり1コアのみ実装されていましたが、今では2コア、4コア、そしてそれ以上といった具合に同時に複数の命令を処理できるマルチコアプロセッサになるなど、進化は続いています。

システム仮想マシン

皆さんはどのようか仮想マシン技術をご利用、もしくは興味をお持ちでしょうか。有名な仮想マシンソフトウェアとしてはVMware社によるESX Serverをはじめとする仮想化ソリューションやMicrosoft社によるHyper-V、そのほかオープンソース起源となるKVMやXenなどを目にされることが多いのではないでしょうか。

先に挙げた仮想マシン技術は、どれも下記の特徴を持っています。

  • x86システムの上で動く
  • x86システムを再現する
  • x86システム用のソフトウェア(オペレーティングシステム)が動作する

このような仮想マシンは、x86システムの機能(CPU、メモリ管理、その他のI/Oデバイスなど)をプログラム的に再現し、x86システム用ソフトウェアの実行が可能な仕組みとなっています。便宜上、本連載ではこのような仮想マシンを、x86仮想マシンと呼びたいと思います。また、x86仮想マシンのように、オペレーティングシステムが実行できる特徴を持つ仮想マシンのことを、システム仮想マシン(System Virtual Machine)と呼びます。

最近の市販ゲーム機には、過去のゲーム機向けのソフトウェアをインターネットからダウンロードして遊べる機能が搭載されています。これらの機能は、旧式ゲーム機をソフトウェア的に再現した仮想マシンが用意されており、その上で旧作ゲームを実行する仕組みとなっています。これらも、広義のシステム仮想マシンのひとつと言えます。

プログラムを実行するための「プロセス仮想マシン」

仮想マシンが使われる別のケースとして、コンピュータ環境に依存しないように作られたプログラムを特定のコンピュータ環境上で実行するための仮想マシンソフトウェアが存在します。これらの仮想マシンは「開発したプログラムが、多数あるターゲット環境でも問題なく実行できる」ように使われます。このような仮想マシンをプロセス仮想マシン(Process Virtual Machine)と呼びます。

プロセス仮想マシンの一番身近な例としては、携帯電話のアプリ機能が挙げられるでしょう。現在入手できる携帯電話の多くには、Java言語で作られたアプリを実行するための仮想マシンが搭載されています。どの端末でも、キャリア等で決められたプロファイル(実行環境の仕様)を守っているため、多数ある携帯電話端末が別々のハードウェア構成をとっていても、アプリの互換性が提供されているのです。

図2 携帯電話とJava仮想マシン
図2 携帯電話とJava仮想マシン

Java言語のほか.Net Frameworkも仮想マシン技術により成り立っています。Java言語で作られたプログラムは、コンパイラによりオブジェクトコードに変換され、それを使用するコンピュータ環境用Java VMの上で実行します。.Net Frameworkも基本的には同じ仕組みとなっていますが、Java言語のような専用プログラミング言語ではなく、.Net Frameworkに対応するプログラミング言語であれば開発に利用できるという特徴があります。

図3 .Net Frameworkと仮想マシン
図3 .Net Frameworkと仮想マシン

そのほか、日本発のプログラミング言語Rubyもバージョン1.9.0からYARV(Yet Another Ruby VM)と呼ばれる仮想マシン機能が追加されました。これにより、Ruby言語のプログラムは一度中間言語にコンパイルされてから、同仮想マシンの上で実行されるようになり、実行速度が改善されました。

このような仮想マシンを、プロセス仮想マシン(Process Virtual Machine)と呼びます。本連載ではプロセス仮想マシンについて深く解説しませんが、これらの仮想マシン技術もすでに広く使われています。皆さんも無意識のうちに、これらさまざまな仮想マシンの恩恵を授かっていることでしょう。

x86仮想マシンで何ができるのか

まだx86仮想マシンを使ったことがない方もいらっしゃると思いますので、x86仮想マシンがどのようなものかについて簡単に説明しましょう。

コンピュータを動かすためには、オペレーティングシステム(OS)が必要です。皆さんが利用しているコンピュータにも、多くの場合、Windows、Mac OS、もしくはLinuxなどのOSがインストールされていることでしょう。オペレーティングシステムは、OSの核となるカーネル(kernel)および周辺プログラムから構成されるソフトウェアで、アプリケーションプロセスを起動・実行・停止したり、メモリやデバイスなどコンピュータが持っているハードウェアを管理し、アプリケーションプロセスに割り当てたり入出力処理を請け負ったりしています。また、ひとつのOS上で同時に複数のソフトウェアを実行するマルチタスク機能、不正な処理をしたソフトウェアを検出し強制終了させる等の保護機能なども、OSの大事な役割です。

では、x86仮想マシンを使うことでどのようなメリットがあるのでしょうか?

x86向けのOSは 、OSはコンピュータのハードウェアリソースを全て管理することが前提となっています。このため、基本的には、ひとつのコンピュータ上で複数のOSを同時実行できません。たとえば、WindowsとLinuxを同時に使いたければ、コンピュータをOSの数だけ準備する必要があります。

ここで、仮想マシンの出番です。仮想マシンを使うと、1台のコンピュータを複数のコンピュータのように扱うことができるため、WindowsとLinux、異なるバージョンのWindows環境を1台のコンピュータ上で共存・同時実行することなどが可能となります。

図4 仮想マシンの仕組み
図4 仮想マシンの仕組み

利用者がx86仮想マシンを使う動機はさまざまです。Windows環境とLinuxなどのPC UNIX環境を同時利用したり、業務環境、開発環境、試験環境や独立したテスト環境をひとつのコンピュータ上に共存させたり、ユーザが日常業務を進めるための仮想デスクトップ環境を提供したり、コールセンターにおいてサポート対象の各種システム環境を切り替えたりなど、いろいろな活用法があります。

完全仮想化と準仮想化

システム全体を仮想化する「システム仮想マシン」について紹介していきますが、システム仮想マシン自体もいくつかの実装方式が存在します。ここでは、x86マシンの仮想化手法として、オープンソースの仮想マシンソフトウェアXenがサポートする完全仮想化と準仮想化を紹介しましょう。

ひとつめに、実機と同一のOSカーネルをそのまま使用する方式があります。これは、ソフトウェア処理により構築された仮想ハードウェア上で、これまでと同じソフトウェアを実行します。仮想マシン上で動作するOSは「そこに本物のハードウェアがある」と錯覚した状態で動作するため、使用するOS側に別途変更を加える必要がない点が魅力ですが、そのかわりに仮想マシンの実装は複雑になりがちです。特にXenの世界において、この方式を完全仮想化(Full Virtualization)と呼んでいます。VMware、Hyper-V、KVM、Xenなどの主要な仮想マシンソフトウェアは、完全仮想化の方式をとっています。

ふたつめに、OSが仮想マシン上で実行されることを前提に、仮想マシンソフトウェアが上位に提供する環境にあわせたOSカーネルを用意する方式があります。この方式を準仮想化(Para Virtualization)と呼びます。準仮想化の場合は、仮想環境で実行されるゲストOSが仮想マシンソフトウェアと協調動作する仕組みとなり、仮想マシンソフトウェアによるオーバーヘッドが少なく済みます。

図5 完全仮想化と準仮想化
図5 完全仮想化と準仮想化

では、完全仮想化と準仮想化のメリット、デメリットは何でしょうか?

理由については次回以降に解説していきますが、もともとx86システムのアーキテクチャは仮想化に適していません。そのため、完全仮想化を実現しようとすると効率が悪かったことに加え、オープンソースの仮想マシン技術であるXenが準仮想化の手法により高い性能を示していたため、準仮想化が注目されました。

しかし、最近はx86プロセッサやチップセットなどが提供する仮想化機能の性能が向上してきており、性能目的のために OSカーネルを別途準備することによるメリットは薄れてきています。ハードウェアの性能改善の結果、完全仮想化はこれまでの物理環境とほぼ同じ感覚でOSを利用でき、しかも準仮想化に近い性能が出せるようになってきたこともあり、現在ではx86システムの仮想化手法としては完全仮想化が主流となっています。

おすすめ記事

記事・ニュース一覧