目次


クラウド仮想マシンの複製エラーを修正する

ランタイム・イメージ・アクティベーションによる問題解決

Comments

仮想システム・イメージを利用する利点の 1 つは、イメージを複製して、別の異なる環境で再利用できることです。通常、複製したイメージを再利用するには、イメージに含まれるソフトウェア・アプリケーションを再構成するための作業が必要となりますが、ソフトウェアが事前にインストールされている VM を複製するときには、再構成に関する問題が起こりがちです。特に、通常は DHCP をサポートせずに、着信 TCP リクエストを静的アドレスでリッスンする DBserver やAppServer などのサーバー・サイドのサービスを実装するアプリケーションを扱っている場合は、再構成に問題があることは珍しくありません。

このイメージ再構成の問題を解決するために従来使用されているプロセスは、イメージ再アクティベーション (Image Re-Activation) プロセスとして知られています。このプロセスでは、アクティベーション・エンジン (例えば、仮想イメージをブート時にカスタマイズできるようにするためのフレームワークである IBM Activation Engine) を用いた手法や、アプリケーションに固有のアクティベーション・スクリプトを用いた手法が活用されます。

けれども、このような状況でイメージ再アクティベーション・プロセスを使用する場合の問題は、このプロセスでは常に、アプリケーションの構成の誤りをすべて正しく再構成するために実行できる適切なスクリプトの存在が前提となるという点です。

この記事では、この問題を解決するための方法として従来の方法に代わる方法について説明します。この方法は、アプリケーションに関する情報 (元のネットワーク構成が影響している構成成果物に関する情報) がない場合や、アプリケーション固有の構成成果物を修復するために事前ビルドされたアクティベーション・スクリプトを利用できない場合に役に立ちます。VM 内に存在しているアプリケーションがわからない場合や、(アプリケーションがあまり使われていなかったり、つい最近リリースされたアプリケーションであるため文書化されておらず、リバース・エンジニアリングが不可能であったり等々の理由で) VM に存在するアプリケーションに対して使用できる再有効化スクリプトがない場合には、環境に関する情報が不完全になりがちです。

VM を複製した結果、VM 内のソフトウェア・スタックにネットワーク構成の誤りが生じた場合、その誤りを修正するための再有効化スクリプトも、アプリケーションに関する十分な情報もないとしたら、VM を再び有効にするには、私たちが提案する RIA (Runtime Image Activation: ランタイム・イメージ・アクティベーション) と呼ぶ方法がより効果を発揮するはずです。この方法は、個々のアプリケーションにはとらわれません。私たちはサンプル RIA コマンドライン・インターフェースのプロトタイプを作成したので、これを使用して、この記事で説明するネットワーク構成手法を画策あるいは実装することができます。これらの手法を使用すれば、複製による不適切な構成の問題を解決することができます。

完璧な複製を作成することが必ずしも良いとは限りません

クラウド指向の環境では、マシン・プロビジョニングが中心的な機能となります。つまり、定期的に新しい物理マシンがネットワークに接続されたり、新しい仮想マシンが作成されたりします。このような環境では、ランタイム・イメージ (つまり、ディスクの内容全体) が既存のマシンや有用なテンプレートのリポジトリーから複製されることは珍しくありません。

ランタイム・イメージを複製する際に繰り返される問題は、外部環境 (ネットワーク構成の IP アドレスなど) によって変わってくる情報がランタイム・イメージに含まれることです。イメージに組み込まれたオペレーティング・システムやアプリケーションは、必要な再構成を行わない限り、おそらく正常には機能しないでしょう。よくありがちなエラーとしては、例えば以下のものが挙げられます。

  • ネットワーク・ソケットでのバインディング試行が失敗します。
  • 必要なネットワーク・サービスへのアクセス試行が失敗します。
  • ネットワーク上に重複する IP アドレスを公開すると、ランダム接続の失敗、切断、そしてネットワークが不安定になるなどの深刻な問題が間違いなく発生します。

マシンが使用するように構成されている IP アドレスの情報は、オペレーティング・システムの構成ファイルの中にあります。VM を複製した後に最初に行わなければならない作業は、古い IP アドレスを新しい IP アドレスに置き換えることです。この作業は、スクリプトやツールによって、現在使用している特定のオペレーティング・システムに応じた方法でランタイム・イメージの内容を直接操作するという方法で自動化することができます。操作の内容としては、例えば、Linux/UNIX システムの場合には /etc 内のファイルのストリングを置換し、Windows システムの場合にはレジストリーのエントリーを変更したりします。

インストールされているアプリケーションに、ネットワーク構成から導き出される内部構成や、インストール時に取り込まれる内部構成が含まれることはよくあります。例えば、Web サーバーは、HTTP/HTTPS リクエストに対処するときにアドバータイズする IP アドレスやホスト名などの情報を、独自の構成データに保存することがあります。この情報を修正する 1 つの方法は、アプリケーションを再インストールすることですが、これは基本的に、「事前に構成されたマシンの複製を作成する」手法から「マシンを一からインストールする」という手法に変えることを意味します。それでは厄介であり、非効率的です。しかも、仮想マシンを素早く確実に一貫した方法で作成できるというメリットをはじめとする、複製に伴うすべてのメリットが台無しになってしまいます。

VM を複製した後で VM 内のソフトウェアを再びアクティブにするために従来使われているのはどのような手法なのでしょうか。

伝統主義者の手法: すべての構成ファイルを修正する

私たちが、VM 内のソフトウェアを再びアクティブにするために通常採っている手法は、不適切な構成ファイルをその保存場所によらず片っ端から修正することです。これは、ケース・バイ・ケースで個々の構成ファイルを修正するという方法で、皆さんはそのために必要な作業については理解できるはずです。つまり、VM に含まれていなければならないアプリケーションと、それぞれのアプリケーションで行われなければならない操作を極めて正確に把握する必要があります。これらの操作は、マウントされた (実行中でない) イメージでスクリプトとして実行することも、実行中のマシンで最初のブートとして、またはエージェント・レベルで実行することもできます。

この手法では、何を行わなければならないかを完全に把握しているとすれば、最終的に最適な結果が得られます。つまり、アプリケーションは、「正しく」インストールしたアプリケーションとまったく同じように機能するようになります。

その一方で、この手法はかなり危うい手法でもあります。ほんの小さな詳細の変更 (例えば、「ユーザーが構成ファイルを別のパスに移した可能性があるか?」、「ソフトウェアのこのバージョンでは、構成ファイルを古いバージョンと同じ場所に保存しているか?」といったことなど) をしただけでも悪夢のような記録維持の作業が必要になる可能性があります。

アプリケーションに固有の情報を把握せずに構成を修正しようとすると、失敗しがちです。マーフィーの法則を理解しているとしたら、イメージ全体を精査して、古い IP の (テキスト形式またはバイナリー形式の) すべてのオカレンスを新しい IP に置き換えるなどという作業は、決して真剣に検討するような対象にはなりません

それよりも有効な戦略があります。私たちはこの戦略を「ネットワークのトリック」と呼んでいます。

新たな戦略: ネットワークのトリック

関連するソフトウェアについての具体的な情報がなくても、複製された構成のエラーを修正するために代わりに使用できる革新的な手法が、これから説明しようとしている手法です。まずは、シナリオを用意します。

よくあるケースとして、外部から到達可能なデーモンを介してサービスをエクスポートしているマシンについて考えてみましょう。これらのデーモンはインストール時に、それぞれがリッスンすることになる IP アドレスを構成ファイルに保存するので、自らをネットワーク・インターフェースにバインドすることができません。そのため残念ながら、複製したマシンでは起動に失敗するはずです。

アプリケーションの構成ファイルを修正する代わりにネットワーク構成環境の形を変えることで、誤った構成でも動作するようにアプリケーションにトリックを仕掛けます。このトリックを支援するのは、マシン自体のオペレーティング・システムです。

概要

図 1 は、全体のプロセスを説明したものです。

図 1. ソリューションの概要
ソリューションの概要
ソリューションの概要

左側に示されているのが、元のマシン (「ソース・マシン」と呼びます) です。ソース・マシンを複製して、右側のマシン (「ターゲット・マシン」と呼びます。図 1 のラベル 1 を参照) を作成します。ソース・マシンを複製した時点では、ソース・マシン内に 3 つのアプリケーションがインストールされていました。そのうち、App1 はマシンに割り当てられた IP アドレスを自動的に検出できますが、App2App3 はそれぞれの構成ファイル (テキスト形式またはデータベース) に保存された IP アドレスを使用するという設定です。

ターゲット・マシンにとって問題となるのは、古い IP アドレス (IPS) を新しい IP アドレス (IPT。図 1 のラベル 2 を参照) に変更した後、外部クライアントは App1 にしか到達できなくなることです。App2App3 は使用することができません。アドレスとして IPS が設定されたインターフェースにはバインドすることができないことから、この 2 つのアプリケーションを起動することができないためです。

この問題は、どのように解決すればよいのでしょうか?

追加のダミー・ネットワーク・インターフェース (手始めとしてのステップ)

最初のステップとして、追加のネットワーク・インターフェースを作成します。Linux では、必要な数だけインターフェースのエイリアスを作成することができます。例えば、(127.0.0.1/8 として構成される通常の lo の他に) 追加のループバック・インターフェースを作成して、そのインターフェースに古い IP を割り当てるという方法を使えます (図 1 のラベル 3 を参照)。追加インターフェースは、lo のエイリアスとして生成することができます。そのインターフェースは lo:0 として識別されます。あるいは、eth0 デバイスのエイリアスとして eth0:0 を生成することも可能です。

追加インターフェースを作成した後、誤って構成されているアプリケーションは、この偽のインターフェースで起動してバインドできるようになります。ただし、外部マシンからの接続は、まだ受け入れることができません。外部ホストは新しい IP の使用を試みるはずですが、新しい IP が設定されたインターフェースでリッスンするプロセスはないため、パケットは複製されたマシンに到達するとすぐに破棄されてしまいます。

図 2 に、新しいアドレス (IPT) 192.168.31.9 と古いアドレス (IPS) 10.10.9.9 を示します。

図 2. サーバーが起動されると、偽のアドレスへのバインドが行われます
サーバーが起動されると、偽のアドレスへのバインドが行われます
サーバーが起動されると、偽のアドレスへのバインドが行われます

上記の図には、古くて「誤っている」IP にバインドして起動に成功したデーモンが示されています。

次は、カーネル・レベルでのネットワーク・アドレス変換 (Network Address Translation: NAT) のリダイレクトについて検討します。

カーネル・レベルでの NAT リダイレクト

2 番目のステップとして、オペレーティング・システムが新しい IP に着信するすべての接続をインターセプトし、これらの接続を内部でそっと古い IP にリダイレクトするようにします (新しいアドレスを古いアドレスにリダイレクトするということです)。

このリダイレクトは、NAT ルールとして、カーネル・レベルで簡単に設定することができます。NAT リダイレクトがパフォーマンスに重大な影響を与えることはありません。これは、ファイアウォールとゲートウェイで一般に使用されるトリックとしてよく知られています。接続ブローカー (図 1 のオレンジ色の星印) が、リダイレクトを行います。

また、古い IP 宛てのトラフィックが実際にマシンに到達できるように、クライアント・マシンとすべての中間ノードのルーティング・ルールを設定する必要もあります。

最後の注意として、リダイレクトは特定のポートに対して行う必要があります。

NAT が提供するウォッチドッグ・デーモン

newIP から oldIP への変換ルールを普遍的に適用すると、新しい IP で正しくリッスンしているすべてのアプリケーション (例えば、独自の古い構成ファイルから IP アドレスを読み取るのではなく、実行時に IP アドレスを検出できるだけの賢いアプリケーション) が機能しなくなってしまうため、リダイレクトするポートを把握する必要があります。

それでも、アプリケーションに固有の情報が必要になるという事態は避けなければなりません (実際ここでは、どのアプリケーションを修正しようとしているのかを把握していることすら前提にしていません)。そうなると、使用されるポートを自動的に検出する方法が必要になってきます。ポートの自動検出を実現するには、オペレーティング・システムに、古い IP が設定されたインターフェースを介してリッスンされているポートのリストを要求します。

このリストは、Linux では netstat -l を実行することで取得します。取得したリストのポートに合わせて、NAT リダイレクトを調整します。

堅牢性を向上させるために、このスキャンとリダイレクト・フェーズを数秒間隔で繰り返します。それによって、起動に時間がかかるアプリケーションや、ポートを動的にバインドおよびアンバインドするアプリケーションにも対処することができます。

スキャンを実行したり、ブローカーの制御を行ったりする役割を担うのは、ウォッチドッグ・デーモンです (図 1 のラベル 4 と 5 を参照)。

図 3 と図 4 に、ウォッチドッグの動作を示します。

図 3. ウォッチドッグの動作: ウォッチドッグによってリダイレクト・ルールが作成されます
ウォッチドッグの動作: ウォッチドッグによってリダイレクト・ルールが作成されます
ウォッチドッグの動作: ウォッチドッグによってリダイレクト・ルールが作成されます

上記の図ではウォッチドッグが、何者かが 10.10.9.9:80 をリッスンしていることを検出し、192.168.31.9:80 宛てのトラフィックをユーザーにはわからないようにハイジャックして 10.10.9.9:80 にリダイレクトするルールを作成したことがわかります。

図 4. クライアントが正常に接続を確立した様子
クライアントが正常に接続を確立した様子
クライアントが正常に接続を確立した様子

これで、外部クライアントは 192.168.31.9 を指すことによって、サーバーに接続できるようになりました。

  • クライアントの視点からは、マシンには新しいアドレス (192.*) が割り当てられています。
  • サーバーの視点からは、マシンのアドレスは古いまま (10.*) ですが、VM が複製される前と同じように、マシンは着信ネットワーク・リクエストに対応することができます。

まとめると、この手法は以下の作業内容で構成されています。

  • 古い IP を持つダミー・インターフェースを設定することで、構成に誤りがあるデーモンが、ネットワーク構成の問題を生じることなく起動できるようにします。
  • それと同時に、古い IP を設定したダミー・インターフェースに対するリッスン用テーブルの各項目に関してポーリングを行うウォッチドッグ・デーモンをセットアップします。このウォッチドッグ・デーモンは、リスナーを検出すると、新しい IP から古い IP へのポート・リダイレクトを調整します。

サーバーが新しい IP で適切に構成されていることを期待する外部クライアントには、古い IP は見えません。デーモンは、新しい IP にバインドしても、古い IP にバインドしても機能します。これは、オペレーティング・システムによって行われる NAT トリックのおかげです。

しかし、ソリューションをさらに完全にするためには、実質的な再構成のトリックが他にもいくつかあります。

戦略の補強: 構成のトリック

前述の IP エイリアシング・メカニズムは、ここでの目的のほとんどを果たしていますが、以下に挙げる構成のトリックを使用すれば、より完全なソリューションの実現を画策することもできます。

  • ARP (Address Resolution Protocol) フィルタリング
  • 名前解決および DNS プロキシー
  • getHostName() フック

ARP フィルタリング

Linux ホストでの偽のインターフェースの構成には、喜ばしくない副次効果を伴います。それは、偽のインターフェースがローカル・インターフェース (eth0:0ではなく、lo:0) だとしても、デフォルトでは、マシンのあらゆるインターフェースに構成されたすべての IP に対する ARP リクエストが、任意のインターフェースで応答されることです。

これは、偽の IP がクライアントからも何らかの方法で見えるということを意味します (そして実際に、ping 可能になります)。複数の複製を作成する場合や、同じネットワーク・セグメント内にソース・マシンの複数のコピーを作成する場合には尚更のこと、完璧な秘密工作が望まれます。

Linux では、sysctl ネットワーク・パラメーター arp_ignore を 1 に変更することで、このデフォルトの振る舞い (0 は、すべての ARP リクエストに応答することを意味します) を回避することができます。

名前解決および DNS プロキシー

図 1 に示されている複製された VM 内の App2/App3 デーモンが、古い IP (IPS) に加えて (あるいはそれに代わって) ホスト名 (例えば、HNS) への静的参照を維持している場合、名前解決チェーンを操作して、正しい IP が返されるようにする必要もあります。

そのための方法は、古いホスト名 (HNS) の問い合わせに対して新しい IP (IPT) が返されるように、ローカルの /etc/hosts 構成ファイルを更新することです。名前解決プロセスが外部ネーム・サーバーを利用している場合には、チェーンの中で最初に応答するネーム・サーバーとして構成されたローカル DNS プロキシーをインストールします。すると、このプロキシーが、変更された /etc/hosts ファイルに従った応答を返すようになります。

getHostName() フックの使用

重宝するかもしれないもう 1 つの構成戦略は、関数コールを取得する「フック」です。getHostName() 関数をフックして、この関数から返されるのが変更された値 (つまり、古いホスト名) になるようにします。

このフックはプロトタイプ化されており、例えば、root 全体に適用されるようにネストしたり、ある低いレベルのユーザー権限で実行されるプロセスに作用するようにネストしたりするなど、さまざまなユーザー・レベルでネストすることができます。

すべての手法をまとめて適用する

構成プロセス全体を容易にするために、この記事で説明した構成手法を適用できるようにプロトタイプ化された Linux 用 RIA コマンドラインがあります。

以下に、RHEL 仮想システムでの構文と使用例を記載します。

./ria start -oh <oldhostname> -oi <old_ipv4> -ni <new_ipv4> [options]
./ria stop | status

./ria start -oh oldhostname.domain.com -oi 10.10.1.1 -ni 1.2.3.4 -ipalias -hnresolv -dnat

まとめ

この記事で紹介した手法を実際に実装したところ、非常に効果があることが証明されました。テストに使用したのは、Web サーバー (Apache) とアプリケーション・サーバー (IBM WebSphere Application Server) がホストする、静的 IP の構成を使ってインストールしなければならない環境です。VM を複製した後、この環境は機能しなくなりました。ソフトウェア・スタックがバインドする対象、リッスンする対象、そして受け付ける対象は、アプリケーション固有の構成成果物に保存された古い IP 構成のままになっていたためです。

RIA 手法によってこの問題は回避され、サーバー・ソフトウェア・スタックは、まだ古い環境内にあると認識しているにも関わらず、新しい環境で機能できるようになりました。この手法には、主要な製品の使用ケースのリグレッション・テストが必要です。

イメージ再アクティベーションの手法は、常に検討すべき有効な代替手段であることを忘れないでください。古いアプリケーション構成を「取り除き」、新しい構成に置き換えることを目的としたイメージ再アクティベーションは、「外科的」で明確な手法です。ただし、コストがかかるため、最善の手法にはならない場合があります。

けれども、イメージ内のアプリケーションに関する情報がなく、投資計画もなく、ソフトウェア・アプリケーションに組み込まれた構成を変更する方法が文書化されていない場合には、例外なく、個々のアプリケーションにとらわれない RIA 手法を検討するべきです。

これに対してユーザーが次のような難点を指摘する可能性があります。それは、アプリケーションが起動されてから、NAT デーモンがリダイレクトを調整するまでにはタイムラグがあることです。その数秒の間には、何が起こるのでしょうか。

外部クライアントには単にサービスが使用不可能のように見えるというのが、その答えです。外部クライアントの視点からは、数秒後に、サービスが正常に開始したように見えます。適切なポーリング間隔を使用していれば、重大な悪影響はないはずです。例えば、数分の間は 1 秒間隔でポーリングし (起動しているものをすぐに捕捉するため)、その後はポーリングを 5 秒間隔から 10 秒間隔に緩めてください。

RIA 手法は、クラウド・プロビジョニング・ソフトウェアに簡単に組み込むことができ、Tivoli Cloud Management スタック (TSAM (Tivoli Service Automation Manager)) を使用して首尾良くプロトタイプ化されています。この機能を仮想マシンのデプロイメント・プロセスに適用する際に認識していなければならないのは、古い IP の情報 (イメージをインポートしてクラウド・デプロイメント・ツールに登録するときに指定することができます) と新しい IP の情報 (これは、クラウド・デプロイメント・ツールが動的に生成し、適切なデプロイメント・ワークフローで使用します) だけです。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Cloud computing, Linux
ArticleID=812253
ArticleTitle=クラウド仮想マシンの複製エラーを修正する
publish-date=05102012