3.4.1 ハートビートを用いたNFSのHA構成

（2016年時点での内容をアーカイブとして掲載しているため、一部の掲載内容が最新情報とは異なる場合がありますので、ご了承ください。最新のIBM Cloudのアップデート情報は[IBM Cloud アップデート情報](https://www.ibm.com/cloud-computing/jp/ja/cloud-update/) や [柔らか層本](https://ibm.ent.box.com/v/ibmcloud-yawaraka)をご参照ください。）

概要
ハートビート(Heartbeat)を利用して高可用性(High Availability)構成を作る例として、NFSサーバーを題材にして、共有ディスクにエンデュランス・ストレージを利用する方法をご紹介します。
 

NFSの高可用性構成
今回、構築する構成は、次の図のようになります。 主としてNFSサービスを提供するサーバー、そして、待機サーバーは、主サーバーの障害時に VIP(仮想IP)アドレスを引き継ぎます。 このVIPは、NFSを利用するクライアントが、NFSサービスとしてアクセスするIPアドレスです。 引き継ぎ後に、待機サーバーでVIPが有効になることで、NFSのクライアントは、障害前と同じようにNFSサービスを利用して業務処理を継続できます。 エンデュランス・ストレージのiSCSIストレージは、本番サーバーと待機サーバーからアクセス可能なIPアドレスを持ち、どちらからでも同じようにアクセスできます。 エンデュランス・ストレージをiSCSIとして注文する方法は、1.6.7 エンデュランス・ストレージを利用するには？の章にあります。

高可用性構成の動作としては、図の本番サーバーと待機サーバーの間で、相互に監視を行ないます。 待機サーバーのハートビートのプロセスが、主となる本番サーバーの存在を確認できなくなった時に、待機サーバー上でペースメーカーのプロセスが、NFSサーバーのプロセスを起動しVIPアドレスを有効にします。 このハートビートとペースメーカーの概要は、3.4 アクティブ・スタンバイのサーバーを構成するには？の章にあります。

VIPは、仮想サーバーや物理サーバーの起動時に付与されるIPアドレス以外のものを利用する必要があります。 クラウドの環境では、同じサブネットの空いているIPアドレスを適当にVIPとして使うと、IPアドレスは、クラウドの管理システムが割当を行なうため、新しく起動するサーバーのIPアドレスと同じになるといった障害になる恐れがあります。 そこで、SoftLayerでは、ポータブルIPという機能を活用します。 この機能の利用方法は、4.2 サーバーが変わっても同じIPアドレスを利用するには？の章にあります。


構成に必要な材料の注文
以下の3点をカスタマーポータル ( https://control.softlayer.com/ )から注文します。

1. 仮想サーバー CentOS 6.x - Minimal Install (64 bit) x 1
2. ポータブルIPアドレス（8 Portable Private IP Addresses）× 1
3. エンデュランス・ストレージ × 1 （SATAディスク並みの 200 IOPSの場合、 2IOPS/GBタイプで100GB）

仮想サーバーは、NFSサーバー用に1台オーダーします。 ここで、アレっと思った方もいると思います。 NFSサーバーは2台とNFSクライアントの計3台が必要ですよね。 ここではクラウドならではの必殺技として、最初の1台を作った後に複製して3台にします。 このようにすれば作業時間は半分近くに短縮できます。

プライベートのポータブルIPアドレスは、無料ですので少し多めに、8個を確保しておきます。 この8個の内、3つはゲートウェイ、ネットワークアドレス、ブロードキャストアドレスとして、予約されていますので、5個を使うことができます。 ただし、プライベートの場合、SoftLayerのHSRP（Hot Standby Router Protocol: Ciscoが開発したルーティング冗長化プロトコルで、障害時等にActiveルータとStandbyルータとの切り替えを実現）の予約アドレスが含まれることがあり、3個しか使えないことがあります。

これらの注文の方法は、仮想サーバーは1.2 仮想サーバーを起動するには？、ポータブルIPアドレスは4.2 サーバーが変わっても同じIPアドレスを利用するには？、エンデュランス・ストレージをiSCSIとして注文する方法は、1.6.7 エンデュランス・ストレージを利用するには？の章にあります。そして、2台目のNFSサーバーを作るには、3.2 サーバーのクローンを作るには？の方法を利用していきます。

ここでは、分かりやすくするために、最初にまとめて注文するようにしていますが、仮想サーバーの費用を節約するには、必要な都度、注文する方法もあります。

追加ソフトウェアのインストール
仮想サーバーが起動したら、sshでログインして、NFSのツール、ハートビートやペースメーカーを導入していきます。 仮想サーバーにログインする方法は、1.4 物理サーバーや仮想サーバーログインするには？を参照してください。

作業開始前に、Linux OSに更新をすべて適用しておきます。
 
```
# yum update
```

iSCSI
 
```
# yum install iscsi-initiator-utils -y
```

NFS
 
```
# yum -y install nfs-utils
```

ハートビート＆ペースメーカー

ハートビートは、SOURCEFORGE.JP (http://sourceforge.jp/projects/linux-ha/releases/61791 ) から pacemaker-1.0.13-2.1.el6.x86_64.repo.tar.gz をダウンロードします。 このペースメーカーのtarには、ハートビートも含まれています。 今回は、ファイル名からもわかるとおり、2014/12月現在最新のpacemaker-1.0.13-2.1を利用します。 ブラウザから一旦パソコンに、ダウンロードして、仮想サーバーへ再度転送しても良いですが、仮想サーバーから直接SOURCEFORGE.JPへ接続してダウンロードもできます。 以下は後者の例です。
 
```
# wget 'http://sourceforge.jp/frs/redir.php？m=iij&f=%2Flinux-ha%2F61791%2Fpacemaker-1.0.13-2.1.el6.x86_64.repo.tar.gz' -O pacemaker-1.0.13-2.1.el6.i686.repo.tar.gz
# tar xzvf pacemaker-1.0.13-2.1.el6.i686.repo.tar.gz
# mv pacemaker-1.0.13-2.1.el6.x86_64.repo /tmp
# cd /tmp/pacemaker-1.0.13-2.1.el6.x86_64.repo
# yum -c pacemaker.repo install heartbeat.x86_64
# yum -c pacemaker.repo install pacemaker.x86_64
```

仮想サーバーとiSCSIストレージの接続
エンデュランス・ストレージをiSCSIで接続する方法は、1.6.7 エンデュランス・ストレージを利用するには？ LinuxのiSCSIシングルパス設定の章にあります。

デバイスとして認識できるようになったら、/dev/sda にファイルシステムを作成して、マウントできるようにします。
 
```
# mkfs.ext4 /dev/sda
```

マウントポイントになるディレクトリを作成して、iSCSIストレージをマウントして、dfコマンドで確認します。 次の画面のように、/export としてiSCSIのディスクがマウントされていることが確認できました。
 
```
# mkdir /export
# mount -t ext4 /dev/sda /export
# df -h

Filesystem      Size  Used Avail Use% Mounted on
/dev/xvda2       25G  1.2G   23G   5% /
tmpfs           497M     0  497M   0% /dev/shm
/dev/xvda1      248M   58M  179M  25% /boot
/dev/sda         20G   44M   19G   1% /export
```

NFSサーバーの設定
次に、/exportディレクトリをNFSで外部のサーバーからアクセスできるように/etc/exportsファイルに設定します。

```
# vi /etc/exports
/export *(rw,fsid=0,sync,no_root_squash,subtree_check)
```

この設定は、/export のディレクトリをアスタリスクで指定される任意のサーバーへ、以下の条件でアクセスを許可するものです。
 

  rw ファイルシステムのマウントを読み書き可能とします。
  fsid=0 待機サーバーへ切り替わった場合、fsidが変わることでfidが変わり開いていたファイルがアクセスできなくなることを防止のため、指定しておきます。
  sync NFSサーバがディスクへの書き込みが実際に行われるのを確認してから、次の書き込み要求に応答します。
  no_root_squash NFSクライアントが、root権限での書き込み可能とします。
  subtree_check NFSリクエスト発行の度に、現在のアクセス権限がツリー階層をさかのぼっても有効であるか、毎回チェックします。

NFSサービスを起動します。
 
```
# service rpcbind start
# service nfslock start
# service nfs start
```

エクスポートするファイル・システムの設定を有効化します。

```
# exportfs -a
# exportfs
/export
```

NFSサービスはペースメーカーが制御するため、自動起動を無効にします。
 
```
# chkconfig nfs off
```

NFSの設定が完了しました。 最後にiSCSIをアンマウントしておきます。
 
```
# umount /dev/sda
```

ポータブルIPの設定
NFSクライアントがアクセスするVIPを設定します。 この設定は、haresources の中に設定するため、後述の「ハートビート＆ペースメーカーの設定」の章をご参照お願いします。
 

ハートビートの設定ファイル
ハートビートの設定ファイルをサンプルからコピーしておき、サーバーの複製後からの作業の手間を省けるようにします。

```
# cp /usr/share/doc/heartbeat-3.0.4/authkeys /etc/ha.d/
# cp /usr/share/doc/heartbeat-3.0.4/haresources /etc/ha.d/
# cp /usr/share/doc/heartbeat-3.0.4/ha.cf /etc/ha.d/
```

authkeysファイルの設定をします。 これは1台目と2台目で同一の値が設定されている必要があります。 推奨の設定はmd5ですが、crcで設定してみます。
 
```
# vi /etc/ha.d/authkeys
# cat /etc/ha.d/authkeys

auth 1
1 crc
#2 sha1 HI!
#3 md5 Hello!
```

クラスター間の認証情報ですから、root以外から参照できないように600を設定します。
 
```
# chmod 600 authkeys
```

NFSを起動するために、以下のファイルを他のファイルからコピーして作成します。
 
```
# pwd
/etc/ha.d/resource.d
# cp apache nfsserver

# vi nfsserver   <-- 編集
# cat nfsserver
#!/bin/sh
#
...省略
. /etc/ha.d/resource.d//hto-mapfuncs

usage() {
    echo "usage: $0 [config-file-pathname] $LEGAL_ACTIONS"
    exit 1
}

case $# in
  1)    op=$1
    ;;
  2)    OCF_RESKEY_configfile=$1; export OCF_RESKEY_configfile
    op=$2
    ;;
  *)    usage
    ;;
esac

OCF_TYPE=nfsserver   <--- 元の文字列から nfsserverに置き換え
OCF_RESOURCE_INSTANCE=${OCF_TYPE}_$OCF_RESKEY_configfile
export OCF_TYPE OCF_RESOURCE_INSTANCE

ra_execocf $op
```

仮想サーバーの複製
ここまで作成してきた仮想サーバーをマスターのイメージにして、スタンバイになるサーバーを作成します。 この作成方法は、3.2 サーバーのクローンを作るには？を参照してください。 イメージから新たなサーバーを起動する場合、元の仮想サーバーと同じVLANに作成する必要があります。 この理由は、VIPを利用するポータブルIPはVLANに割当られるためです。 新たに起動される仮想サーバーのIPアドレスは、異なるアドレスが付与され、ホスト名は起動時に指定したものが付与されます。

複製されたサーバーのIPアドレスのサブネットは、元になったサーバーと異なるサブネットに割り当てられる可能性がありますが、VLANが同じであれば、ポータブルIPを利用することに問題はありません。

物理サーバーの場合には、フレックス・イメージを利用することで、同じように2台目のサーバーを複製することができます。
 

ハートビート＆ペースメーカーの設定
アクティブ側とスタンバイ側のサーバーに、それぞれハートビートの設定を行ないます。 先にコピーしたサンプル・ファイルには、各パラメータの意味がコメントされているので、参考にパラメータを決定します。 ここでの設定内容は、アクティブとスタンバイ間でeth0からudpポート694で相互監視をするという設定になります。 次の編集例は、見やすくするために、設定項目を抜き出したものです。
 
```
# vi /etc/ha.d/ha.cf
# cat /etc/ha.d/ha.cf

debugfile /var/log/ha-debug
logfile /var/log/ha-log
logfacility local0
keepalive 2
deadtime 30
warntime 10
initdead 120
udpport 694
ucast eth0 10.52.21.72     <-- 対向サーバーのIPアドレスを指定  (設定内容が異なる）
auto_failback off
node anfs01a.example.com  <-- クラスタのメンバーのホスト名  uname -n と同じものを設定
node anfs02a.example.com  <-- 同上
ping 10.52.21.65  <-- デフォルト・ゲートウェイのIPアドレスを指定  (同じVLANでもサブネットが変わるとアドレスが変わるので設定必要なケースもある)
```

このファイルの設定に加えて、/etc/hostsにクラスタメンバーのホスト名とIPアドレスを登録しておく必要があります。 アクティブ側とスタンバイ側の2台のサーバーが決まったら、この登録名でpingで応答があることを確認します。

ペースメーカがリソースを制御するための /etc/ha.d/haresources を設定します。 今回の構成では、3つのリソースを登録しています。 このファイルに記載された左から順に実行します。 また、リソースを停止するときには右から順に実行します。 従って、依存関係を考慮して以下の順番で登録します。 スペースで区切って、「アクティブのホスト名」「Filesystemのマウント情報」「仮想IP NFSサービス」で1行で記載しています。 このファイルも2つのサーバー間で同じものである必要があります。 特に、先頭のフィールドのホスト名は、アクティブ側のサーバー名として一致している必要があります。 もし間違えて、それぞれのサーバー名とすると、二つのサーバーがアクティブになってしまいます。
 
```
# vi /etc/ha.d/haresources
...省略
anfs01a.example.com Filesystem::/dev/sda::/export::ext4 IPaddr::10.52.82.50/29/eth0:1 nfsserver
```

実行環境に合わせて、/etc/ha.d/shellfuncs ファイルを変更します。 今回のCentOS6は、64ビット版を利用しているので、HA_BIN変数に、/usr/lib64/heartbeatを定義します。
 
```
# vi /etc/ha.d/shellfuncs
...省略
: ${HA_SBIN_DIR:=/usr/sbin}
: ${HA_NOARCHBIN:=/usr/share/heartbeat}
: ${OCF_AGENTS:=/usr/lib/ocf/resource.d//heartbeat/}
HA_BIN=/usr/lib64/heartbeat  <-- 追加

export HA_DIR HA_RCDIR HA_FIFO HA_BIN
export HA_DEBUGLOG HA_LOGFILE HA_LOGFACILITY
export HA_DATEFMT HA_RESOURCEDIR HA_DOCDIR
export OCF_AGENTS 
```

ハートビートの自動起動を設定します。
 
```
# chkconfig heartbeat on
```

ハートビートの動作確認
アクティブ側サーバーとスタンバイ側サーバーで、順番にハートビートを起動します。 正常に起動すれば、メッセージが表示されます。 この時、何も表示されないでサービスが起動しない場合は、shellfuncsを確認してみることをお勧めします。
 
```
# /etc/init.d/heartbeat start

Starting High-Availability services: Done.
```

しばらくすると、クラスタの動作が開始されます。 以下のようなコマンドで、リソースが確保され、NFSのサービスが稼働していることが確認できます。
 
```
# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvda2       25G  1.4G   22G   6% /
tmpfs           497M     0  497M   0% /dev/shm
/dev/xvda1      248M   83M  153M  35% /boot
/dev/sda1        20G   44M   19G   1% /export ←/exportがマウントされていることを確認します。


# ip addr show eth0:1
2: eth0:  mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 06:c1:f1:f3:92:92 brd ff:ff:ff:ff:ff:ff
    inet 10.52.21.72/26 brd 10.52.21.127 scope global eth0
    inet 10.52.82.50/29 scope global eth0:1 ←VIPが割り当たっていることを確認します。
    inet6 fe80::4c1:f1ff:fef3:9292/64 scope link
       valid_lft forever preferred_lft forever

# service nfs status
...省略
nfsd (pid 12568 12567 12566 12565 12564 12563 12562 12561) is running...
rpc.rquotad (pid 12547) is running...
```

この状態で、次のようにして、アクティブ側を停止させると、スタンバイ側にリソースが移ることが確認できます。
 
```
# /etc/init.d/heartbeat stop
```

動作確認
NFSクライアントからNFSサーバーをマウントして、NFSサーバーが待機サーバーへ切り替わっても、NFS上のファイルが継続して利用できることを確認します。 ここでも、「サーバーの複製」で使ったイメージを使って、簡単にNFSクライアントを起動します。 今回は、NFSクライアントとNFSサーバーをポータブルIPのサブネット上で繋いでしまいます。 /etc/sysconfig/network-script/ifcfg-eth0:1を編集して、ポータブルIPアドレスの中から 10.52.82.51 を設定します。
 
```
# vi /etc/sysconfig/network-scripts/ifcfg-eth0:1

DEVICE=eth0:1
BOOTPROTO=static
ONBOOT=yes
HWADDR=06:59:70:dd:07:fc
IPADDR=10.52.82.51
NETMASK=255.255.255.248
```

ここで作成したサブ・インターフェース(eth0:1)を有効にします。 ここまでの設定でポータブルIPを利用した通信が可能になります。
 
```
# ifup eht0:1
```

NFSクライアントを動作させるためのサービスを起動します。 そして、起動時からNFSクライアントが利用できるように設定します。
 
```
# service rpcbind start
# service nfslock start
# chkconfig nfslock on
# chkconfig rpcbind on
```

マウント・ポイントを作成して、NFSをマウントします。 /etc/fstabを設定すると mount /nfs でマウントできるようになります。
 
```
# mkdir /nfs
# mount -t nfs 10.52.82.50:/export /nfs
```

NFSの共有ドライブがマウントされていることを確認します。
 
```
# df -h
Filesystem           Size  Used Avail Use% Mounted on
/dev/xvda2            25G  1.2G   22G   6% /
tmpfs                497M     0  497M   0% /dev/shm
/dev/xvda1           248M   58M  179M  25% /boot
10.52.82.50:/export   20G   44M   19G   1% /nfs     <-- NFSの共有ドライブがマウントされています。
```

マウントが成功したら、NFSクライアント上の/exportに、テストファイル(test)を作成しましょう。
 
```
# touch /nfs/test
# ls /nfs
lost+found  test
```

待機サーバーへの切換えを実施します。 NFSサーバーが動作しているサーバーのハートビートを停止して、待機サーバーへ切り替わります。 NFSクライアントが、NFS上のサーバーを利用できるまでには、数十秒必要になります。
 
```
# service heartbeat stop
Stopping High-Availability services: Done.
```

NFSクライアントで、継続してテストファイル(test)が存在していることを確認します。 次のように、切換え後もファイルが存在していることを確認できました。
 
```
# ls /nfs
lost+found  test
```