IBM® Smart Business Development and Test on the IBM Cloud (以下、IBM Cloud とします) は、動的にプロビジョニングとスケーリングが行われる柔軟な環境であり、企業顧客がアプリケーションの開発、テスト、およびホストを行う上で必要となるすべてのものを提供します。IBM Cloud には、クラウド・リソースを構成、管理するための Web ポータル、開発作業やテスト作業を即座に開始するための IBM 製品のソフトウェア・イメージ、そしてユーザーがクラウド・リソースやソフトウェアをプログラムによって制御できるようにするための API が含まれています。また IBM チームは IBM Cloud が登場して以来、その柔軟性とレジリエンシーをさらに高めるための新機能を追加し続けています。
このようにアジリティーが高まり、柔軟性も大幅に向上すると、ビジネスの要求に応じてアプリケーションのトポロジーをリアルタイムで容易に調整できるようになりますが、その代償としてクラウド環境が持つ高可用性 (HA: High Availability) などの特徴を実現しにくくなります。
高可用性は、いかなるノードで障害が発生しても本番レベルのアプリケーションを保護するための要件ですが、決して新しい概念ではなく、この高可用性という課題に対処するためのソフトウェア製品は既に数多くあります。しかしそれらの製品の大部分はクラウドに対応していないため、パブリック・クラウドのプロバイダーのほとんどは高可用性を実現する上で必要な機能を提供していません。
この点を考慮に入れると、顧客はクラウドの外部で HA を構成することで、クラウドにデプロイされるアプリケーションを補完する必要があります。この記事では、この問題に IBM Cloud ではどのように対処しているのか、またその機能を利用する方法について、以下の順序で説明します。
- IBM Cloud に採用されている手法 (仮想 IP アドレスのサポートの追加)
- この機能を利用できるようにクラウド・インスタンスを準備する方法
- 高可用性 Web サイトをセットアップする方法 (例を使って説明します)
- そのサイトをテストする方法
HA に関する懸念に、セキュアかつ適切な方法で対応するために、IBM Cloud のエンジニアは IBM Cloud の仮想インスタンスに仮想 IP アドレス (vIP) のサポートを追加しました。高可用性サービスを提供するにはさまざまな方法がありますが (「参考文献」を参照)、それらの方法のうち、最もよく使用されしかも確実なのは、仮想 IP アドレスを使用する方法です。
1 つのインスタンスが持つことのできる IP アドレスには、通常の静的な IP アドレス (それぞれのインスタンスがプロビジョニングされたときに取得され、決して変更されることのない 1 つの IP アドレス) に加え、1 つまたは複数の動的な仮想 IP アドレスがあります。仮想 IP アドレスとインスタンスとの関連付けはインスタンスの中で実行されるアプリケーション・コードによって制御されるため、アプリケーションのトポロジーはノードの障害に 1 秒以内の非常に短い時間で対応することができます。
単純な例を考えてみましょう。VM A と VM B という仮想マシンのペアがあり、それぞれの静的 IP アドレスが 192.168.1.101 と 192.168.1.102 だとします。さらに、どちらの VM も、192.168.1.10 という vIP を動的に割り当てられるように構成されているとします (図 1)。
図 1. VM A (Proxy A) と VM B (Proxy B) は個別に静的 IP アドレスを持ち、さらにいずれか一方が vIP を持つことができる
この構成では、静的 IP アドレスを使用して、インスタンスの管理や保守を行います。これとは対照的に、仮想 IP アドレスが、サーバーの IP アドレスとしてクライアントに公開されます。
最初は、VM A が vIP を持つため、その結果すべてのサービス・トラフィックは VM A で処理されます。VM B は起動され実行状態にありますが、まだ vIP を保持しておらず、ウォーム・スタンバイとして動作しています (図 2)。
図 2. アクティブ/パッシブ構成: VM A が vIP を保持してすべてのトラフィックを処理し、VM B はパッシブ・スタンバイとして動作する
ここで、アプリケーションが VM A で問題を検出したとします。例えば VM A で処理速度の低下や、障害が発生している場合です。アプリケーションは、もう一方の VM に vIP の制御を渡すことを決定します。すると、VM A は vIP を手放し、今度は VM B が vIP を保持してすべてのトラフィックを処理するようになります。VM A は問題の修復が終わると、ウォーム・スタンバイとなります (図 3)。
図 3. アクティブ/パッシブ構成: VM 間で役割を交換する
仮想 IP アドレスの VM 間での移動は 1 秒以内に実行できるため、トラブルの最初の兆候が検出されたときに仮想 IP アドレスを移せるように注意深くプログラミングすることで、アプリケーションがサービスの提供を停止する可能性を大幅に削減したり、実質的にゼロにしたりすることができます。この方法は単純でありながら実証された方法であり、IBM Cloud 環境でサポートされている方法でもあります。
では、この機能を利用できるようにインスタンスを準備する方法について調べてみましょう。
仮想 IP アドレスによる方法を利用して高可用性を実現するためには、以下の 3 つのステップに従って IBM Cloud のインスタンスを準備します。
未使用の割り当てられていない予約済み IP アドレスを取得する
まず、未使用の割り当てられていない予約済み IP アドレスがあることを確認してください。そのためには、IBM Cloud ポータルにログインし、「Account Tab (アカウント・タブ)」をクリックします。下の方にある「Your IPs (ご使用の IP)」セクションまでスクロールし、予約済み IP の一覧を調べます。選択したデータ・センターに、少なくとも 1 つの未使用のアドレスがあることを確認します。未使用のアドレスがない場合には、「Add IP (IP の追加)」をクリックし、新しい IP アドレスが使用可能になるのを待ちます (図 4)。
図 4. IBM Cloud ポータルの予約済み IP アドレス・パネル
次に、インスタンスを単純にプロビジョニングします。お好みのイメージを選択し、その後に表示される画面で「Virtual IP address (仮想 IP アドレス)」セクションの近くにある「Add IP (IP の追加)」ボタンをクリックし、未使用の IP アドレスを 1 つ選択します (図 5)。
図 5. IBM Cloud インスタンスのプロビジョニング・ダイアログによってインスタンスに vIP を割り当てる
仮想 IP アドレスは、その仮想 IP アドレスの割り当て対象となるインスタンスと同じデータ・センター内にある必要があることに注意してください。「Close (閉じる)」をクリックしてプロビジョニング要求を完了します。
各インスタンスはプロビジョニングされると、最初は静的 IP アドレスのみを持ちます。インスタンスの静的 IP アドレスは eth0 ネットワーク・インターフェースにバインドされます。一方、プロビジョニングの際に仮想 IP が選択されると、それらの仮想 IP は選択された順に、eth0、eth1、などのインターフェースに割り当てられます。
インスタンスのライフサイクルの任意の時点で、sudo /sbin/ifup <インターフェース名> コマンドを実行することで、仮想 IP アドレスをインスタンスに関連付けることができます。その関連付けは sudo /sbin/ifdown <インターフェース名> コマンドによって解除することができます。
ところで、仮想 IP アドレスを持てるのは 1 度に 1 つのインスタンスのみです。IBM Cloud はマルチキャストをサポートしていないため、1 つの IP アドレスを複数の VM に割り当てても競合が発生するだけです。
例えば、あるインスタンスが、システムによって割り当てられた 170.224.163.231 という静的 IP アドレスと、170.224.163.161 という仮想 IP アドレスを受け取ったとします。/etc/sysconfig/network-scripts/ifcfg-eth0 により、以下のようにプライマリー・インターフェースの詳細な構成を知ることができます。
DEVICE=eth0 TYPE=Ethernet BOOTPROTO=static HWADDR=DE:AD:BE:A7:13:52 IPADDR=170.224.163.231 NETMASK=255.255.240.0 ONBOOT=yes GATEWAY=170.224.160.1 |
上記の内容を以下に示す /etc/sysconfig/network-scripts/ifcfg-eth1 ファイルの内容と比較してみてください。
DEVICE=eth1 TYPE=Ethernet BOOTPROTO=static HWADDR=DE:AD:BE:C8:25:20 IPADDR=170.224.163.161 NETMASK=255.255.240.0 ONBOOT=no |
あるインスタンスに対して sudo /sbin/ifup eth1 コマンドを発行すると、そのインスタンスに 170.224.163.161 を関連付けることができ、またその関連付けは sudo /ifdown eth1 によって解除することができます。ブート時にこの IP アドレスを関連付けたい場合には、/etc/sysconfig/network-scripts/ifcfg-eth1 ファイルの中の ONBOOT を単純に yes に変更します。
この例では、HA アクティブ/パッシブ構成の 2 つのプロキシー・サーバーと、3 つの Web/アプリケーション・サーバーから成る単純なトポロジーを構成します (図 6)。
図 6. 2 つのリバース・プロキシーがアクティブ/パッシブ構成でセットアップされ、3 つの Web サーバーにトラフィックを分散する単純なトポロジー
この例で使用しているソフトウェアの構成は以下のとおりです。
- プロキシーは nginx を実行しています。
- Linux HA ソフトウェアと Pacemaker ソフトウェアによってプロキシーの高可用性を実現しています。
- Web サーバーは Apache (ベース OS イメージの一部としてプリインストールされています) を実行しています。
- すべての IBM Cloud インスタンスは 64 ビットの Bronze 構成をベースとした RHEL 5.4 イメージを使用しています。
- IBM Cloud ポータルを使用して、5 つのインスタンスをすべてプロビジョニングする必要があります。この記事で先ほど説明したように、2 つのプロキシー・ノードには必ず vIP を予約し、割り当ててください。
- プロキシーのインスタンスを構成します。すべてのダウンロード・ファイルは「参考文献」セクションから入手することができます。
- 前提として、以下のコマンドを実行する必要があります。
sudo yum -y install glib2-devel libxml2 libxml2-devel bzip2 bzip2-devel pcre-devel
- nginx をインストールします (以下を参考にしてください)。
wget http://nginx.org/download/nginx-0.8.53.tar.gz tar -xvfz nginx-0.8.53.tar.gz cd nginx-0.8.53 ./configure -with-http_ssl_module make sudo make install
- 基本的なプロキシー・ルールを nginx に追加するために、/usr/local/nginx/conf/nginx.conf ファイルを編集し、以下の内容をサーバー・ディレクティブの下に追加します (アプリケーション・サーバーの実際の IP アドレスを使用します)。
upstream appservers { ip_hash; server appserver1_ip; server appserver2_ip; server appserver3_ip; } - すべてのサーバーで時刻の同期が取れていることが重要なので、必ず ntpd が自動的に起動されるようにします。
sudo /sbin/chkconfig --level 2345 ntpd on sudo /sbin/service ntpd start
- Pacemaker パッケージと Linux-HA パッケージをインストールします。まず、Clusterlabs (Pacemaker) リポジトリーと EPEL リポジトリーが利用可能であることを確認します。RHEL 5.4 の場合は、以下の 2 つのコマンドを実行します。
sudo rpm -Uvh \ http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm sudo wget -O \ /etc/yum.repos.d/pacemaker.repo http://clusterlabs.org/rpm/epel-5/clusterlabs.repo
続いて以下のコマンドを実行し、Pacemaker パッケージと、その他必要なパッケージをインストールします。sudo yum install -y pacemaker heartbeat
- nginx サーバーを管理するスクリプトが必要なので、nginx のリソース・エージェントをインストールします。このスクリプトは既に Linux-HA プロジェクトに提出されているので、いずれ自動的に提供されるようになるはずです。それまでの間は以下のコマンドを使用します。
sudo wget -O /usr/lib/ocf/heartbeat/resource.d/nginx \ http://lists.linux-ha.org/pipermail/linux-ha-dev/attachments/20101206/3c141ea6/ attachment.txt - Linux-HA プロジェクトの Heartbeat ソフトウェアを適切に構成する必要があります。IBM Cloud の場合、(ネットワーク上で一意のアドレスによって特定される 1 つの宛先にメッセージを送信する) ユニキャスト通信をすべての通信で使用するように構成する必要があります。Heartbeat 通信レイヤーをインストールしたのは、このためです。
Heartbeat 通信レイヤーを構成するためのファイルには、/etc/ha.d/ha.cf、/etc/ha.d/authkeys、および /etc/logd.cf という 3 つのファイルがあります。
- すべてのマシンは /etc/ha.d/ha.cf ファイルの正確なコピーを持つ必要があります。そのように構成するためには、以下の行を追加します。
use_logd yes ucast eth0 cluster1-fixed-ip ucast eth0 cluster2-fixed-ip # repeat for all cluster nodes autojoin any crm on
IBM Cloud クラウドを実行する場合、ucast通信メソッドを使用する必要があることを覚えておいてください。というのは IBM Cloud は、ブロードキャストやマルチキャストをサポートしていないからです。このため、マルチキャストまたはブロードキャストが必要な Corosync を通信レイヤーとして使用することができません。構成ファイルに記述しなければならない「固定 IP」アドレスは、サーバーの (仮想アドレスではなく) 実際のアドレスで、サーバーごとに 1 行で記述します。 - 各マシンには /etc/ha.d/authkeys ファイルのコピーも必要であり、このファイルのモードを 0600 にする必要があります。以下の方法で最初のコピーを生成し、続いてこのファイルをクラスター内の他のすべてのノードにコピーします。
cat <<-!AUTH >/etc/ha.d/authkeys auth 1 1 sha1 'dd if=/dev/urandom count=4 2>/dev/null | openssl dgst -sha1` !AUTH
- 最後に、/etc/ha.d/logd.cf を logfacility daemon という行で構成します。
logfacility daemon
- すべてのマシンは /etc/ha.d/ha.cf ファイルの正確なコピーを持つ必要があります。そのように構成するためには、以下の行を追加します。
- Pacemaker の構成は Pacemaker が実行された後の方が容易なので、この構成は後で行うことにします。
- 以下のコードによって Heartbeat が自動的に起動されるようにします。
sudo /sbin/chkconfig --levels 345 heartbeat on
- ファイアーウォールの初期構成は少し設定が厳しすぎるため、以下のように /etc/sysconfig/iptables にルールをいくつか追加します。
# allow pings -A INPUT -p icmp --icmp-type any -j ACCEPT # on the virtual IP address, allow only ports 80 and 443. -A INPUT -d virtual_ip -m tcp -p tcp --dport 80 -j ACCEPT -A INPUT -d virtual_ip -m tcp -p tcp --dport 443 -j ACCEPT -A INPUT -d virtual_ip -j REJECT --reject-with icmp-host-prohibited # allow ssh on the service IPs -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT # allow heartbeat port -A INPUT -p udp -m udp --dport 694 -j ACCEPT
- 編集が終了したら、ファイアーウォールを再起動します。
sudo /sbin/service iptables restart
- Web サーバーの構成には少し注意が必要です。最初に、Apache が自動的に起動されるようにします。
sudo /sbin/chkconfig -level 345 httpd on sudo /sbin/service httpd start
次に、以下のように /etc/sysconfig/iptables でポート 80 と 443 を開きます。
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
終了したら、
sudo /sbin/service iptables restartと入力してファイアーウォールを再起動します。これらのノードでも ntpd が自動的に起動されるようにします。sudo /sbin/chkconfig --level 2345 ntpd on sudo /sbin/service ntpd start
これでセットアップは完了したはずですので、次にこのシステムをテストしてみましょう。
以下の手順でシステムをテストします。
- クラスターのすべてのノードで Heartbeat を起動します (すると Pacemaker が起動します)。
crmコマンドを使用して Pacemaker を構成します。- すべてが適切に起動されたことを確認します。
- 構成をテストします。フェイルオーバーによる基本的なリソース転送をいくつか実行します。
Heartbeat を起動するためには service heartbeat start コマンドを発行します。Heartbeat が起動されると、以下のように数多くのプロセスが表示されるはずです。
ha_logd: read process ha_logd: write process heartbeat: master control process heartbeat: FIFO reader heartbeat: write: ucast some-ip-address heartbeat: read: ucast some-ip-address /usr/lib/heartbeat/ccm /usr/lib/heartbeat/cib /usr/lib/heartbeat/lrmd -r /usr/lib/heartbeat/stonithd /usr/lib/heartbeat/attrd /usr/lib/heartbeat/crmd /usr/lib/heartbeat/pengine |
これらのプロセスが表示されると、Heartbeat と Pacemaker が実行されていることがわかります。
Pacemaker を構成するには、crm configure edit コマンドを使用して、実行中の構成を編集します。このコマンドによりテキスト・エディターが開くので、構成ファイルの最後にある property ステートメントの直前に、以下の行を挿入します。
primitive nginx-primitive ocf:heartbeat:nginx \
op monitor interval="5s" timeout="120s" \
OCF_CHECK_LEVEL="0" \
op monitor interval="10s" timeout="120s" \
OCF_CHECK_LEVEL="10" \
params configfile="/etc/nginx/stci.d/nginx.conf"
primitive nginx-ipaddr ocf:heartbeat:IPaddr2 \
op monitor interval="5s" timeout="120s"\
params ip="NGINX-IP-ADDRESS"
primitive NFS-server lsb:nfs-kernel-server
primitive NFS-ipaddr ocf:heartbeat:IPaddr2 \
op monitor interval="5s" timeout="120s"\
params ip="NFS-IP-ADDRESS"
group nginx-group nginx-primitive nginx-ipaddr
group NFS-group NFS-server NFS-ipaddr
clone nginx-clone nginx-group \
meta clone-max="1"
|
Pacemaker の構成を保存すると、システムによってリソースが起動され、この新しい構成がシステムのすべてのノードに伝えられるはずです。ここは大変に興味深い部分です。システム・ログを調べてみると、サービスが開始されたことを示すメッセージなどがあるはずです。HA システムの状態を調べるためには sudo crm_mon コマンドを実行します。このコマンドにより、どのリソースがクラスター内で実行されているか、またどのノードがアップ状態あるいはダウン状態であるか、といった情報が表示されます。
この crm_mon コマンドにより、どのノードで nginx が実行されているかがわかりました。この構成をテストする方法はいくつかありますが、すべての方法を試してみることをお勧めします。十分なテストをしていないクラスターは高可用性クラスターではありません。
- アクティブなノードに対して
sudo service heartbeat stopコマンドを発行し、各設定などがどこに引き継がれたのかを確認したら Heartbeat を再起動します。 - アクティブなノードに対して
sudo reboot -fコマンドを発行し、リソースがどこに移されるのかを (別のノードから) 確認します。 - アクティブなノードに対して
sudo crm node standbyコマンドを発行し、サービスがどこに移されたのかを確認したら、sudo crm node onlineコマンドを発行します。
これで nginx プロキシー・サービスのセットアップとテストのプロセスは完了しました。Linux にはカーネル・レベルのロード・バランサーも組み込まれており、そのロード・バランサーを nginx の代わりに使用して高可用性を実現することもできます。
この記事で紹介した方法と同じ方法を使用することで、クラウド内のほとんどすべてのサービスを高可用性にすることができます。例えば、IBM Cloud 内の NFS サーバーは、クラウドの仮想サーバー間で複製されたデータを持たせることで、高可用性にすることができます。
この記事では、高可用性を実現するために IBM Cloud に採用されている方法 (仮想 IP アドレスのサポートの追加) の詳細、vIP の機能を利用できるようにクラウドのインスタンスを準備する方法、高可用性 Web サイトをセットアップする方法の例、そしてそのサイトをテストする方法について説明しました。
学ぶために
- 仮想 IP アドレス以外にも HA サービスを提供できる方法があります。可用性、自動化、管理システム、オープンソース、およびその他のトピックがどのように関連するかを Managing Computers with Automation で学んでください。
- nginx ("engine x") は HTTP サーバーであり、リバース・プロキシー・サーバーです。
- developerWorks でクラウド開発者のためのリソースを調べてください。クラウドにデプロイするためにプロジェクトを構築しているアプリケーション開発者やサービス開発者の知識や経験を発見し、共有することができます。
- developerWorks を Twitter でフォローしてください。
- developerWorks On demand demos をご覧ください。初心者のための製品インストール方法やセットアップのデモから、上級開発者のための高度な機能に至るまで、多様な話題が解説されています。
- IBM Smart Business Development and Test on the IBM Cloud にアクセスしてください。
製品や技術を入手するために
- この記事で紹介した高可用性プロキシーを実現する方法の元となった資料は以下のとおりです。
- Linux-HA プロジェクト [学ぶ] には、高可用性クラスター・システムのための一連のビルディング・ブロックが用意されています [Heartbeat をダウロードする | Cluster Glue をダウンロードする | Resource Agents をダウンロードする]。
- ユーザーにとって便利なように、Heartbeat デーモンを CRM (Cluster Resource Manager)、つまり Pacemaker と組み合わせる必要があります。
- EPEL (Extra Packages for Enterprise Linux) は Fedora プロジェクトのボランティアによるコミュニティー作業であり、RHEL (Red Hat Enterprise Linux) とその互換システム向けの高品質アドオン・パッケージのリポジトリーを作成しています [学ぶ | ダウンロード]。
議論するために
- developerWorks コミュニティーのクラウド・コンピューティング・グループに参加してください。
- developerWorks コミュニティーのメンバーによる、クラウドに関する優れたブログを読んでください。
- developerWorks コミュニティーに加わってください。developerWorks コミュニティーは専門家のネットワークであり、接続、共有、および協力のための一連のコミュニティー・ツールを豊富に提供しています。