インフラ●●○○○

仮想マシン

Virtual Machine ・ かそうましん

物理マシンの上にソフトウェアで作った仮想のコンピュータ。OS を丸ごと載せて隔離する、クラウドの基礎技術。

✦ 30秒で試す — 航海クラウドで借りるサーバは、たいてい1台の機械を分けた幻だこの計算を仮想マシンの中で動かすと、物理マシンで直接動かすより?予想してみる

概要

仮想マシン(VM: Virtual Machine)は、1台の物理コンピュータの上にソフトウェアで作り出した「もう1台のコンピュータ」です。CPU・メモリ・ディスク・ネットワークカードといったハードウェアを仮想的に用意し、その上に本物と同じように OS をインストールして動かします。中で動く OS から見れば、自分が物理マシンの上にいるのか仮想マシンの上にいるのか、原則として区別がつきません。

この技術のおかげで、1台の物理サーバの上に、互いに独立した複数のマシンを同居させられます。AWS の EC2 をはじめ、クラウドで「サーバを借りる」ときに手元に来るものの実体は、ほとんどの場合この仮想マシンです。手元の PC で Windows の中に Linux を動かす、といった開発用途でも日常的に登場します。

なぜ生まれたか

仮想マシンの考え方は、実はクラウドよりずっと古く、1960年代のメインフレームにさかのぼります。当時のコンピュータは1台が非常に高価で、多くの利用者で分け合う必要がありました。IBM は CP-40・CP-67 という研究システム(のちの CP/CMS、1972年の製品 VM/370)で、1台のメインフレームの上に利用者ごとの「自分専用のマシン」を作り出し、それぞれが別の OS を動かせるようにしました。1974年には Popek と Goldberg が、ある CPU を効率よく仮想化できるための条件を形式的に示しています。要点は、OS だけが実行してよい特権的な命令(センシティブな命令)が、ふつうのプログラムから実行されたときに必ず CPU の例外(トラップ)を起こすこと。そうであれば、ゲスト OS をふつうの権限で走らせ、危ない命令のときだけ仮想化の層が割り込んで肩代わりできます。

その後、安い PC サーバが普及すると、仮想化はいったん主役を降ります。「1台の物理マシンに1つの役割」が基本になり、アプリケーション同士がライブラリや設定を奪い合って壊れるのを避けるために、物理的に分けるのが確実だったからです。その結果、CPU 使用率が数 % しかないサーバが何十台も並び、購入費・電気代・設置スペースが膨れ上がる無駄が常態化しました。

この無駄に再び仮想化で応えたのが、1999年に VMware が出した x86 向けの製品でした。x86 は Popek と Goldberg の条件を満たしておらず、特権的なのにトラップしない命令がいくつもあったため、素直には仮想化できません。VMware はゲスト OS のカーネルの命令列を実行直前に安全な命令列へ書き換える「バイナリ変換」でこれを回避し、2003年に登場した Xen はゲスト OS 自体を仮想化向けに改造する「準仮想化」という別の道を取りました。仮想マシンは「隔離したい」と「集約したい」という相反する要求を同時に満たし、マシン全体がただのファイル(ディスクイメージ)になったことで、複製・バックアップ・別ハードウェアへの引っ越しも劇的に容易になりました。この性質が、のちのクラウドコンピューティングの土台になります。

詳細

ハイパーバイザと、トラップして肩代わりする仕組み

仮想マシンを実現する中核のソフトウェアを「ハイパーバイザ」と呼びます。ハイパーバイザは物理マシンの CPU やメモリを分割して各仮想マシンに割り当て、ゲスト OS が発行する特権的な命令やハードウェアへのアクセスを横取りして、安全に仲介します。ハードウェア上で直接動く Type 1(ベアメタル型: VMware ESXi、Hyper-V、Xen など。Linux のカーネル自体をハイパーバイザにする KVM もこちらに数えられます)と、ふつうの OS の上のアプリケーションとして動く Type 2(ホスト型: VirtualBox、VMware Workstation など)に大別されます。データセンターやクラウドの基盤は Type 1、開発者が手元で使うのは Type 2 が中心です。

ゲスト OS のふつうの計算はそのまま CPU で実行され、ハイパーバイザが出てくるのは、ゲストが「自分がマシンの主だ」と思ってハードウェアを直接いじろうとした瞬間だけです。このトラップと肩代わりの往復は、次のようになります。

ハイパーバイザCPUゲストOSハイパーバイザCPUゲストOSふつうの計算命令そのまま実行 速い特権的な命令 例 ページ表の切り替えトラップ ゲストを一時停止そのゲストの仮想的なハードウェア状態を更新結果を返して再開

2005〜2006年には Intel VT-x と AMD-V という CPU の仮想化支援機能が登場し、x86 でもこのトラップが素直に起きるようになりました。ただし、初期の支援機能は1回のトラップのコストが大きく、成熟したバイナリ変換より遅い場面も多かったことが VMware 自身の研究で報告されています。流れを決定的に変えたのは、2007〜2008年に加わったメモリ仮想化の支援(Intel の EPT、AMD の NPT)です。ゲスト OS が管理する仮想メモリの番地を、さらに物理メモリの番地へ変換する2段目の翻訳を CPU が自前で行えるようになり、ハイパーバイザがページ表の写し(シャドーページテーブル)を維持し続ける重い仕事が不要になりました。こうして、いまの仮想マシンは多くの処理で物理マシンに近い性能で動きます。

仮想マシンがクラウドを支える

クラウドコンピューティングの IaaS(Infrastructure as a Service)は、巨大なデータセンターに並んだ物理サーバ群の上で、ハイパーバイザが顧客ごとの仮想マシンを切り出して貸し出す仕組みです。2006年に始まった AWS の EC2 は Xen の上で動き、2017年からは KVM を土台に、ネットワークやストレージの処理を専用のカードに逃がした Nitro という仕組みへ移っています。「数分でサーバが1台手に入る」「不要になったら即座に消せる」という体験は、マシンがソフトウェアで作られたただのデータだからこそ成り立ちます。他の顧客と同じ物理マシンに同居していても互いに干渉できない強い隔離も、マルチテナントのクラウドには欠かせない性質です。

ただし、同居は完全にタダではありません。同じ物理マシンの別の仮想マシンが CPU やディスクを使い込むと、自分の性能まで揺らぐ「うるさい隣人」の問題があり、2018年に公表された Spectre・Meltdown のように、CPU の投機実行を通じて隣の仮想マシンのメモリを覗けてしまう脆弱性も見つかりました。隔離の強さは、ハイパーバイザとハードウェアの正しさの上に成り立っています。

スナップショット、イメージ、ライブマイグレーション

仮想マシンのディスクやメモリの状態は、ある瞬間のコピー(スナップショット)として保存できます。危険な変更の前にスナップショットを取り、失敗したら巻き戻す — 物理マシンでは考えられなかった運用です。OS とミドルウェアをセットアップ済みのディスクイメージ(AWS の AMI など)をテンプレートとして用意しておけば、同じ構成のサーバを何台でも複製できます。これがスケーリング、特にサーバの台数を増やすスケールアウトの基本手段です。さらに、動いている仮想マシンのメモリを別の物理マシンへ少しずつ写し、最後の一瞬だけ止めて切り替える「ライブマイグレーション」を使えば、利用者を止めずに物理マシンを保守できます。

コンテナとの対比

仮想マシンの弱点は「重さ」です。1台ごとに OS を丸ごと抱えるため、イメージは数 GB 規模になり、起動にも数十秒から数分かかります。同じ OS を何十個も動かすなら、同じカーネルを何十回も動かしていることになります。この重さを嫌い、カーネルを共有したままプロセスの見える範囲だけを切り分ける技術として広まったのがコンテナです。

隔離の強さと引き換えの重さ(仮想マシン)か、軽さと引き換えの浅い隔離(コンテナ)か — 両者はトレードオフの関係にあり、実際のクラウドでは「仮想マシンの上でコンテナを動かす」という重ね着が標準的な構成です。セキュリティの境界として強い隔離が要る場面、Windows など異なる OS を動かしたい場面では、いまも仮想マシンが選ばれます。両者の中間として、AWS Lambda の土台である Firecracker のように、機能を削って1秒未満で起動する軽量な仮想マシン(マイクロ VM)も使われています。

仮想マシン方式コンテナ方式VM 1アプリライブラリゲストOSカーネルごとVM 2アプリライブラリゲストOSカーネルごとハイパーバイザ物理マシンアプリライブラリアプリライブラリアプリライブラリコンテナコンテナコンテナホストOSのカーネル1つを全コンテナで共有namespaces と cgroups で区切る物理マシン
層構造の比較 — 仮想マシンは VM ごとに OS を丸ごと抱え、コンテナは1つのカーネルを共有する

金の枠が「カーネル」です。仮想マシン方式では VM の数だけカーネルが動き、コンテナ方式では1つだけです。隔離の境界がどこにあるか — ハイパーバイザか、共有カーネルの中か — が、重さと隔離の強さの違いをそのまま決めています。コンテナの側から同じ構造を確かめたいときは、コンテナの記事の部品で、ホストとコンテナの視点を切り替えてみてください。

試問

仮想マシンの中で動くゲスト OS は、自分が本物の機械の主だと思って命令を出します。仮想マシンを作るソフトウェア(ハイパーバイザ)は、そのうち一部の命令だけを横取り(トラップ)して肩代わりし、残りは本物の CPU にそのまま実行させます。下の7つの命令や操作が、どちらになるかを考えます。

✦ 命題挑戦中

ゲストOSの中で起きる7つの命令・操作を、CPUがそのまま実行するものと、ハイパーバイザが横取りして肩代わりするものに仕分けよ

CPU がそのまま実行ハイパーバイザは出てこない
ハイパーバイザが肩代わりいったん止めて横取りする

項目を選んでから、入れる箱を選びます