libvirt 仮想化ライブラリーの徹底調査

容易な Linux 仮想化のための API

libvirt ライブラリーは Linux の仮想化機能の Linux API です。このライブラリーは Xen や KVM などの多種多様なハイパーバイザーだけでなく、QEMU、そして Linux 以外のオペレーティング・システムを対象とした仮想化製品もサポートします。この記事では libvirt について説明するとともに、その使用方法とアーキテクチャーについても詳しく探ります。

専門知識をお持ちの方へ:  仮想環境でゲスト OS を管理する方法や libvirt が役に立つ場合について、原文記事の終わりにあるコメント欄にコメント (英語) をお寄せください。

M. Tim Jones, Independent author

M. Tim JonesM. Tim Jones は組み込みソフトウェアのエンジニアであり、『Artificial Intelligence: A Systems Approach』、『GNU/Linux Application Programming』現在、第 2 版です) や『AI Application Programming』(こちらも現在、第 2 版です)、それに『BSD Sockets Programming from a Multilanguage Perspective』などの著者でもあります。技術的な経歴は静止軌道衛星用のカーネル開発から、組み込みシステム・アーキテクチャーやネットワーク・プロトコル開発まで、広範にわたっています。また、コロラド州ロングモン所在のEmulex Corp. の顧問エンジニアでもあります。


developerWorks 貢献著者レベル

2010年 1月 05日

Tim とつながるには

Tim は developerWorks で人気の高いお馴染みの著者の 1 人です。Tim が書いたすべての developerWorks の記事を閲覧してみてください。また、My developerWorks では、Tim のプロフィールを調べることや、彼やその他の著者、そして他の読者とつながることができます。

スケールアウト・コンピューティング (クラウド・コンピューティングなど) に関して言えば、libvirt はこれまでにないほど重要なライブラリーの 1 つかもしれません。libvirt は、ホスト上で稼働するゲスト・オペレーティング・システムをセキュアに管理することを目的とした、特定のハイパーバイザーにとらわれない API を提供します。libvirt 自体はツールというわけではありません。libvirt はゲスト・オペレーティング・システムの管理用ツールをビルドするための API であり、抽象化の概念に基づいています。libvirt は、サポートしているハイパーバイザーによって実装される一般的な機能のための共通 API を提供します。libvirt は当初、Xen の管理 API として設計されましたが、その後拡張されて数々のハイパーバイザーをサポートするようになりました。

基本アーキテクチャー

My developerWorks の GReen グループに参加してください

エネルギー、効率性、環境に関するトピックについて議論し、リソースを共有するために、My developerWorks の Green computing group に参加してください。

libvirt のアーキテクチャーと使用方法について詳しく探る前に、まずは libvirt の使用モデルについて説明しておきます。libvirt は、管理アプリケーションで使用するように設計された一連の API として存在します (図 1 を参照)。libvirt はハイパーバイザー固有のメカニズムを介して、使用可能なハイパーバイザーのそれぞれと通信し、API リクエストを実行します。QEMU を使用したこの仕組みについては後で説明します。

図 1. libvirt の使用モデルと libvirt を使用しないモデルとの比較
libvirt の使用モデルと libvirt を使用しないモデルとの比較

上記の図には、libvirt で使用する用語も比較表示されています。これらの用語は API の名前に使用されるため、重要となります。用語の使い方に関してモデル間で異なる基本的な 2 つの点は、libvirt では物理ホストについては「ノード」と呼び、ゲスト・オペレーティング・システムを「ドメイン」と呼ぶ点です (訳注: 図 1 上では左右いずれも一番下の層が Node となっていますが、おそらく左側の図では Node ではなく Physical host と記述するつもりだったと思われます)。libvirt (およびそのアプリケーション) はホスト Linux オペレーティング・システムのドメイン (ドメイン 0) で動作することに注意してください。

制御手段

libvirt では、2 つの異なる制御手段を使えます。まず 1 つは図 1 に示すように、管理アプリケーションとドメインが同じノード上にある場合の手段です。この場合、管理アプリケーションは libvirt を介してローカル・ドメインを制御します。もう 1 つは、管理アプリケーションとドメインが別々のノード上にあり、リモート通信が必要となる場合の制御手段です (図 2 を参照)。この場合には、リモート・ノード上で動作する libvirtd という特殊なデーモンが使用されます。libvirtd は libvirt が新しいノードにインストールされると自動的に起動されて、自動的にローカル・ハイパーバイザーを判別して各ハイパーバイザーのドライバーをセットアップします (これについては、この後すぐに説明します)。管理アプリケーションはローカルの libvirt を介し、カスタム・プロトコルを使ってリモートの libvirtd と通信します。QEMU の場合、カスタム・プロトコルの終端は QEMU モニターです。QEMU にはモニター・コンソールが組み込まれているので、このコンソールを使用して稼働中のゲスト・オペレーティング・システムを検査できるだけでなく、仮想マシン (VM) のさまざまな側面を制御することができます。

図 2. libvirtd によるリモート・ハイパーバイザーの制御
libvirtd によるリモート・ハイパーバイザーの制御

ハイパーバイザーのサポート

多種多様なハイパーバイザーでの拡張性をサポートするために、libvirt はドライバー・ベースのアーキテクチャーを実装します。このアーキテクチャーは、ベースとなる多数のハイパーバイザーに対して共通 API が同じように適用できるようにします。つまり、この API によって、一部のハイパーバイザーが持つ特殊な機能が隠されるということです。さらに、API 関数のすべてを実装していない一部のハイパーバイザーは、特定のドライバー内でサポートされないハイパーバイザーとして定義されます。図 3 に、libvirt API と関連ドライバーの階層を示します。この図では、libvirtd がリモート・アプリケーションからローカル・ドメインにアクセスする手段を提供している点にも注意してください。

図 3. libvirt のドライバー・ベースのアーキテクチャー
libvirt のドライバー・ベースのアーキテクチャー

この記事を執筆している時点で、libvirt は、表 1 に記載するハイパーバイザーのドライバーを実装しています。オープンソース・コミュニティーから新しいハイパーバイザーが登場するにつれ間違いなく、ここに記載されていないドライバーも利用可能になってくるはずです。

表 1. libvirt がサポートするハイパーバイザー
ハイパーバイザー説明
XenIA-32、IA-64、および PowerPC 970 アーキテクチャー対応のハイパーバイザー
QEMU各種アーキテクチャー対応のプラットフォーム・エミュレーター
KVM (Kernel-based Virtual Machine)Linux プラットフォーム・エミュレーター
LXC (Linux Containers)オペレーティング・システムを仮想化するためのLinux (軽量) コンテナー
OpenVZLinux カーネルをベースとしたオペレーティング・システム・レベルの仮想化
VirtualBoxx86 仮想化対応のハイパーバイザー
User Mode Linux各種アーキテクチャー対応の Linux プラットフォーム・エミュレーター
テスト疑似ハイパーバイザーのテスト・ドライバー
ストレージストレージ・プール・ドライバー (ローカル・ディスク、ネットワーク・ディスク、iSCSI ボリューム)

libvirt と仮想化シェル

libvirt のアーキテクチャーをいくつか説明したところで、ここからは libvirt 仮想化 API の使用例を見ていきましょう。最初の例で使用するのは、virsh (仮想化シェル) と呼ばれるアプリケーションです。libvirt の上に位置するこのシェルは libvirt 機能の大部分を使用できますが、対話式 (シェル・ベース) で機能します。このセクションでは virsh を使った VM 操作の側面を、例を用いて説明します。

最初のステップは、ドメイン構成ファイル (リスト 1 に記載) を定義することです。このコードはドメインを定義するために必要なすべてのオプション (ハイパーバイザー (エミュレーター)、ドメインが使用するリソース、周辺環境の構成 (ネットワークなど) に至るまでのすべてのオプション) を指定します。ただし、以下の構成は極めて単純なものであることに注意してください。libvirt がサポートする実際の属性は、これよりも遥かに多様性があり、例えば BIOS やホストのブートローダー、ドメインが使用するリソース、使用されるデバイス (フロッピー・ディスクや CD-ROM、USB、PCI デバイスなど) などを指定することができます。

ドメイン構成ファイルでは、この QEMU ドメインに使用する基本メタデータを定義します。定義するメタデータには、ドメイン名、最大メモリー、使用可能な初期メモリー (現行値)、そしてこのドメインに使用を許可する仮想プロセッサー数などがあります。ここでは UUID (Universally Unique Identifier) を割り当てずに、代わりに libvirt が UUID を割り当てられるようにします。さらに、このプラットフォームでエミュレートするマシンのタイプ (この例では、完全仮想化 (hvm) の 686 プロセッサー)、エミュレーターの場所 (タイプが同じ複数のエミュレーターをサポートする必要がある場合)、そしてドメイン用の仮想ディスクを定義します。この例で指定している VM は、VMDK (Virtual Machine Disk) フォーマットの ReactOS オペレーティング・システムであることに注意してください。最後にデフォルトのネットワーク構成を指定し、グラフィックには VNC (Virtual Network Computing) を指定します。

リスト 1. ドメイン構成ファイル
<xml version="1.0"?>
<domain type='qemu'>
  <name>ReactOS-on-QEMU<name>
  <uuid<uuid>
  <memory>131072<memory>
  <currentMemory>131072<currentMemory>
  <vcpu>1<vcpu>
  <os>
    <type arch='i686' machine='pc'>hvm<type>
  <os>
  <devices>
    <emulator>usr/bin/qemu<emulator>
    <disk type='file' device='disk'>
      <source file='/home/mtj/libvtest/ReactOS.vmdk'/>
      <target dev='hda'/>
    <disk>
    <interface type='network'>
      <source network='default'/>
    <interface>
    <graphics type='vnc' port='-1'/>
  <devices>
<domain>

ドメイン構成ファイルが完成したら、virsh ツールを使ってドメインを開始してください。virsh ツールは実行する特定のアクションに応じたコマンド引数を取ります。新規ドメインを開始する場合は、以下のように create コマンドとドメイン構成ファイルを使用します。

リスト 2. 新規ドメインの開始
mtj@mtj-desktop:~/libvtest$ virsh create react-qemu.xml
Connecting to uri: qemu:///system
Domain ReactOS-on-QEMU created from react-qemu.xml

mtj@mtj-desktop:~/libvtest$

上記では、ドメインに接続するために使用する URI (Universal Resource Indicator) が qemu:///system となっていることに注意してください。このローカル URI は、ローカル QEMU ドライバーのシステム・モード・デーモンに接続します。ホスト shinchan の SSH (Secure Shell) プロトコルでリモート QEMU ハイパーバイザーに接続する場合には、qemu+ssh://shinchan/ という URI を使用します。

次に、virsh 内で list コマンドを使用すると、特定のホスト上でアクティブになっているドメインをリストアップすることができます。以下に示すように、このコマンドによってアクティブ・ドメインと、それぞれのドメイン ID および状態が表示されます。

リスト 3. アクティブ・ドメインのリストアップ
mtj@mtj-desktop:~/libvtest$ virsh list
Connecting to uri: qemu:///system
 Id Name                 State
----------------------------------
  1 ReactOS-on-QEMU      running

mtj@mtj-desktop:~/libvtest$

このリストで定義されている名前は、ドメイン構成ファイルのメタデータで定義した名前です。上記には、このドメインのドメイン ID は 1 で、現在実行中であることが示されています。

suspend コマンドを使用すると、ドメインを一時停止することができます。このコマンドはドメインをスケジューリング対象から外しますが、ドメインはメモリーにそのまま常駐するので、すぐに再開することができます。以下は、ドメインを一時停止し、list コマンドで状態を確認してから、ドメインを再開する例です。

リスト 4. ドメインを一時停止し、状態を確認してから再開する方法
mtj@mtj-desktop:~/libvtest$ virsh suspend 1
Connecting to uri: qemu:///system
Domain 1 suspended

mtj@mtj-desktop:~/libvtest$ virsh list
Connecting to uri: qemu:///system
 Id Name                 State
----------------------------------
  1 ReactOS-on-QEMU      paused

mtj@mtj-desktop:~/libvtest$ virsh resume 1
Connecting to uri: qemu:///system
Domain 1 resumed

mtj@mtj-desktop:~/libvtest$

virsh ユーティリティーは他にも多数のコマンドをサポートします。数例を挙げると、ドメインの保存 (save)、保存したドメインのリストア (restore)、ドメインのリブート (reboot) などがあります。また、実行中のドメインからドメイン構成ファイルを作成することもできます (dumpxml)。

ここまでのところで、ドメインを開始して操作する方法については説明しましたが、ドメインに接続して実際の動作を確認するにはどうしたらよいでしょうか。その場合には、VNC を使用します。VNC を以下のように使用することで、特定ドメインのグラフィカル・デスクトップを表すウィンドウを作成することができます。

リスト 5. ドメインへの接続
mtj@mtj-desktop:~/libvtest$ xvnc4viewer 127.0.0.1 0

libvirt と Python

前のセクションの例ではコマンドライン・ユーティリティー virsh によるドメインの制御を説明したので、今度は Python を使ってドメインを制御する例を見てみましょう。Python は libvirt でサポートされているスクリプト言語で、簡潔なオブジェクト指向のインターフェースを libvirt API に提供します。

以下の例で、virsh ユーティリティーの例で行った操作 (listsuspendresume など) を Python で実行する場合を検討します。リスト 6 に、Python のサンプル・スクリプトを記載します。このスクリプトでは、まず初めに libvirt モジュールをインポートし、続いてローカル QEMU ハイパーバイザーに接続します。そこからは使用可能なドメイン ID を繰り返し処理し、ドメイン ID ごとにドメイン・オブジェクトを作成してからドメインを一時停止、再開、そして破棄します。

リスト 6. Python でドメインを制御する場合のスクリプト (libvtest.py)
import libvirt

conn = libvirt.open('qemu:///system')

for id in conn.listDomainsID():

	dom = conn.lookupByID(id)

	print "Dom %s  State %s" % ( dom.name(), dom.info()[0] )

	dom.suspend()
	print "Dom %s  State %s (after suspend)" % ( dom.name(), dom.info()[0] )

	dom.resume()
	print "Dom %s  State %s (after resume)" % ( dom.name(), dom.info()[0] )

	dom.destroy()

これは単純な例ですが、この例から、libvirt が Python を介してもたらす威力を理解できるはずです。つまり、単純なスクリプトによって、ローカル QEMU ドメインのすべてを繰り返し処理し、ドメインに関する情報を出力してからドメインを制御することができます。リスト 7 に、このスクリプトによる出力を記載します。

リスト 7. リスト 6 の Python スクリプトによる出力
mtj@mtj-desktop:~/libvtest$ python libvtest.py
Dom ReactOS-on-QEMU  State 1
Dom ReactOS-on-QEMU  State 3 (after suspend)
Dom ReactOS-on-QEMU  State 1 (after resume)
mtj@mtj-desktop:~/libvtest$

API の概要

全体的に見ると、libvirt API はハイパーバイザー接続 API、ドメイン API、ネットワーク API、ストレージ・ボリューム API、そしてストレージ・プール API という 5 つのセクションに分けられます。

libvirt の通信は常に、指定されたハイパーバイザーへの接続が確立されてから行われます (例えば、リスト 6open 呼び出しを参照)。この接続により、その他すべての API が操作に使用するパスが提供されます。C の API では、この接続の振る舞いは virConnectOpen 呼び出し (および認証用のその他の関数呼び出し) によって行われます。これらの関数のレスポンスは、ハイパーバイザーへの接続を表す virConnectPtr オブジェクトです。このオブジェクトはその他すべての管理機能の基盤としての役割を果たすため、指定されたハイパーバイザーに対する API 呼び出しを以降で行う際に必須の引数となります。以降の呼び出しで重要なのは、ハイパーバイザーとドライバーの両機能を返す virConnectGetCapabilities、そしてノードに関する情報を取得する virNodeGetInfo です。情報は XML 文書として返されるので、この XML 文書を構文解析することで、どのような振る舞いが考えられるかを理解することができます。

ハイパーバイザーにアクセスした後は、一連の API 呼び出しによって、そのハイパーバイザー上のさまざまなリソースを繰り返し処理することができます。例えばハイパーバイザー上のアクティブ・ドメインを表すドメイン識別子の一覧を返すには、virConnectListDomains API 呼び出しを使用します。

libvirt API は、ドメインを対象とした数多くの関数を実装しています。ドメインを調査または管理する際にまず必要なのは、virDomainPtr オブジェクトです。このハンドルを取得するにはいくつかの方法があります (ID、UUID、またはドメイン名のいずれかを使用した方法)。引き続きドメインを繰り返し処理する例を用いると、この関数が返す索引リストを使って virDomainLookupByID を呼び出すことで、ドメイン・ハンドルを取得することができます。ドメイン・ハンドルを取得すれば、後はドメインの調査 (virDomainGetUUIDvirDomainGetInfovirDomainGetXMLDescvirDomainMemoryPeek) からドメインの制御 (virDomainCreatevirDomainSuspendvirDomainResumevirDomainDestroyvirDomainMigrate) に至るまで、数々の操作を実行することができます。

libvirt API を使って仮想ネットワークとストレージ・リソースを管理したり、検査したりすることも可能です。API のモデルに従い、仮想ネットワークを管理および検査するには virNetworkPtr オブジェクトが必要です。一方、仮想ネットワークのリソースを管理するには virStoragePoolPtr (ストレージ・プール) または virStorageVolPtr (ボリューム) オブジェクトが必要となります。

libvirt API はイベント・メカニズムもサポートします。イベント・メカニズムには、特定のイベント (ドメインのブート、一時停止、再開、停止などのイベント) が発生した場合に通知を受けられるように登録することができます。


言語バインディング

(C++ をサポートする) C で実装された libvirt ライブラリーは、Python に対する直接サポートを組み込んでいますが、数々の言語バインディングもサポートしています。Ruby、Java™ 言語、Perl、および OCaml を対象としたバインティングはすでに実装されています。また、C# から libvirt を呼び出すための取り組みも行われました。libvirt は最もよく使われているシステム・プログラミング言語 (C および C++) と多種多様なスクリプト言語、さらには統合的な関数型言語 (Objective caml) もサポートします。つまり、焦点としている言語が何であれ、libvirt がドメインを制御するための道筋を提供するというわけです。


libvirt を使用したアプリケーション

この記事では機能のほんの一部を紹介しただけですが、libvirt がもたらす威力は理解していただけたはずです。そしてご想像の通り、libvirt をベースに作成されて成功を収めているアプリケーションはいくつもあります。そのうち興味深いアプリケーションの 1 つは、この記事でも取り上げた仮想化シェルの virsh です。また、オペレーティング・システムのディストリビューションから新規ドメインをプロビジョニングするために使用できる virt-install というアプリケーションもあります。virt-clone というユーティリティーを使用すれば、別の VM から VM を複製することもできます (オペレーティング・システムとディスクの両方を複製)。高度なアプリケーションとしては、汎用デスクトップ管理ツールの virt-manager、そして VM のグラフィカル・コンソールへのセキュアな接続を実現する軽量のツール、virt-viewer が挙げられます。

libvirt をベースに作成されたツールのなかでとりわけ重要なのは、oVirt です。oVirt VM 管理アプリケーションは、1 つのノードにある単独の VM でも、あるいは何百ものホストに散在する何千もの VM でも管理できるように設計されました。このアプリケーションは多数のホストと VM を簡単に管理できるようにするだけでなく、クラスタリングおよびロード・バランシングを自動化するために使用することも可能で、複数のプラットフォームおよびアーキテクチャーで機能します。


さらに詳しく調べてください

この短い記事からわかるように、複数のシステムからなる大規模なネットワークの多種多様なハイパーバイザー環境でドメインを管理するアプリケーションを構築するには、libvirt はまさにうってつけのライブラリーです。クラウド・コンピューティングの人気が高まるなか、それとともに libvirt も成長し、新しいアプリケーションとユーザーを増やしていくことは間違いありません。この記事を執筆している時点で、libvirt は登場してからわずか 4 年余りしか経っていません。極めてスケーラブルなコンピューティングの世界では比較的新しい存在なので、今後も機能が追加されていくことは確かです。

参考文献

学ぶために

製品や技術を入手するために

  • libvirt を使用した Red Hat の oVirt オープン VM 管理プラットフォームは、どのような種類のアプリケーションを構築できるかを明らかにしています。多数のホストを管理するために使用できる oVirt は拡張も容易で、何千もの VM をサポートできます。
  • この記事では QEMU 上のドメインを説明する手段として ReactOS を使用しました。QEMU に関するこの記事では、QEMU プラットフォームで簡単に実行できる ReactOS (Windows® の無料クローン) について詳しく説明しています。
  • developerWorks から直接ダウンロードできる IBM 試用版ソフトウェアを使用して、Linux で次の開発プロジェクトを構築してください。

議論するために

  • My developerWorks コミュニティーに加わってください。ここでは他の developerWorks ユーザーとのつながりが持てる他、開発者主導のブログ、フォーラム、グループ、ウィキを調べることができます。

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Linux, Cloud computing
ArticleID=465663
ArticleTitle=libvirt 仮想化ライブラリーの徹底調査
publish-date=01052010