NFS 冗長化 (HAクラスタ構成)(目次)
| Table of Contents |
システム構成
|
HeartbeatとDRBDを利用してNFSのHAクラスタ(Active/Stanby)を実現します。
NFSのデータ(/data)はDRBDでネットワーク越しのデータミラーリングを行い、Heartbeatを利用して自動フェイルオーバーを行ないます。
プライマリ側
-
ホスト名(IP)
- serv11(192.168.11.11)
-
OS
- CentOS 5.5 (kernel 2.6.18-194.11.1.el5)
-
パッケージ
- nfs-utils-lib-1.0.8-7.6.el5
- nfs-utils-1.0.9-47.el5_5
- portmap-4.0-65.2.2.1
- kmod-drbd83-8.3.8-1.el5.centos
- drbd83-8.3.8-1.el5.centos
- heartbeat-2.1.3-3.el5.centos
セカンダリ側
-
ホスト名(IP)
-
OS
- CentOS 5.5 (kernel 2.6.18-194.11.1.el5)
-
パッケージ
- nfs-utils-lib-1.0.8-7.6.el5
- nfs-utils-1.0.9-47.el5_5
- portmap-4.0-65.2.2.1
- kmod-drbd83-8.3.8-1.el5.centos
- drbd83-8.3.8-1.el5.centos
- heartbeat-2.1.3-3.el5.centos
仮想IP
-
ホスト名(IP)
DRBDのインストール・設定
DRBDパーティンションの作成
メタディスク用のパーティンション作成
-
メタディスクのサイズはDRBDユーザーズガイドに計算式があるので参考にして下さい。
ちなみに0.7系では128M固定です。
http://www.drbd.jp/users-guide/ch-internals.html#s-internal-meta-data
-
ざっくり計算すると以下のようになります。
しかし、下記容量ではメタデータ領域が小さいとの警告が出る場合があります。データ容量 メタデータ 10GB 2MB 100GB 5MB 1TB 32MB 10TB 310MB
-
今回のディスクは5GBですが、起動時に警告が表示されるため、200MBのメタデータ領域を作成します。
# fdisk /dev/sdbコマンド (m でヘルプ): nコマンドアクション e 拡張 p 基本領域 (1-4)p領域番号 (1-4): 1最初 シリンダ (1-652, default 1): 1終点 シリンダ または +サイズ または +サイズM または +サイズK (1-652, default 652): +200M
データ用のパーティンション作成
-
残りは全てデータ領域とします。
コマンド (m でヘルプ): nコマンドアクション e 拡張 p 基本領域 (1-4)p領域番号 (1-4): 2最初 シリンダ (26-652, default 26):Using default value 26終点 シリンダ または +サイズ または +サイズM または +サイズK (26-652, default 652):Using default value 652
-
パーティション情報をセーブして終了します。
コマンド (m でヘルプ): w領域テーブルは交換されました!ioctl() を呼び出して領域テーブルを再読込みします。ディスクを同期させます。
DRBDのインストール
-
DRBDはyumで8.3をインストールします。
# yum install drbd83# yum install kmod-drbd83
DRBDの設定
drbd.confの設定
- DRBDの設定を行います。セカンダリ側も同じ設定をします。
- 設定ファイルの詳細については公式サイトを参照の事。 http://www.drbd.jp/documentation/drbd.conf.html
メタファイルの作成
-
meta-diskに「internal」を指定した場合、ext3などのファイルシステムが作成されているとメタファイルの作成に失敗する事があるため、ddコマンドを利用してmeta-diskのデバイスをゼロで埋めます。
詳細は 公式サイトFAQ (英文)を参照# dd if=/dev/zero bs=1M count=1 of=/dev/sdb1; sync
-
メタファイルを作成します。
# drbdadm create-md r0Writing meta data...initializing activity logNOT initialized bitmapNew drbd meta data block successfully created.
自動起動の設定
-
自動起動をonに設定します
# chkconfig drbd on
-
chkconfigコマンドで自動起動のonを確認します。
# chkconfig --list drbddrbd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
DRBDの起動
-
もう1台のDRBDが起動していないため、最初に起動したサーバでは以下のような警告が出ますが、
yesとタイプして先に進みます。起動に成功したら、もう1台も起動します。# /etc/init.d/drbd startStarting DRBD resources: [r0Found valid meta data in the expected location, 0 bytes into /dev/sdb1.d(r0) s(r0) n(r0) ]..........*************************************************************** DRBD's startup script waits for the peer node(s) to appear. - In case this node was already a degraded cluster before the reboot the timeout is 0 seconds. [degr-wfc-timeout] - If the peer was available before the reboot the timeout will expire after 120 seconds. [wfc-timeout] (These values are for resource 'r0'; 0 sec -> wait forever) To abort waiting enter 'yes' [ 13]:yes
-
2台ともDRBDを起動したら、以下のようにして状態を確認します。
「ro:Secondary/Secondary」の通り、起動時は両方ともセカンダリで接続されています。
プライマリへの昇格(プライマリ側のみ)
-
プライマリにしたいサーバで、以下のコマンドを実行するとプライマリへの昇格処理が行われ、同時にデータ同期が実施されます。
# drbdadm -- --overwrite-data-of-peer primary r0
-
データの同期状態を確認します。
DRBDボリュームのマウント(プライマリ側のみ)
-
DRBDボリュームにファイルシステムを作成後、マウントします。
[root@serv11 ~]# mke2fs -j /dev/drbd0[root@serv11 ~]# mount -t ext3 /dev/drbd0 /data/
-
ファイルシステムのマウントを確認します。
-
dfコマンドでもマウントを確認する事が可能です。
[root@serv11 ~]# df -hFilesystem サイズ 使用 残り 使用% マウント位置/dev/mapper/VolGroup00-LogVol00 7.2G 2.7G 4.2G 39% //dev/sda1 99M 25M 70M 26% /boottmpfs 125M 0 125M 0% /dev/shm/dev/drbd0 4.8G 138M 4.4G 3% /data
これでDRBDボリュームが利用可能になります。
DRBDの動作確認
プライマリ側で作成したテストファイルがセカンダリ側でも表示される事を確認します。
-
プライマリ側でテストファイルを作成後、セカンダリに降格させる。
(セカンダリへの降格には、DRBDボリュームをアンマウントさせる必要があります)[root@serv11 ~]# echo test > /data/test.txt[root@serv11 ~]# umount /data[root@serv11 ~]# drbdadm secondary r0
-
セカンダリ側をプライマリに昇格させて、テストファイルを確認します。
[root@serv12 ~]# drbdadm primary r0[root@serv12 ~]# mount -t ext3 /dev/drbd0 /data[root@serv12 ~]# cat /data/test.txttest
プライマリ側で作成したファイルが見れれば、DRBDの動作に問題はありません。
NFSのインストール・設定
NFSのインストール
-
NFSのインストール
# yum install portmap# yum install nfs-utils# yum install nfs-utils-lib
NFSの設定
公開ディレクトリの作成(プライマリ側のみ)
-
公開ディレクトリを作成します。
[root@serv11 ~]# mount -t ext3 /dev/drbd0 /data[root@serv11 ~]# mkdir -m 1777 /data/nfs_dir
-
サービス監視用のディレクトリを作成します。
[root@serv11 ~]# mkdir /data/watch
-
匿名ユーザ(nfsnobody)書き込みを可能にするため、所有者を変更します。
[root@serv11 ~]# chown nfsnobody:nfsnobody /data/nfs_dir/
-
NFSのexports情報など保存するディレクトリをDRBD領域に変更します。
# mv /var/lib/nfs /data/nfs_lib# ln -s /data/nfs_lib /var/lib/nfs
exportsの編集(プライマリ側のみ)
-
/nfs_dir を公開ディレクトリとして設定します。
# vi /etc/exports/data/nfs_dir 192.168.11.0/255.255.255.0(rw,root_squash)/data/watch 127.0.0.1/255.255.255.255(ro,root_squash)
- ・/data/nfs_dir
- 公開ディレクトリ
- ・192.168.11.0/255.255.255.0
- 接続を許可するクライアント
- ・(rw,root_squash)
-
オプション。詳細は下記参照
■一般的なオプションオプション名 説明 ro 読み込み専用でマウント rw 読み書きを許可してマウント async ディレクトリ内のファイルは非同期に反映される(デフォルト) sync asyncと反対。ファイル更新が直ちに行われる wdelay 複数の書き込み処理を1度に行う。NFSサーバ側での更新を一括して行う no_wdelay wdelayとは反対。syncオプションと併用する noaccess 指定したディレクトリを共有しない
■ユーザIDのマッピングに関するオプションオプション 説明 all_squash すべてのUID,GIDを匿名アカウントへマッピング(nfsnobody) anonuid すべてのUIDを匿名アカウントへマッピング anongid すべてのGIDを匿名グループへマッピング(nfsnobody) squash_uids 指定したUIDのユーザをすべて匿名アカウントへマッピング squash_gids 指定したGIDユーザをすべて匿名グループへマッピング map_identity UID,GIDに関する変換を行わない。 map_static UID,GIDに関する変換を定義するマップファイルを指定する root_squash rootアカウントをnfsnobodyへ変換する(デフォルト) no_root_squah root_squashの反対。rootアカウントをroot(サーバ側)へマッピング
-
exportfsコマンドで設定を反映させます。
# exportfs -ra
自動起動の設定
-
NFSはHeartbeat経由で起動する必要があるため自動起動をOFFにします
# chkconfig portmap off# chkconfig nfslock off# chkconfig rpcidmapd off# chkconfig nfs off
Heartbeatのインストール・設定
Heartbeatのインストール
-
yumでインストールします。 先にstonithをインストールしないとheartbeatのインストールに失敗します。
# yum install heartbeat-stonith# yum install heartbeat
Heartbeatの設定
-
heartbeatの設定で利用するファイルは以下の通りです。尚、heartbeatの設定は特に記述がない限り、プライマリとセカンダリで全く同じ設定を行います。
ファイル名 説明 備考 /etc/ha.d/ha.cf クラスタ構成を定義するメイン設定ファイル /etc/ha.d/haresources Version1用のリソース設定ファイル /etc/ha.d/authkeys 認証設定ファイル
準備
-
設定ファイルはサンプルがあるのでコピーします。
# cp /usr/share/doc/heartbeat-2.1.3/authkeys /etc/ha.d/# cp /usr/share/doc/heartbeat-2.1.3/ha.cf /etc/ha.d/# cp /usr/share/doc/heartbeat-2.1.3/haresources /etc/ha.d/
-
NFSの起動スクリプトを修正します。
標準スクリプトのままだとrpc関連が正しく終了されないため、DRBD領域がアンマウントできずフェイルオーバーに失敗します。
#!/bin/sh## nfs This shell script takes care of starting and stopping# the NFS services.## chkconfig: - 60 20# description: NFS is a popular protocol for file sharing across TCP/IP \# networks. This service provides NFS server functionality, \# which is configured via the /etc/exports file.# probe: true# config: /etc/sysconfig/nfs# Source function library.. /etc/rc.d/init.d/functions# Source networking configuration.[ -f /etc/sysconfig/network ] && . /etc/sysconfig/network# Check for and source configuration file otherwise set defaults[ -f /etc/sysconfig/nfs ] && . /etc/sysconfig/nfs# Remote quota server[ -z "$RQUOTAD" ] && RQUOTAD=`type -path rpc.rquotad`RETVAL=0# See how we were called.case "$1" in start) : :(省略) : stop) # Stop daemons. echo -n $"Shutting down NFS mountd: " killproc rpc.mountd echo echo -n $"Shutting down NFS daemon: " killproc nfsd #■修正 echo if [ -n "$RQUOTAD" -a "$RQUOTAD" != "no" ]; then echo -n $"Shutting down NFS quotas: " killproc rpc.rquotad RETVAL=$? echo fi # Do it the last so that clients can still access the server # when the server is running. cnt=`/usr/sbin/exportfs -v | /usr/bin/wc -l` if [ $cnt -gt 0 ]; then action $"Shutting down NFS services: " /usr/sbin/exportfs -au else action $"Shutting down NFS services: " /bin/false fi [ -x /usr/sbin/rpc.svcgssd ] && /sbin/service rpcsvcgssd stop rm -f /var/lock/subsys/nfs ;; *) : :(省略) :esacexit $RETVAL
-
NFSは関連デーモンが多いため、専用のリソース起動スクリプトを用意します。
# vi /etc/ha.d/resource.d/nfs #!/bin/bash## /etc/ha.d/resource.d/nfs#PATH=/bin:/usr/bin:/sbin:/usr/sbinexport PATHstart() { mount -t rpc_pipefs sunrpc /var/lib/nfs/rpc_pipefs service portmap start service rpcidmapd start service nfslock start service nfs start exit 0}stop() { service nfs stop service nfslock stop service rpcidmapd stop service portmap stop umount /var/lib/nfs/rpc_pipefs}case "$1" in start) start ;; stop) stop ;; *) echo $"Usage: $0 {start|stop}" exit 1esacexit 0
ha.cfの設定
-
ha.cfを編集します。ほとんどの設定がコメントアウトを解除しただけです。
# vi /etc/ha.d/ha.cflogfile /var/log/ha-loglogfacility local0keepalive 2deadtime 30warntime 10initdead 120udpport 694#baud 19200 # シリアルケーブル用の設定(今回は利用しない)#serial /dev/ttyS0 # シリアルケーブル用の設定(今回は利用しない)bcast eth0 auto_failback offnode serv11 #uname -nnode serv12 #uname -nrespawn root /usr/local/bin/check_service #サービス監視スクリプト
haresourcesの設定
-
共有リソースの設定はDRBDに関する設定を一行追加します。
- 書式 [node-name resource1 resource2 ... resourceN]
- resourceの部分は「/etc/ha.d/resource.d」配下のファイル名を記載します。
- 各リソースに渡す引数は「::」で区切って記述します。
-
リソースがIPADDRの場合はリソース名を省略可能です。
# vi /etc/ha.d/haresourcesserv11 drbddisk::r0 Filesystem::/dev/drbd0::/data::ext3 192.168.11.10/24 nfs
authkeysの設定
-
認証の設定を行います。認証は現時点で最もセキュリティレベルの高いsha1を利用します。
# vi /etc/ha.d/authkeysauth 22 sha1 test
-
セキュリティを確保するため、ファイルパーミッションを変更します。セカンダリ側も同様に設定します。
# chmod 600 /etc/ha.d/authkeys
サービス監視スクリプトの作成
-
heartbeatはサーバ間のフェイルオーバを自動的に行いますが、NFSサービスが異常終了してもフェイルオーバしません。
そのため、監視スクリプトを作成してサービスが正しく動作している事を監視する必要があります。# vi /usr/local/bin/check_service#!/bin/sh#=============================================# heartbeat用 NFSサービス監視スクリプト#=============================================#-----------------------------------------------------------------INTERVAL=5 # 監視間隔VIP=192.168.11.10 # 仮想IPGATEWAY=192.168.11.1 # ゲートウェイNFS_DIR=/data/watch # サービス確認用のNFSディレクトリMNT_POINT=/mnt/nfs # マウントポイント#-----------------------------------------------------------------#ログを記録するLog_Write() { /bin/logger -p local0.crit -t "check_service" $1}#-----------------------------------------------------------------while :do sleep $INTERVAL # # 仮想IPアドレスの有無を確認 # /etc/ha.d/resource.d/IPaddr $VIP status > /dev/null 2>&1 if [ $? -ne 0 ] then continue fi # # ゲートウェイとの通信確認 # ping -c 1 -w 1 $GATEWAY > /dev/null 2>&1 if [ $? -ne 0 ] then Log_Write "Destination ".$GATEWAY." Unreachable" /usr/lib/heartbeat/heartbeat -k exit fi # # NFSのサービス確認 # mount -t nfs 127.0.0.1:$NFS_DIR $MNT_POINT if [ $? -ne 0 ] then Log_Write "NFS service failed" /usr/lib/heartbeat/heartbeat -k exit else umount $MNT_POINT fidone※whileの後の:(コロン)はtrueと同じですが、:の方がtrueより実行効率が良いです。
-
スクリプトに実行権限を付与します。
# chmod +x /usr/local/bin/check_service
-
サービス確認用のマウントポイントを作成します。
# mkdir /mnt/nfs
自動起動の設定
-
自動起動をonに設定します。セカンダリ側も同様に設定します。
# chkconfig heartbeat on
-
chkconfigコマンドで自動起動のonを確認します。
# chkconfig --list heartbeat heartbeat 0:off 1:off 2:on 3:on 4:on 5:on 6:off
Heartbeatの起動
-
NFSサービスを停止させDRBDをセカンダリへ変更します。
# /etc/init.d/nfs stop# /etc/init.d/nfslock stop# /etc/init.d/rpcidmapd stop# /etc/init.d/portmap stop# umount /data# drbdadm secondary r0
-
Heartbeatを起動します。セカンダリ側も同様に起動させます。
# /etc/init.d/heartbeat start
冗長化(HA)の動作確認
プライマリ側のNFSを停止させてフェイルオーバーの動作確認を行います。
初期状態の確認
-
serv11(プライマリ側)の状態を確認します。
仮想IPが割り当てられている事を確認します。[root@serv11 ~]# ifconfig -a eth0:0eth0:0 Link encap:Ethernet HWaddr 00:0C:29:BF:CC:32 inet addr:192.168.11.10 Bcast:192.168.11.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 Interrupt:177 Base address:0x1400
DRBD領域をマウントしている事を確認します。
NFSが起動されている事を確認します。[root@serv11 ~]# ps ax |grep nfsd17170 ? S< 0:00 [nfsd4]17171 ? S 0:00 [nfsd]17172 ? S 0:00 [nfsd]17173 ? S 0:00 [nfsd]17174 ? S 0:00 [nfsd]17175 ? S 0:00 [nfsd]
-
serv12(セカンダリ側)の状態を確認します。
仮想IPが割り当てられていない事を確認します。[root@serv12 ~]# ifconfig -a eth0:0eth0:0 Link encap:Ethernet HWaddr 00:0C:29:0F:CB:EB UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 Interrupt:177 Base address:0x1400
DRBD領域もマウントされていない事を確認します。
NFSが起動していない事を確認します。[root@serv12 ~]# ps ax |grep nfsd
フェイルオーバーの確認
-
フェイルオーバーの確認をするため、serv11(プライマリ側)のNFSを停止させます。
[root@serv11 ~]# killall -9 nfsd
-
serv11の状態を確認します。
NFSを終了させたため、仮想IPが割り当てられていません。[root@serv11 ~]# ifconfig -a eth0:0eth0:0 Link encap:Ethernet HWaddr 00:0C:29:BF:CC:32 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 Interrupt:177 Base address:0x1400
DRBD領域もマウントされていません。
NFSも起動していません。[root@serv11 ~]# ps ax |grep nfsd
-
serv12の状態を確認します。
serv11側でNFSを終了させたため、仮想IPが割り当てられています。[root@serv12 ~]# ifconfig -a eth0:0eth0:0 Link encap:Ethernet HWaddr 00:0C:29:0F:CB:EB inet addr:192.168.11.10 Bcast:192.168.11.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 Interrupt:177 Base address:0x1400
DRBD領域もマウントされています。
NFSも起動しています。[root@serv12 ~]# ps ax |grep nfsd 9454 ? S< 0:00 [nfsd4] 9455 ? S 0:00 [nfsd] 9456 ? S 0:00 [nfsd] 9457 ? S 0:00 [nfsd] 9458 ? S 0:00 [nfsd] 9459 ? S 0:00 [nfsd]
-
serv11側のheartbeatがサービス監視スクリプトにより停止しているため起動させます。
[root@serv11 ~]# /etc/init.d/heartbeat startlogd is already runningStarting High-Availability services: [ OK ]
以上でフェイルオーバの確認は終了です。
-
ちなみに、NFSクライアントを用意してファイルオープン中にフェイルオーバーさせましたが
特に問題ありませんでした。
FAQ
Q. rpcidmapdが起動できない
# /etc/init.d/rpcidmapd startRPC idmapd を起動中: Error: RPC MTAB does not exist.
-
A.
下記を実行する事で解決します。
# mount -t rpc_pipefs sunrpc /var/lib/nfs/rpc_pipefs
Q. NFS領域をアンマウントできない
# umount /dataumount: /data: デバイスを使用中です
-
A.
下記手順でアンマウントして下さい。
-
mtabで現在マウント状況を確認します。
# cat /etc/mtabrpc_pipefs /data/nfs_lib/rpc_pipefs rpc_pipefs rw 0 0
-
関係するものがあればアンマウントします。
# umount rpc_pipefs
-
次に該当ディレクトリにユーザが居ないか確認します。
# fuser -mv /data USER PID ACCESS COMMAND/data: root 2566 ..c.. bash
-
ユーザに移動してもらうか、プロセスをkillします。(killはおすすめしません)
# kill 2566
-
それでも解決しない場合は強制的にアンマウントします。(当然おすすめしません)
# umount -l /data
-
mtabで現在マウント状況を確認します。