この章では、Sun Cluster のデータサービス API のサンプルアプリケーション in.named について説明します。in.named デーモンは、Internet DNS (ドメインネームサービス) の Solaris 実装です。
この章で説明するアプリケーションの例では、どのようにデータサービスアプリケーションの高可用性を実現するかを示します。これは例として示すことだけを目的としています。このアプリケーションの高可用性を実現できる保証はありません。
この章では、Sun Cluster データサービス API について説明している hareg(1M) と haget(1M) のマニュアルページを読んでいることを前提としています。
このアプリケーション例は、API の機能を多数 (すべてではありません) 示します。次に示すアプリケーションの特徴に注意してください。
アプリケーション例で使用されるデータは簡単に異なるセットに分割できません。したがって、単一のデータセット (論理ホスト) を使用します。
in.named データサービスはコマンド行オプション -b をサポートします。このオプションを使用すると、論理ホストのディスクセット上にあるファイルシステム内のデータを指定できます。
あるデータサービスのクライアントサーバープロトコルでは、サーバーが自分のホスト名をクライアントへのメッセージの一部としてクライアントに戻すことがあります。このようなプロトコルでは、クライアントは戻されたホスト名を将来サーバーに接続するときのホスト名として使用できます。サンプルの in.named では、このような状況は発生しません。in.named データサービスはサーバーのホスト名を必要とせず、クライアントにもホスト名を戻しません。
in.named データサービスは、特別に指定なしに多重ホームホストを処理できます。
in.named データサービスは、特別に指定なしに追加の論理ホストの IP アドレスを処理できます。停止メソッドと開始メソッドは in.named デーモンを強制終了および再起動します。
in.named データサービスは、実際のクラスタが複数の論理ホストを持っている場合でも、単一の論理ホストだけを使用します。このメソッド実装では、どの論理ホストが使用されているのかが動的に計算されます。たとえば、論理ホスト hahost1 を使用している場合、in.named のデータは hahost1 のディスクセットに格納されます。
管理者は起動ファイル (-b フラグ引数で指定する) をディスクセット内の任意のファイルシステムに格納できます (ファイルシステムの空き領域に依存します)。しかし、HA-in.named メソッド実装には、起動ファイルを見つけるための開始点が必要です。アプリケーション例では、この開始点は hainnamed サブディレクトリの下にある管理ファイルシステムにあります。つまり、この管理ファイルシステムの hainnamed.config 構成ファイルには、論理ホストの多重ホストディスク内のどこか別の場所にあるディレクトリを示すディレクトリ名が 1 つだけ入っています。つまり、このディレクトリに実際のデータが存在します。これは、間接参照のレベルです。
論理ホスト hahost1 の場合、ファイル hainnamed.config のパス名は次のとおりです。
/hahost1/hainnamed/hainnamed.config
/logical_host/hainnamed/hainnamed.config
HA-in.named メソッドは、上記構成ファイルが各論理ホストに存在するかどうかを検証することにより、HA-in.named 用に使用されている論理ホストを動的に計算するように作成されています。
たとえば、A1 から A5 までのファイルシステムが hahost1 ディスクセット上に存在しており、管理者が HA-in.named データの格納場所として /hahost1/A1/hainnamed ディレクトリを選択した場合、そのディレクトリ名が hainnamed.config ファイルに入っていなければなりません。
/hahost1/A1/hainnamed ディレクトリにおいて、管理者は in.named 用の named.boot ファイルを作成しなければなりません (named.boot ファイルの内容については、in.named(1M) のマニュアルページを参照してください)。in.named データベースを更新する場合、管理者は上記ディレクトリにある named.boot ファイルを編集します。この作業は、非 HA の in.named 構成で /etc/named.boot ファイルを編集するのとほとんど同じです。管理と更新についての詳細は、「HA-in.named の管理: データベースの更新」を参照してください。
ここでは、HA-in.named メソッド実装の基本機能を考えます。HA-in.named では、start メソッドは登録されておらず、すべての作業は start_net メソッドで行われます。同様に、stop メソッドも登録されておらず、すべての作業は stop_net メソッドで行われます。start_net メソッドは in.named デーモンを起動し、stop_net メソッドは -TERM シグナルを送信して in.named デーモンを強制終了します。
Sun Cluster API では、各メソッドの機能が呼び出し回数に依存しないことが必要です。つまり、メソッドを何回呼び出しても、その影響は 1 回呼び出したときと同じでなければなりません。HA-in.named の場合、各メソッドは呼び出し回数に依存しないことを実現するために、自分の作業がすでに行われているかどうかを検証します。start_net は in.named デーモンがすでに動作しているかどうかを検証し、stop_net は in.namedデーモンがすでに停止しているかどうかを検証します。
Sun Cluster のプロセス監視機能は 2 つの構成要素、pmfadm(1M) コマンドと rpc.pmfd(1M) プロセス監視デーモンから構成されています。アプリケーション例では、in.named デーモンを起動または強制終了したり、in.named デーモンがすでに動作しているかどうかを照会するために、pmfadm(1M) コマンドが使用されています。詳細は、pmfadm(1M) と rpc.pmfd(1M) のマニュアルページを参照してください。
HA-in.named メソッド実装では、Sun Cluster 構成についての情報を抽出するために、haget(1M) ユーティリティプログラムが使用されています (詳細は、haget(1M) のマニュアルページを参照してください)。このメソッド実装では、コード実行中にユーザーの操作が介入しないため、エラーメッセージは syslog(3) に記録されます。このときに使用される syslog 機能は、Sun Cluster が使用するものと同じです。syslog 機能の名前を調べるには、haget(1M) を -f syslog_facility オプション付きで呼び出します。
次に、in.named データサービス用の start_net メソッドの例を示します。
#! /bin/sh # #Copyright 13 Apr 1996 Sun Microsystems, Inc. All Rights Reserved. # #ident "@(#)innamed_start_net.sh 1.1 96/04/13 SMI" # # HA-in.named start_net method ARGV0=`basename $0` SYSLOG_FACILITY=`haget -f syslog_facility` MASTERED_LOGICAL_HOSTS="$1" if [ -z "$MASTERED_LOGICAL_HOSTS" ]; then # This physical host does not currently master any logical hosts. exit 0 fi # Replace comma with space to form an sh word list: MASTERED_LOGICAL_HOSTS="`echo $MASTERED_LOGICAL_HOSTS | tr ',' '`" # Dynamically search the list of logical hosts which this physical # host currently masters, to see if one of them is the logical host # that HA-in.named uses. MYLH= for LH in $MASTERED_LOGICAL_HOSTS ; do # Map logical hostname to administrative file system name: PATHPREFIX_FS=`haget -f pathprefix $LH` CONFIG="${PATHPREFIX_FS}/hainnamed/hainnamed.config" if [ -f $CONFIG ]; then MYLH=$LH break fi done if [ -z "$MYLH" ]; then # This host does not currently master the logical host # that HA-in.named uses. exit 0 fi # This host currently masters the logical host that HA-in.named uses, $MYLH # See if in.named is already running, if so exit. (We must have # started it on some earlier cluster reconfiguration when this # physical host first took over mastery of the $MYLH logical host.) # We determine whether in.named is already running by using the pmfadm # command to query its status: if the query succeeds, it is already # running. if pmfadm -q hainnamed >/dev/null 2>&1 ; then exit 0 fi HA_INNAMED_DIR="`cat $CONFIG`" if [ ! -d $HA_INNAMED_DIR ]; then logger -p ${SYSLOG_FACILITY}.err ¥ "${ARGV0}: directory $HA_INNAMED_DIR missing or not mounted" exit 1 fi # We cd to the HA_INNAMED_DIR directory because the named.boot file # contains the names of other files. By cd'ing, we permit all of # those names to be relative names, relative to the current directory cd $HA_INNAMED_DIR if [ ! -s named.boot ]; then logger -p ${SYSLOG_FACILITY}.err ¥ "${ARGV0}:file $HA_INNAMED_DIR/named.boot is missing or empty" exit 1 fi # Run the in.named daemon under the control of the Sun Cluster process # monitory facility. Let it crash and restart up to 4 times an hour; # if it crashes more often than that, the process monitor facility daemon # will cease trying to restart it. pmfadm -c hainnamed -n 4 -t 60 /usr/sbin/in.named -b named.boot if [ $? -ne 0 ]; then logger -p ${SYSLOG_FACILITY}.err ¥ "${ARGV0}: pmfadm -c of in.named failed" exit 1 fi exit 0 |
次に、in.named データサービス用の stop_net メソッドの例を示します。
#! /bin/sh # Copyright 13 Apr 1996 Sun Microsystems, Inc. All Rights Reserved. # #ident "@(#)innamed_stop_net.sh 1.1 96/04/13 SMI" # # HA-in.named stop_net method # ARGV0=`basename $0` SYSLOG_FACILITY=`haget -f syslog_facility` NOT_MASTERED_LOGICAL_HOSTS="$2" if [ -z "$NOT_MASTERED_LOGICAL_HOSTS" ]; then # This physical host currently masters all logical hosts. exit 0 fi # Replace comma with space to have an sh word list: # NOT_MASTERED_LOGICAL_HOSTS="`echo $NOT_MASTERED_LOGICAL_HOSTS |tr ',' ' '`" # Dynamically search the list of logical hosts that this physical # host should not master, to see if one of them is the logical host # that HA-in.named uses. There are two cases to consider: # (1) This physical host gave up mastery of that logical host during # some earlier cluster reconfiguration. In that case, the HA administrative # file system for the logical host will no longer be mounted so the # /HA administrative_file_system/hainnamed directory will not exist. # This method has no work to do, because the work got done during the # earlier cluster reconfiguration when this physical host first gave up # mastery of the logical host. # (2) This cluster reconfiguration is the one in which this physical # host is giving up mastery of the logical host. In that case, the # administrative file system is still mounted when the stop_net method # is called and the /HA administrative_file_system/hainnamed directory # will exist. MYLH= for LH in $NOT_MASTERED_LOGICAL_HOSTS ; do # Map logical hostname to pathprefix file system name: PATHPREFIX_FS=`haget -f pathprefix $LH` CONFIGDIR="${PATHPREFIX_FS}/hainnamed if [ -d $CONFIGDIR ]; then MYLH=$LH break fi done if [ -z "$MYLH" ]; then # This host is not giving up mastery of the HA-in.named logical host # during this cluster reconfiguration. exit 0 fi # This host is giving up mastery of the HA-in.named logical host, $MYLH # during this cluster reconfiguration. # # See if in.named is running, and if so, kill it. If it is not running, # then either we must have killed it during some earlier reconfiguration # when this physical host first gave up mastery of the logical host, or # this physical host has not had mastery of the logical host since it # last rebooted. # # Tell process monitor to kill the in.named daemon, if it was already # running. if pmfadm -q hainnamed; then pmfadm -s hainnamed TERM if [ $? -ne 0 ]; then logger ${SYSLOG_FACILITY}.err ¥ "${ARGV0}: pmfadm -s of in.named failed" exit 1 fi fi exit 0 |
HA-in.named の例では、abort メソッドは登録されていません。abort_net メソッドは、stop_net メソッドと同じコードを使用します。つまり、hareg(1M) ユーティリティで HA-in.named を Sun Cluster に登録するとき、abort_net は stop_net が使用するコードを指すように登録されます。
hareg(1M) でデータサービスを登録するとき、作成したメソッド (start_net、stop_net、fm_start など) 用にタイムアウト値を指定できます。しかし、メソッドに設定したタイムアウト値は、クラスタの再構成時、論理ホストのテイクオーバー用に設定したタイムアウト値の半分よりも少なくなければなりません。論理ホストのテイクオーバー用のデフォルトのタイムアウト値は 180 秒です。したがって、メソッド用に設定したタイムアウト値が 90 秒よりも大きい場合、論理ホストのテイクオーバー用のタイムアウト値を増やさなければなりません。そうしないと、メソッドがタイムアウトします。
論理ホストのテイクオーバー用のタイムアウト値を増やすには、scconf(1M) コマンドを使用します。詳細は、scconf(1M) のマニュアルページと、『Sun Cluster 2.2 のシステム管理』のクラスタ移行手順のタイムアウトの構成に関する説明を参照してください。
ここでは、HA-in.named の start_net メソッドと stop_net メソッドに改善できるところがないかを考えます。これらのメソッドはエラー検出処理機能を持っています。たとえば、/usr/sbin/in.named バイナリが存在するか、実行可能か、空でないかを検証できます。検証の結果がエラーである場合、エラーメッセージが記録されます。cat(1) で hainnamed.config ファイルを表示する前に、このファイルが存在するか、正しいアクセス権を示しているか、空でないかを確認します。
これらのメソッドは、非 HA の in.named データファイル /etc/named.boot が存在するかも検証できます。このファイルが存在する場合、当該ホストが非 HA の in.named と HA-in.named のどちらを実行しているのか混乱する可能性があります。つまり、1 度に実行できるのはどちらか 1 つだけです。このような状況はサーバー構成エラーとして扱われ、エラーメッセージが記録されます。in.named の起動や強制終了は行われません。
Solaris では、DNS のクライアントであるホストには /etc/resolv.conf ファイルがあります。このファイルには、DNS サービス時に接続するためのネームサーバーのホストの一覧が含まれています。この一覧では、ネームサーバーのホストは、ホスト名ではなく、IP アドレスで表現されています。ホストの IP アドレスが複数含まれていることもあります。
HA-in.named の ネットワーククライアントは、論理ホストの IP アドレスをリストします。たとえば、hahost1 の IP アドレスは /etc/resolv.conf ファイルを参照してください。
HA-in.named が使用する論理ホストを物理ホストがマスターしない期間があります。しかし、このような期間中でも、ホストには HA-in.named のクライアントになることができる必要があります。このためには、クラスタ内のすべての物理ホスト上にある /etc/resolv.conf ファイルに論理ホストの IP アドレスを追加します。
HA-in.named の管理は、非 HA の in.named の管理と似ています。in.named データベースを更新する場合は、サーバーにログインします (in.named データファイルが格納されているファイルシステムに root の NFS アクセス権を与えるのはセキュリティ上問題があるので注意してください)。HA-in.named を更新する場合は、HA-in.named が使用するように構成されている論理ホストを現在マスターしている物理サーバーにログインします。どの物理ホストがどの論理ホストをマスターしているのかを調べるには、hastat(1M) ユーティリティを使用します。
HA-in.named を更新するには、そのデータファイルを編集します。まず、不意の障害に備えて、データファイルのコピーを作成し保存しておきます。たとえば、ログイン後、HA-in.named データが格納されているディレクトリ (この例では、/hahost1/A1/hainnamed ディレクトリ) に移動します。次に、データファイルのコピーを作成し、コピーの方を編集します。編集が完了したら、コピーの名前を実際のデータファイルの名前に変更します。たとえば、次のようにします。
% cd /hahost1/A1/hainnamed % cp named.boot named.boot.new % vi named.boot.new % sync % mv named.boot.new named.boot |
in.named(1M) のマニュアルページに説明されているとおり、次に、kill(1M) コマンドを使用し、SIGHUP シグナルを in.named デーモンに送信します。すると、in.named デーモンはデータファイルを読み直します。
高可用性データサービスのインストールと構成は文書にしておかなければなりません。この文書では、管理ファイルシステムに存在する管理ファイルを構成する方法、およびデータサービスのデータを 1 つまたは複数の論理ホストのファイルシステムまたは raw パーティションにインストールする方法を記述しなければなりません。また、HA バージョンのデータサービスの管理履歴と更新も文書にするべきです。
Sun Cluster を使用すると、HA データサービスの作成者はデータサービス用の障害監視メソッドを作成できます。たとえば、in.named 用の障害モニターを作成し、nslookup(1M) を使用して定期的に in.named に照会できます。非常に長いタイムアウト値を使用して照会がタイムアウトした場合、障害モニターは、in.named デーモンがハングアップしたために、強制終了および再起動しなければならないと判断します。
障害監視を実行するのは、in.named が動作している物理ホスト、つまり、in.named が使用する論理ホストをマスターするホスト上だけです。論理ホストをマスターしない物理ホスト上では障害監視を実行しません。
障害モニターは FM_START メソッドにより起動され、FM_STOP メソッドにより停止されます。FM_INIT メソッドは必要ありません。つまり、hareg(1M) の呼び出し時、HA-in.named は FM_INIT を登録しません。
次に、in.named データサービス用の FM_START メソッドの例を示します。
#! /bin/sh # Copyright 26 Oct 1996 Sun Microsystems, Inc. All Rights Reserved. #ident "@(#)innamed_fm_start.sh 1.1 96/04/13 SMI" # HA in.named fm_start method # Called-back by Solaris Cluster as the FM_START method for HA in.named. # ARGV0=`basename $0` SYSLOG_FACILITY=`haget -f syslog_facility` MASTERED_LOGICAL_HOSTS="$1" if [ -z "$MASTERED_LOGICAL_HOSTS" ]; then # This physical host does not currently master any logical hosts. exit 0 fi # Replace comma with space to form an sh word list: MASTERED_LOGICAL_HOSTS="`echo $MASTERED_LOGICAL_HOSTS tr ',' ' '`" # Dynamically search the list of logical hosts which this physical # host currently masters, to see if one of them is the logical host # that HA-in.named uses. MYLH= for LH in $MASTERED_LOGICAL_HOSTS ; do # Map logical hostname to administrative file system name: PATHPREFIX_FS=`haget -f pathprefix $LH` CONFIG="${PATHPREFIX_FS}/hainnamed/hainnamed.config" if [ -f $CONFIG ]; then MYLH=$LH break fi done if [ -z "$MYLH" ]; then # This host does not currently master the logical host # that HA-in.named uses. exit 0 fi # This host currently masters the logical host that HA in.named uses, # $MYLH. # Create an asynchronous process to periodically probe the in.named # daemon, under the control of the process monitor facility. # The asynchronous probe is in its own shell script: # hainnamed_fmprobe # The asynchronous process will be terminated by the FM_STOP method. pmfadm -c hainnamedfm hainnamed_fmprobe $MYLH exit 0 |
次に、in.named データサービス用の FM_STOP メソッドの例を示します。
#! /bin/sh # # Copyright 26 Oct 1996 Sun Microsystems, Inc. All Rights Reserved. # #ident "@(#)innamed_fm_stop.sh 1.1 96/04/13 SMI" # # HA in.named fm_stop method # # Called back by Sun Cluster as the FM_STOP method for HA in.named. # # Stop the asynchronous fault monitoring process that was created # earlier under the control of pmfd. # # Ignore errors when calling pmfadm just in case the hainnamed_fmprobe # is already not running. Reasons for it being already not running # include the fact that it is started only on the physical host that # currently masters the logical host, the fact that FM_STOP can be # called even though FM_START has not be en called, and the fact # that it may have died an early death all by itself. pmfadm -s hainnamedfm TERM >/dev/null 2>&1 exit 0 |
次に、in.named データサービス用の検証スクリプト例 ha.innamed_fmprobe を示します。このスクリプトは、FM_START メソッドによるプロセス監視機能の制御下で起動されます。
#! /bin/sh # # Copyright 26 Oct 1996 Sun Microsystems, Inc. All Rights Reserved. # #ident "@(#)hainnamed_fmprobe.sh 1.1 96/04/13 SMI" # # Usage: hainnamed_fmprobe logical_host # # Periodically probes the in.named running on the logical_host. # If the probe times out, then this script will query the pmfd to # see if the pmfd is still running in.named: # (i) if so, this script assumes that in.named is hung and # sends a KILL signal to the in.named process, causing it to # die. pmfd will restart in.named provided it has not used # up its ration of restarts per time period. # (ii) if not, this script will assume that in.named has exhausted # its ration of restarts. This script will call hactl -g to give up # mastery of the logical host to some other new master physical host. # ARGV0=`basename $0` LOGICAL_HOST="$1" SYSLOG_FACILITY=`haget -f syslog_facility` PROBE_INTERVAL_SECS=60 MIN_PROBE_SECS=`hactl -f min_probe_timeout_secs` PROBE_TIMEOUT_SECS=`expr $MIN_PROBE_SECS + 180` CLUSTER_KEY=`hactl -f cluster_key` NSLOOKUP=/usr/sbin/nslookup if [ ! -x $NSLOOKUP -o ! -s $NSLOOKUP ]; then logger ${SYSLOG_FACILITY}.err ¥ "${ARGV0}: $NSLOOKUP does not exist or is not executable" exit 1 fi while true; do # Call nslookup under a timeout, using hatimerun. # The -norecurse option tells in.named not to consult # other name service instances on other hosts beyond the # one on $LOGICAL_HOST. # The -retry=10000 is telling nslookup to take forever # retrying: this means that for a hung server, nslookup # will never itself giveup, rather, the timeout on hatimerun # will expire first. hatimerun -t $PROBE_TIMEOUT_SECS ¥ $NSLOOKUP -norecurse -retry=10000 $LOGICAL_HOST $LOGICAL_HOST if [ $? -ne 99 ]; then sleep $PROBE_INTERVAL_SECS continue fi # Here when the timeout occurred. logger -p ${SYSLOG_FACILITY}.err ¥ "${ARGV0}: nslookup of in.named on $LOGICAL_HOST timed-out" if pmfadm -q hainnamed then # The in.named process exists. Kill it on the # assumption that it is hung. Sleep a short time, # and if hainnamed still exists in the pmfd, assume # that pmfd is restarting it (it has not yet used # up its ration of restarts per time interval.) logger -p ${SYSLOG_FACILITY}.err ¥ "${ARGV0}: KILLing hung in.named" pmfadm -k hainnamed KILL sleep 30 if pmfadm -q hainnamed; then continue fi fi # Here when pmfadm -q says that hainnamed no longer # exists in pmfd. Assume that the ration of restarts # was exhausted. Also assume that something is amiss # that moving to a new master could improve. logger -p ${SYSLOG_FACILITY}.err ¥ "${ARGV0}: in.named restarted too many times, not restarting" logger -p ${SYSLOG_FACILITY}.err ¥ "${ARGV0}: giving up mastery of $LOGICAL_HOST" hactl -g -s hainnamed -k $CLUSTER_KEY -l $LOGICAL_HOST done |