GlassFish 4 でかんたんクラスタ構築

この記事はGlassFish Advent Calendar 2013の3日目として新たに書き下ろしたものです。前日の記事はキクタロー @kikutaro_ さんの「NetBeansでGlassFishのリモートデバッグ」でした。


今年のJava Day Tokyo 2013のフィナーレ "Java The Night" に参加された方は覚えていらっしゃるかもしれませんが、その場で開催されたデモ大会において、筆者は自宅環境に構築したGlassFish 4の24ノードクラスターをVPN経由でアクセスする実演を行いました。

この事前準備は、JJUG CCC 2013 Springの発表準備と重なり、かなり慌ただしい中で行ったのですが、それを可能にしてくれたのはGlassFishのクラスタ管理機能の進歩です。

GlassFishのクラスタ環境構築に関する日本語文献としては、寺田さんの下記ブログ記事がよく知られています。

いずれもGlassFish v3.1時代の記事で、同一アーキテクチャを採用しているGlassFish 4でも内容はほぼ通用します。ただし、GlassFish v3.1当時に比べるとGlassFishのクラスタ管理機能はほとんど管理コンソールだけで実現できるようになっています。

もちろんGlassFish v3.1の管理コンソールにもクラスター管理機能は備わっているのですが、一部機能の不足や動作の不安定さから、asadminによるCLIでの構築作業の方が確実でした。

この記事では、GlassFish 4の管理コンソールでとりあえずクラスタ環境を構築する方法を、"Java The Night" のデモ環境構築時の手順を一部再現しながらご紹介します。

1. 前提条件

今回はSSHによる4ノードのクラスタを構築します。マシンは4台(Solaris Zoneで構築したためインスタンスと言った方が正確でしょうか)のSolaris 11.1を使用します。SSHを使用するのであればLinuxでも全く問題ないのですが、4月のデモで使用したSolarisが生きていたので、インフラ構築の手間を省くためそれを流用しました。24台のうち今回は以下の4台を使用します。

マシン一覧
ホスト名役割
pasiphae ドメイン管理サーバー(DAS)
sinope SSHノード
callirrhoe SSHノード
megaclite SSHノード

4台のマシンは、GlassFishを動作させるユーザーとそのパスワートを一致させておきます。実は4月のデモではパーミッション関係のトラブルを回避するため、GlassFishをrootで動作させるという手抜きをやっており、そのための設定がそのまま残っていたので今回も同じ手段を使うことにします。SSHはデフォルト設定ではrootログインを受け付けないため、事前にsshd.confの設定を変更してrootログインを許可しておきます(4月のデモで使用した24台はすべて設定済みです)。

Solaris 11以降では標準的なインストレーションを行うとrootがユーザーではなくRBACの "Primary Administrator" ロールとなります。GlassFishの管理機能はRBACに対応していないため、上記の手抜きを行う場合にはrootを従来通りのユーザーとして設定するようなインストレーションを行っておく必要があります(具体的にはインストール時に初期ユーザーを省略せずに作成しておきます)。4月のデモで使用した24台のSolarisはすべてrootをロールではなくユーザーとしてインストールしています。

2. GlassFishのインストールと初期設定

GlassFish.orgのダウンロードサイトからGlassFishのZIPアーカイブ glassfish-4.0-ml.zip を取得して(筆者自身は事前にダウンロードしておいたものをscpでコピーする方法を多用しています)、DASを構築する pasiphae 上の適当な場所にコピーします。今回はSolaris文化に合わせて /opt 以下にコピーしました。Linuxの文化では、Red Hat系やSUSEなら /opt 以下、Debian系なら /usr/local 以下が適切でしょうか(筆者はSLES/OpenSUSEとRHELしか使ったことがないので間違っていたらゴメンナサイ)。この場合のasadminのパスは /opt/glassfish4/bin/asadmin となります。

クラスタ環境を構築するには、セキュア管理を有効にする必要があります。また、セキュア管理を有効にするためには asadmin や管理コンソールのパスワードを設定しておかなければなりません。ZIPアーカイブ版のGlassFishでは asadmin のパスワードが設定されていないため、まずはそこから作業を行います。

root@pasiphae:/opt/glassfish4/bin# ./asadmin change-admin-password
Enter admin user name [default: admin]>
Enter the admin password> 
Enter the new admin password> adminのパスワード
Enter the new admin password again> adminのパスワード
Command change-admin-password executed successfully.
root@pasiphae:/opt/glassfish4/bin# ./asadmin start-domain
Waiting for domain1 to start ...............
Successfully started the domain : domain1
domain  Location: /opt/glassfish4/glassfish/domains/domain1
Log File: /opt/glassfish4/glassfish/domains/domain1/logs/server.log
Admin Port: 4848
Command start-domain executed successfully.
root@pasiphae:/opt/glassfish4/bin# ./asadmin enable-secure-admin
Enter admin user name>  admin
Enter admin password for user "admin"> adminのパスワード
You must restart all running servers for the change in secure admin to take effect.
Command enable-secure-admin executed successfully.
root@pasiphae:/opt/glassfish4/bin# ./asadmin restart-domain
Successfully restarted the domain
Command restart-domain executed successfully.

初期設定のポイント

  1. asadminでパスワードを変更するには、change-admin-passwordサブコマンドを使用する。
  2. asadminで最初のパスワードを設定する時、最初に訊かれるのは管理者のユーザー名(デフォルトはadmin)、2番目に訊かれるのは初期パスワード(デフォルトは空白)、実際のパスワード設定はそれ以降になる。英語メッセージで見落としがちのため注意すること。
  3. asadminでセキュア管理を有効にするには、enable-secure-adminサブコマンドを使用する。enable-secure-adminを使用する場合は必ずGlassFishを起動しておくこと。
  4. セキュア管理を設定した後は、設定を有効にするためGlassFishを再起動する。asadminでstop-domainおよびstart-domainサブコマンドを組み合わせるか、restart-domainサブコマンドを使用する。
  5. 上記設定のうち、GlassFishの起動以外は管理コンソール上でも行える(今回はGlassFishインストール作業からの流れで行ったためasadminを使用した)。

初期設定が終了し、https://pasiphae:4848 をブラウザで開くと、証明書が無効云々警告が出て(今回は諸般の事情により無視します)、それを飛ばすと次のようなログイン画面が表示されるはずです。

glassfish-login.png

ユーザー名とパスワードには、asadminで設定したものを入力します。

3. クラスターの作成

クラスタはDASを含め通常2台以上のノードで構成します。まず、最初のノードを sinope 上に作成します。管理コンソールの左側から「ノード」を選択します。

initial-nodes.png

初期状態ではdomain1(デフォルト・ドメイン)のDASのみが作成されています。ここに「新規」ノードを追加します。

create-node.png

スクリーンショットでは項目一覧の下半分が隠れてしまっているので、以下の表に示します。

ノード作成時の設定項目(SSHパスワード認証の場合)
項目名設定内容
名前 任意の名前を設定できる(ここではsinope-domain1)が、必須項目
タイプ 選択必須、ここではデフォルトの「SSH」を選択する
※「DCOM」はWindowsのみ有効、「CONFIG」は既存ノードをドメインに登録する場合に使用する
ノード・ホスト SSHのため実質必須(ここではsinope
ノード・ディレクトリ デフォルト(空欄)
インストール・ディレクトリ デフォルト(DASと同じディレクトリ構成となる)
GlassFish Serverのインストール Enabledにチェック、SSH/DCOMプロビジョニングを生かすためにできる限り有効にしておくことを推奨
強制 デフォルトは無効(チェックなし)、エラー時にロールバックしないことはリスクを伴うため、この項目は原則として有効にしない
SSHポート デフォルト=ポート22
SSHユーザー名 デフォルト(ここではrootとみなされる)
SSHユーザー認証 鍵ファイル(デフォルト)、パスワード、パスワード・エイリアス、今回は「パスワード」を選ぶ→以下の選択項目が変わる
SSHユーザー・パスワード ノードインストール先のユーザー・パスワード(ここではrootのパスワード)
※2つのノード間でユーザー名とパスワードを合わせておくとトラブルが少ない

なるべく簡単に構築するため、ノードはSSHで構築し、SSH認証方式も推奨されている鍵ファイルやパスワード・エイリアスではなく、パスワード認証を用いました。

Windowsの場合はDCOMでのノード構築が第一選択肢となりますが、基盤となるDCOM-RPCが最近のWindowsでは初期状態で無効化されており、有効化する手順も煩雑であるため(筆者は一度も成功したことがない)、今回は回避しました。

「OK」ボタンをクリックすると、少し時間がかかります。その裏では pasiphae 上のGlassFishが自分自身をZIPアーカイブにして sinope にコピーし、sinope 上にGlassFishをインストールしてノードを作成します。一連の作業はすべて pasiphae からSSH/SCPで実行するため、sinope 上での作業は一切不要です(オペレーターはログインさえしていない)。

続いてクラスタを作成します。管理コンソールの左側から「クラスタ」を選択します。

initial-clusters.png

「新規」をクリックしてクラスタを作成します。

create-cluster.png

設定項目はそれほど多くありません。以下に示します。

新規クラスタの設定項目
項目名設定内容
クラスタ名 任意の名前を設定できる(ここではcluster1)が、必須項目
構成 構成のテンプレートを選択するが、最初に選択できるのはdefault-configのみ
Message Queueクラスタ構成タイプ JMS関連の設定、デフォルトのままでよい
インスタンス名 クラスタを構成するインスタンスを識別する任意の名前、ここではわかりやすいようにホスト名をそのまま用いた
重み ロードバランサーで使用する重みで負荷分散の配分はこの値に比例する
※比率であるため任意の数値を入れられるが、asadminで作成した場合のデフォルト値が100のため、これを基準値と考えるとわかりやすい
ノード DASに登録されているノードを選択する
ここではlocalhost-domain1とsinope-domain1の一方を選択する

インスタンス名・重み・ノードは繰り返し項目で、追加・削除が可能ですが、そのオペレーションはWebシステムにありがちなお決まりのパターンです。別に悪いとは言いませんが...

「OK」ボタンをクリックするとクラスタが作成されます。クラスタ環境では、参加しているすべてのノードで1つのドメインを構成します。

list-clusters-1.png

作成されたばかりのクラスタはすべてのノードが停止した状態ですので、起動したいクラスタを選択して「クラスタの起動」をクリックします。

list-clusters-2.png

クラスタ環境では、参加するすべてのインスタンスが同じ状態になります。従って、すべてのインスタンスでアプリケーションや各種リソースが同期されます。これにより複数のインスタンスに負荷を分散されたり、あるいは一部インスタンスに障害が発生しても障害箇所を分離して運用を継続することが出来ます。

list-clusters-3.png

問題がなければすべてのインスタンスが「稼働中」というステータスになります。

クラスタ構築のポイント

  1. クラスタはインスタンスの集まりから構成され、インスタンスはノードと対応している。
  2. DASはlocalhost-domain1という名前のノードで初めから存在している。つまり、DAS自身もノードであり、インスタンスを作成してクラスタに追加することが出来る。
  3. SSHノードおよびDCOMノードは、DASからGlassFishのインストールを含め構築が可能である。
  4. SSHノードを作成する際には、SSH認証方法を「鍵ファイル」「パスワード・エイリアス」「パスワード」から選択する。推奨は「鍵ファイル」だが、最も簡単な方法は「パスワード」である。
  5. クラスタはすべてのインスタンス、または特定のインスタンスについて、起動および停止することが出来る。作成直後のクラスタはすべてのインスタンスが停止している。

この先、実際にはフロントエンドにHTTPサーバを配置して何らかの方法でリクエストを分散しないと、クラスタの負荷分散は機能しません。一番簡単な方法はHTTPサーバのリバース・プロキシ機能を使用することです。個人的にはiPlanet Web Serverのリバース・プロキシがお気に入りなのですが、システム要求を満たせるようであればどのHTTPサーバのものでも構いません(ただし古いバージョンのApacheは避けた方が良いです)。

4. 作成したクラスーを眺めてみる

では、作成したクラスタの設定項目を眺めてみましょう。

4.1. クラスタの一般情報

cluster-overview.png

一般情報ではインスタンスの状態や、クラスタの起動・停止などの基本的な操作を実行できます。

4.2. インスタンス

クラスタに参加しているインスタンスを一覧できます。インスタンス(ノード)単位での起動・停止が可能な他、インスタンスの作成と削除もここから実行できます。

cluster-instances-1.png

4.3. リソース

クラスタ全体で共有しているリソースの一覧です。スタンドアロンのリソースとは別に扱われるので注意が必要です。

cluster-resources.png

4.4. プロパティ

クラスタのプロパティで最も重要なのは、インスタンスの各種待ち受けポート番号でしょう。通常、HTTPリスナーはポート8080を使用しますが、クラスターの各インスタンスのHTTPリスナーはポート28080を使用します。デフォルトではスタンドアロン時の各種待ち受けポート番号+20000となっています。

cluster-system-properties.png

5. クラスタにノードを追加する

ここまでの時点で、作成したクラスタにはDASを含め2つのノードが参加しています。残り2台(callirrhoemegaclite)についても同様にノード作成とクラスタへの追加を行いましょう。

手順は sinope の時と全く同じなので、callirrhoemegaclite を追加した後のノード一覧を見てみましょう。

list-nodes.png

ノード・ホストに callirrhoemegaclite が追加されていることと、これらのインスタンスが空白、つまりクラスターに参加していないし起動もしていないことを表しています。

そこで、4.2. 節で示したインスタンス一覧画面から、ノード callirrhoemegaclite を既存クラスタのインスタンスとして追加してみます。

add-cluster-instances.png

追加した直後のインスタンス callirrhoemegaclite はともに停止しています。このままでは2つのインスタンスは使用されないため、これらを起動する必要があります。インスタンスの起動方法にはいくつかありますが、クラスタ環境でのインスタンス起動・停止は、運用上クラスタ全体を停止できない場合が一般的であるため、ここでは追加したインスタンスのみを個別に起動します。

方法は一覧から起動したいインスタンスを選択して「起動」ボタンをクリックするだけです。

run-cluster-instances.png

何事もなければ、callirrhoemegaclite のステータスが「停止」から「稼働中」に変化しているはずです。

running-cluster-instances.png

4つのインスタンスがすべて起動すると、クラスタの一覧では次のように表示されるはずです。すべてのインスタンスが「稼働中」となっていることに注目してください。

list-clusters-4.png

ノード一覧でも、すべてのノードが稼働していることを確認できます。

list-nodes-2.png

6. クラスタの構成情報

GlassFishのドメインは、それぞれ構成情報を持っています。初期状態では default-config と server-config の2つの構成情報が存在しています。default-config は構成情報のテンプレートであり、設定値の変更は今後作成されるであろうすべての構成情報に影響するため、細心の注意を要します。server-config は初期ドメイン(domain1)に適用されている構成情報で、最初は default-config のコピーですが、設定変更のたびに内容が変更されます。

クラスタを構築すると、これらとは別の構成情報が作成されます。今回はcluster1という名前のクラスタを構築したため、cluster1-configという構成情報が作成されています。

config.png

構成情報の一覧からわかるように、cluster1-configはcluster1に参加している4つのインスタンスすべてに適用されています。server-configはスタンドアロンのインスタンスに対して適用され、テンプレートであるdefault-configは適用されているインスタンスがありません。

スタンドアロンではserver-configの設定値を変更するため、クラスタの設定値を変更したつもりが実はserver-configを変更していて、クラスタには反映されていなかった、というオチも多々ありますので、十分注意してください。

7. まとめ

ブログ記事としてはかなりのボリュームになってしまいましたが、やっていることは難しくありません(GUIベースで、Step by Stepで説明したからボリュームが膨らんだだけです)。今回は過去に構築実績のある基盤上で、敢えて失敗しにくい手順でクラスターを作成しているため、そうそうコケようはずがありません(これを手抜きとも言う)。

もし、他のサーバのクラスタ環境構築経験があるようでしたら、その時の手順と今回のGlassFishにおける(おそらく最も簡単な)手順を比較してみてください。DASからの集中管理ですべてを実現できるGlassFishの素晴らしいクラスタ機能をより多くの方に体験して頂ければ、筆者にとって望外の喜びです。


明日はGlassFishのEmbedded Serverについてお話しする予定です。ではまた。