Thirdware Linux-HA による
nginx Web サーバのクラスタ構築
HOWTO
2012 年 3 月 1 日 初版
目次
1 はじめに...1 1.1 対象読者...1 1.2 想定するサーバ環境...1 1.3 注意事項...1 2 OS 環境の準備...2 2.1 CentOS 6.2 のインストールと初期設定...2 2.2 Thirdware Linux-HA クラスタスタックのインストール...2 RHEL6、CentOS6、Scientific Linux 6 の場合...2 RHEL5、CentOS5 の場合...2 2.3 nginx パッケージのインストール...3 3 DRBD の設定...3 4 nginx クラスタ化のためのデータ領域の準備...5 5 nginx クラスタの構築...5 6 nginx リソースエージェント...7改訂履歴
版番号 改訂年月日 作成者 備考
Thirdware Linux-HA による nginx Web サーバのクラスタ構築 HOWTO
1 はじめに
nginx (「えんじんえっくす」と発音)はロシアの Igor Sysoev が開発・配布するオープンソースの Web サー バソフトウェアで、リバースプロキシサーバやメールプロキシとしても利用できる。少ないリソースで軽快に 動作することや設定の容易さから、nginx を採用する Web サイトが急速に増えている。開発者自身による 商用サポートが始まったこともあって、今後さらに採用事例が増加すると期待されている。
本書では、Thirdware Linux-HA クラスタスタックを使って nginx を HA クラスタとして動作させるための 設定手順の概要を紹介する。
1.1 対象読者
このドキュメントは、以下の知識や経験を有する技術者を対象としている。 • Linux サーバのインストール、運用管理ができること • Thirdware Linux-HA による HA クラスタシステムの構築と運用の基礎知識を持っていること • nginx のインストールと運用ができること 本書では Linux のインストールからクラスタ構築までの流れをひととおり説明するが、初心者向けとして は説明が不親切な箇所があるかもしれない。1.2 想定するサーバ環境
本書が想定するサーバ環境は、Linux ならびに nginx が動作する IA サーバ(32 ビット、64 ビット)である。 以下の説明では、KVM 仮想環境のゲスト OS を用いている。そのハードウェアおよびソフトウェアの特徴 は以下のとおりである。 • 仮想 CPU は 1 個、メモリは 512MB 割り当ててある。 • 仮想ディスクは 8GB を割り当ててある(デバイス名は/dev/vda)。 • 仮想ネットワークインタフェースは3つ割り当ててある(et0、eth1、eth2)。 • CnetOS 6.2 (64 ビット)を最小構成でインストールしてある。 • 仮想ディスクは OS 領域に 4 ギガバイト、スワップ領域に 500 メガバイト、DRBD によるレプリケー ション領域に残り全部を割り当てる。1.3 注意事項
本書は、nginx を HA クラスタ構成にするための基本的な流れを説明したマニュアルという位置付けに なっている。このため、各種設定パラメータも必要最小限の項目に絞っている。パフォーマンスや運用上 のポリシーにもとづく追加パラメータは含まれていない。 株式会社サードウェア 1Thirdware Linux-HA による nginx Web サーバのクラスタ構築 HOWTO
2 OS 環境の準備
2.1 CentOS 6.2 のインストールと初期設定
ステップ1: Linux をインストールする CentOS 6.2 の DVD イメージを使って OS をインストールする。ハードディスクのパーティションを作 成するときに「カスタム」を選び、DRBD によるレプリケーション領域を空けておくこと以外は、一般 的なインストール手順と変わらない。 ステップ2: SELinux を無効にするインストール後最初の起動時に、SELinux を無効にする(/etc/sysconfig/selinux の SELINUX=行を enforcing から disabled に書き換える)。
ステップ3: パケットフィルタリングを調整する
DRBD や heartbeat は ク ラ ス タ ノ ー ド 間 の 通 信 が 不 可 欠 な た め 、 ク ラ ス タ ノ ー ド 間 の 7788/tcp、694/udp、22/tcp を宛先とするパケットを許可するよう、iptables (または ip6tables)のフィル タリング定義を調整する。 ネットワークを設定する ネットワークは、以下の条件を満たすように設定する。これは、インストール時でもインストール後の 調整でもかまわない。 ◦ eth0 はサーバセグメントの LAN に接続する。 ◦ eth1 および eth2 は、クラスタノード間で通信できるような IP アドレスを設定する(物理 サーバを使う場合は、eth1 同士、eth2 同士をネットワークケーブルで直結することを推奨 する)。
2.2 Thirdware Linux-HA クラスタスタックのインストール
LINBIT クラスタスタック・サポート契約ユーザ向けに提供される認定バイナリのリポジトリを使うのが もっとも間違いが少なく、将来のメンテナンスも容易になる。未契約ユーザの場合は、以下のパッケージ を使うのがよいと思われる(2012 年 2 月現在)。ただし、以下の方法は未検証である。 RHEL6、CentOS6、Scientific Linux 6 の場合Heartbeat および Pacemaker は Linux-HA Japan プロジェクト1が提供している「Pacemaker リポジトリパッ
ケージ」が利用できる。DRBD のバイナリ RPM パッケージは、ELRepo プロジェクト2が DRBD 8.3.x の最
新バージョンを提供しているので、これを利用するといいと思われる。
RHEL5、CentOS5 の場合
Heartbeat および Pacemaker は Linux-HA Japan プロジェクト3が提供している「Pacemaker リポジトリパッ
ケージ」が利用できる。DRBD のバイナリ RPM パッケージは、CentOS extra リポジトリに drbd83 パッケー ジが用意されているので、これを使うのがいいと思われる。 1 http://linux-ha.sourceforge.jp/wp/dl/packages 2 http://elrepo.org/tiki/tiki-index.php 3 http://linux-ha.sourceforge.jp/wp/dl/packages 株式会社サードウェア 2
Thirdware Linux-HA による nginx Web サーバのクラスタ構築 HOWTO
2.3 nginx パッケージのインストール
nginx は、同ソフトの開発コミュニティ Web サイト(http://nginx.org/en/download.html)から安定バージョン のビルド済みパッケージをダウンロードできるので、これを使った。
3 DRBD の設定
ステップ1: レプリケーション用パーティションを確保する インストール時に空けておいたディスク領域を fdisk コマンドなどでパーティションとして確保する。 必要に応じて再起動して、OS にパーティションを認識させる。以下の例では/dev/vda3 が DRBD のレプリケーション領域である。 ステップ2: DRBD 設定ファイルを作成する クラスタのどちらか 1 台で DRBD 設定ファイルを作成し、他方に ssh コマンドでリモートコピーする。 設定例は以下のようになる。 /etc/drbd.conf# You can find an example in /usr/share/doc/drbd.../drbd.conf.example include "drbd.d/global_common.conf";
include "drbd.d/*.res";
/etc/drbd.d/global_common.conf
global {
usage-count yes;
# minor-count dialog-refresh disable-ip-verification }
common {
protocol C; handlers {
pri-on-incon-degr "/usr/lib/drbd/notify-pri-on-incon-degr.sh; /usr/lib/drbd/notify-emergency-reboot.sh; echo b > /proc/sysrq-trigger ; reboot -f";
pri-lost-after-sb "/usr/lib/drbd/notify-pri-lost-after-sb.sh; /usr/lib/drbd/notify-emergency-reboot.sh; echo b > /proc/sysrq-trigger ; reboot -f";
local-io-error "/usr/lib/drbd/notify-io-error.sh;
/usr/lib/drbd/notify-emergency-shutdown.sh; echo o > /proc/sysrq-trigger ; halt -f";
# fence-peer "/usr/lib/drbd/crm-fence-peer.sh";
# split-brain "/usr/lib/drbd/notify-split-brain.sh root"; # out-of-sync "/usr/lib/drbd/notify-out-of-sync.sh root";
# before-resync-target "/usr/lib/drbd/snapshot-resync-target-lvm.sh -p 15 -- -c 16k";
# after-resync-target /usr/lib/drbd/unsnapshot-resync-target-lvm.sh; }
startup {
# wfc-timeout degr-wfc-timeout outdated-wfc-timeout wait-after-sb }
disk {
# on-io-error fencing use-bmbv no-disk-barrier no-disk-flushes
Thirdware Linux-HA による nginx Web サーバのクラスタ構築 HOWTO # no-disk-drain no-md-flushes max-bio-bvecs
} net {
# sndbuf-size rcvbuf-size timeout connect-int ping-int ping-timeout max-buffers
# max-epoch-size ko-count allow-two-primaries cram-hmac-alg shared-secret
# after-sb-0pri after-sb-1pri after-sb-2pri data-integrity-alg no-tcp-cork
}
syncer {
# rate after al-extents use-rle cpu-mask verify-alg csums-alg } } /etc/drbd.d/r0.res resource r0 { protocol C; syncer { rate 60M; } disk { on-io-error detach; } device /dev/drbd0; disk /dev/vda3; on nginx1.example.com { address 10.10.0.1:7788; meta-disk internal; } on nginx2.example.com { address 10.10.0.2:7788; meta-disk internal; } } ステップ3: メタデータ領域を作成する 両方のクラスタノードで次のコマンドを実行する。 drbdadm create-md r0 ステップ4: 初期同期を実行する 両方のクラスタノードで DRBD を起動する /etc/init.d/drbd start どちらか一方のノードを初期プライマリ状態に昇格して、レプリケーション領域全体をフル同期する。
drbdadm -- --overwrite-data-of-peer primary r0
ステップ5: DRBD レプリケート領域にファイルシステムを作成する
CentOS 6.2 では ext4 ファイルシステムがデフォルトのファイルシステムなので、DRBD レプリケー ト領域に ext4 ファイルシステムを作成する。
Thirdware Linux-HA による nginx Web サーバのクラスタ構築 HOWTO mkfs.ext4 /dev/drbd0 以上のステップを実行することによって、DRBD レプリケーション領域が初期化され、HA クラスタのため の共有ディスクとして使用できるようになる。
4 nginx クラスタ化のためのデータ領域の準備
コミュニテイサイトからダウンロードした nginx パッケージは、設定ファイルが/etc/nginx、コンテンツ領域が /usr/share/nginx ディレクトリになっている。HA クラスタシステムでは、アクティブなノードがこれらの領域 にアクセスできるよう、準備を行う必要がある。 共有データ領域にアクセスするには、(1)共有データ領域を/usr/share/nginx ディレクトリにマウントする、 (2)別のマウントポイントにマウントした共有データ領域に対するシンボリックリンクを張る、という 2 とおり の方法が考えられる。ここではシンボリックリンクを使うこととする。 ステップ1: DRBD レプリケート領域のためのマウントポイントを作成する 両ノードで適当なマウントポイントディレクトリを作成する(ここでは/h という名前を使う)。 mkdir /h ステップ2: プライマリノードで共有データ領域をマウントする どちらか一方のノードの DRBD をプライマリに昇格させ、//h にマウントする。 drbdadm primary r0 mount /dev/drbd0 /h ステップ3: プライマリノードでコンテンツ領域を共有データ領域にコピーする mkdir -p /h/usr/share cp -a /usr/share/nginx /h/usr/share ステップ4: 両ノードで共有データ領域に対するシンボリックリンクを作成する mv /usr/share/nginx /usr/share/nginx.orig ln -sf /h/usr/share/nginx /usr/share/ 現在セカンダリになっているノードでは、「壊れたシンボリックリンク」が作成されるが、クラスタとし てアクティブな状態になった場合には、正常に共有データ領域にアクセスできる。 設定ファイル(/etc/nginx)についても、同様のシンボリックリンクを張っておくことができる。このようにして おけば、アクティブノードで 1 回だけ設定を変更すれば、フェールオーバしてもその設定が引き継がれる ようになる。5 nginx クラスタの構築
nginx のクラスタシステムの構成は、ターゲットプログラムが違うことを除いて、他のサーバアプリケーショ ンのクラスタシステムと同じである。すなわち、クラスタとして以下のリソースを制御する必要がある。 • クライアントにサービスを提供するための仮想 IP アドレス • コンテンツ領域(およびオプションとして設定ファイル)にアクセスするためのディスクデータの管 理 株式会社サードウェア 5Thirdware Linux-HA による nginx Web サーバのクラスタ構築 HOWTO ◦ DRBD 自体のロール(プライマリまたはセカンダリ)の制御 ◦ アクティブノードでプライマリ DRBD を/h にマウントする • nginx プログラム自体 したがって、クラスタの構築手順は以下のようになる。 ステップ1: Heartbeat 設定ファイルの作成 どちらかのノードで/etc/ha.d/ha.cf および/etc/ha.d/authkeys を作成して、他方にリモートコピーする。 /etc/ha.d/ha.cf crm yes bcast eth1 bcast eth2 node nginx1.example.com node nginx2.example.com /etc/ha.d/authkeys auth 2 2 sha1 rjvf67w1TjJNfY60eZ0QwIE ステップ2: Heartbeat を起動する DRBD が起動していれば停止した上で、両ノードで Heartbeat を起動する /etc/init.d/heartbeat start 以下の設定作業は、2 つの端末ウィンドウを開き、一方で crm_mon コマンドを実行しておき、他方で crm コマンドによる設定作業を進めるのが効率的だ。 ステップ3: クラスタの動作オプション(property)を設定する crm コマンドで対話モードの crm シェルを起動し、configure モードで以下の設定を行う。 property default-resource-stickiness="200" \ no-quorum-policy="ignore" \ stonith-enabled="false" 設定を入力したら、commit コマンドで動作中のクラスタに反映させる。 ステップ4: DRBD の動作条件を設定する
primitive res_drbd_r0 ocf:linbit:drbd \ params drbd_resource="r0" \
op start interval="0" timeout="240" \ op stop interval="0" timeout="100" ms ms_drbd_r0 res_drbd_r0 \
meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true"
ステップ5: その他のリソースを登録する
primitive res_ip ocf:heartbeat:IPaddr2 \
params ip="10.30.101.10" cidr_netmask="16" \ op monitor interval="50" timeout="30" primitive res_mount ocf:heartbeat:Filesystem \
params device="/dev/drbd0" fstype="ext4" directory="/h" options="noatime" \ op monitor interval="10" timeout="60" \
op start interval="0" timeout="60" \ op stop interval="0" timeout="60" primitive res_nginx ocf:heartbeat:nginx \
params configfile="/etc/nginx/nginx.conf"
Thirdware Linux-HA による nginx Web サーバのクラスタ構築 HOWTO status10url="http://localhost/index.html" \
op start interval="0" timeout="60" \ op stop interval="0" timeout="120" \ op monitor interval="10" timeout="30" colocation c_nginx inf: nginx ms_drbd_r0:Master order o_nginx inf: ms_drbd_r0:promote nginx:start
ステップ6: commit してクラスタに反映する
これらの設定を commit すると、nginx サーバのクラスタシステムが動作を開始する。 正常に動作しているクラスタでは、crm_mon コマンドの出力は以下のような感じになる。
============
Last updated: Wed Feb 29 14:26:58 2012 Stack: Heartbeat
Current DC: nginx2.example.com (371a0f12-6959-405c-9af0-2763013510b1) - partition with quorum
Version: 1.0.11-6e010d6b0d49a6b929d17c0114e9d2d934dc8e04 2 Nodes configured, unknown expected votes
2 Resources configured. ============
Online: [ nginx2.example.com nginx1.example.com ] Master/Slave Set: ms_drbd_r0
Masters: [ nginx1.example.com ] Slaves: [ nginx2.example.com ] Resource Group: nginx
res_mount (ocf::heartbeat:Filesystem): Started nginx1.example.com res_ip (ocf::heartbeat:IPaddr2): Started nginx1.example.com
res_nginx (ocf::heartbeat:nginx): Started nginx1.example.com
6 nginx リソースエージェント
nginx リソースエージェントは、nginx サーバプログラムの起動、停止、モニタを受け持つシェルスクリプト で、以下のような動作パラメータを受け付ける。 モ ニ タ に つ い て は 、 OCF_CHECK_LEVEL 変 数 を サ ポ ー ト し て い る 。 OCF_CHECK_LEVEL は op monitor 行に追加パラメータとして指定する(デフォルト値は「無定義])。 デフォルト(OCF_CHECK_LEVEL は無定義) nginx プロセスの存在のみをチェックする。 OCF_CHECK_LEVEL<20 デフォルトのチェックを行う。これに加えて、 status10url で指定された URL にアクセスして 、 status10regex に指定された正規表現にマッチする応答が返ってくることをチェックする。 OCF_CHECK_LEVEL<30 デフォルトのチェックを行う。これに加えて、testconffile に登録されたモニタ条件、あるいは testurl に指定された URL にアクセスして、test20regex に指定された正規表現マッチする応答が返ってく ることをチェックする。 株式会社サードウェア 7Thirdware Linux-HA による nginx Web サーバのクラスタ構築 HOWTO OCF_CHECK_LEVEL<40 external_monitor30_cmd に指定されたコマンドを実行する。 パラメータ 必須/任意 説明 configfile 任意 nginx の設定ファイルをフルパスで指定する。コミュニティからダウンロードした パッケージの場合は/etc/nginx/nginx.conf になる。 httpd 任意 サーバの実行プログラムのフルパス名。デフォルトで自動検出されるようなの で、指定しなくても問題ない
port 任意 status*url を指定して nginx をモニタするときにアクセスするポート番号。デフォ ルトは 80 なので、多くの場合指定しなくても問題ない。 status10url 任意 上の説明を参照。 status10regex 任意 上の説明を参照。 testclient 任意 上の説明を参照。 testurl 任意 上の説明を参照。 test20regex 任意 上の説明を参照。 testconffile 任意 上の説明を参照。 test20name 任意 今のところスクリプト中で使用されていない。 external_monitor30_cmd 任意 上の説明を参照。 options 任意 nginx コマンドの動作オプションを指定する。 たとえば基本的なモニタに加えて/nginx_status の応答を調べたい場合、次のようにリソースを定義する。
primitive res_nginx ocf:heartbeat:nginx \
params configfile="/etc/nginx/nginx.conf" status10url="/nginx_status" \ op start interval="0" timeout="60" \
op stop interval="0" timeout="120" \
op monitor interval="20" timeout="30" OCF_CHECK_LEVEL="10" \ op monitor interval="10" timeout="30" OCF_CHECK_LEVEL="0"