2007年04月24日

OCFS2

OCFS2(Oracle Cluster File System 2)

Oracleが作ったクラスタファイルシステム。ちまたにいくつかあるクラスタファイルシステムのうちの一つである。gfs2と共にkernelに取り込まれており、今後のメンテナンスも安心できるだろう。

ビルド

OCFS2プロジェクトのページからソースをダウンロードして、カーネルモジュールをビルド。DRBDの時と同様にパッケージを作成してインストール。ocfs2-toolsもビルドしてインストール。loadしようとしたら、machine_restartが見つからないというエラーが出てしまう。kernelに取り込まれているOCFS2の部分を見ると、machine_restartがばっさり無くなっている。その部分を通るようにpatchを当ててビルドしてインストール。今度は問題なくloadできた模様。設定をした後に、テスト中にkernel panicで落ちてしまう現象を発見。いきなりつまづいた…。

そもそもkernel-2.6.18には既にocfs2がモジュールで入っているはずだ。locateで調べても出てこない。なんでだろと思って/boot/config-2.6.18-8.1.1-el5PAEを見てみると、

# CONFIG_OCFS2_FS is not set

とさみしい結果に。kernel-2.6.18-8.1.1.src.rpmを展開してkernel-2.6.18-i686.configを確認してみるものの、

$ rpm2cpio kernel-2.6.18-8.1.1.src.rpm | cpio -idm
…省略…
$ grep OCFS2_FS kernel-2.6.18-i686.config
CONFIG_OCFS2_FS=m

となっている。有効になってるはずなのに、どこかで無効化されてるではないか。

specファイルを読み解くと、どうも%prepあたりでmerge.plでconfig-rhel-genericというファイルと混ぜているらしいというのがわかった。そして、config-rhel-genericを見ると、

# CONFIG_OCFS2_FS is not set

と書いてあるので、これが有効になってカーネルモジュールが作成されていないのである。

本来ならば、カーネルモジュールだけを作るためのパッケージを作ればよかったものの、めんどくさかったのでその行を削除してReleaseを多少変更してkernelをビルド。ビルドしようとしたら、signmodulesあたりで止まったので、signmodulesを0にしてビルド。今度はちゃんとビルドできたのでインストール。

drbdもカーネルモジュールにしてしまったので、カーネルのVersion/Releaseが変わったので、リビルドしてインストール。

設定

Oracleが出しているOCFS2 ユーザーズ・ガイドの付録Aを参考にまず、/etc/ocfs2/cluster.confを作成する。ここの例では、cluster:の次の行が行頭から始まっているが、[TAB]かスペースをいれてないとエラーが出た。実際に使用するIPアドレスやホスト名やクラスタ名を変更。

node:
ip_port = 7777
ip_address = 192.168.238.180
number = 0
name = test00.example.com
cluster = ocfs2
node:
ip_port = 7777
ip_address = 192.168.238.181
number = 1
name = test01.example.com
cluster = ocfs2
cluster:
node_count = 2
name = ocfs2

というような感じにしてみた。test01側にも同じファイルをコピー。

O2CBクラスタの起動

モジュールのロードとクラスタのオンラインを行う。

[root@test00 ~]# /etc/init.d/o2cb load
Loading module "configfs": OK
Mounting configfs filesystem at /sys/kernel/config: OK
Loading module "ocfs2_nodemanager": OK
Loading module "ocfs2_dlm": OK
Loading module "ocfs2_dlmfs": OK
Mounting ocfs2_dlmfs filesystem at /dlm: OK
[root@test00 ~]# /etc/init.d/o2cb online ocfs2
Starting O2CB cluster ocfs2: OK

同様にtest01側でも行う。

OCFS2のフォーマット

ocfs2consoleによりフォーマット。あるいはコンソールからフォーマットを行う。blockサイズを4k、クラスタサイズを32k、ボリュームラベル名をshareとする。もし、SELinuxがEnforceになっている場合は、/dev/drbd0が標準状態では考慮されていないためエラーになるので、labelを付けるか、Permissive以下にしておく。

[root@test00 ~]# mkfs.ocfs2 -b 4k -C 32k -N 4 -L data /dev/drbd0
mkfs.ocfs2 1.2.4
Overwriting existing ocfs2 partition.
Proceed (y/N): y
Filesystem label=data
Block size=4096 (bits=12)
Cluster size=32768 (bits=15)
Volume size=107370840064 (3276698 clusters) (26213584 blocks)
102 cluster groups (tail covers 18842 clusters, rest cover 32256 clusters)
Journal size=268435456
Initial number of node slots: 4
Creating bitmaps: done
Initializing superblock: done
Writing system files: done
Writing superblock: done
Writing backup superblock: 4 block(s)
Formating Journals: done
Writing lost+found: done
mkfs.ocfs2 successful

test01側では、drbdでsyncされるのでtest01側での操作は不要。

ocfs2パーティションのmount

fstypeは、ocfs2でmountが可能。ここでは/srv/dataにmountしてみる。

[root@test00 ~]# mount -t ocfs2 /dev/drbd0 /srv/data
[root@test00 ~]# df -T /srv/data
Filesystem Type 1K-blocks Used Available Use% Mounted on
/dev/drbd0 ocfs2 102854336 1058208 103796128 2% /srv/data

test01側でも同様にmount

[root@test01 ~]# mount -t ocfs2 /dev/drbd0 /srv/data
[root@test01 ~]# df -T /srv/data
Filesystem Type 1K-blocks Used Available Use% Mounted on
/dev/drbd0 ocfs2 102854336 1058208 103796128 2% /srv/data

test00側でファイルをtouchして、test01側に出来てる事を確認。test01側でファイルをtouchして、test00側に出来てる事を確認。

[root@test00 ~]# touch /srv/data/a
[root@test00 ~]# ls -laF /srv/data/
total 16
drwxr-xr-x 3 root root 4096 Apr 24 17:53 ./
drwxr-xr-x 3 root root 4096 Apr 24 17:41 ../
-rw-r--r-- 1 root root 0 Apr 24 17:53 a
drwxr-xr-x 2 root root 4096 Apt 24 17:42 lost+found/
[root@test01 ~]# ls -laF /srv/data/
total 16
drwxr-xr-x 3 root root 4096 Apr 24 17:53 ./
drwxr-xr-x 3 root root 4096 Apr 24 17:41 ../
-rw-r--r-- 1 root root 0 Apr 24 17:53 a
drwxr-xr-x 2 root root 4096 Apt 24 17:42 lost+found/
[root@test01 ~]# touch /srv/data/b
[root@test01 ~]# ls -laF /srv/data/
total 16
drwxr-xr-x 3 root root 4096 Apr 24 17:54 ./
drwxr-xr-x 3 root root 4096 Apr 24 17:41 ../
-rw-r--r-- 1 root root 0 Apr 24 17:53 a
-rw-r--r-- 1 root root 0 Apr 24 17:54 b
drwxr-xr-x 2 root root 4096 Apt 24 17:42 lost+found/
[root@test00 ~]# ls -laF /srv/data/
total 16
drwxr-xr-x 3 root root 4096 Apr 24 17:54 ./
drwxr-xr-x 3 root root 4096 Apr 24 17:41 ../
-rw-r--r-- 1 root root 0 Apr 24 17:53 a
-rw-r--r-- 1 root root 0 Apr 24 17:54 b
drwxr-xr-x 2 root root 4096 Apt 24 17:42 lost+found/

というように、双方から書き込んでもsyncされている。



2007年04月20日

DRBD

DRBD(Distributed Replicated Block Device)

ざっくりとした説明としては、ネットワーク越しにミラーするとか書かれていたりする。つまり、ブロックデバイスのミラーなのでファイルシステムが破壊された場合もそのままコピーされてしまう。

ネットワーク越しにコピーするために、データの転送にはGigabitEthernetが必須と言える。最近のSATAのHDDでも70MB/s程の書き込み性能があるものも増えてきているので、そのくらいの速度を出そうと思うと少なくとも560Mbps + αは必要になる。そういう意味でもGigabit Etherの使用は必須である。

DRBDとは」の最後にある通り、通常のクラスタファイルシステムには、共有ストレージが必要であるが、通常FCだったりiSCSIを使ったりするところを、DRBDで代用する事ができる。

drbd-8.0からは、ocfs2かgfs2を使うことで、primary/primaryの構成もとれるらしい。

ビルド

CentOSを使ったので自分でカーネルモジュールをビルド。gfs-kmodパッケージを参考にしつつ、drbd-8.0.2.src.rpmというパッケージから、drbdとkmod-drbdとkmod-drbd-PAEとkmod-drbd-xenを生成。今回使用しているハードウエア用には、kmod-drbd-PAEしか必要ないが、ついでなので作成。

設定

まずdrbdで使うパーティションを用意(LVMでもOK)する。この例では、LVMにより、/dev/VolGroup00/share00を100GB用意した。man drbd.confで出てくるA SMALL DRBD.CONF FILEに書いてあるものをそのまま/etc/drbd.confにコピー。shared-secretの次の行にallow-two-primaries;を追加する。実際に使用するdiskやIPアドレスやホスト名を変更。

#
# please have a look at the example configuration file in
# /usr/share/doc/drbd/drbd.conf
#
global { usage-count yes; }
common { syncer { rate 300M; } }
resource r0 {
protocol C;
net {
cram-hmac-alg sha1;
shared-secret "FooFunFactory";
allow-two-primaries;
}
on test00.example.com {
device /dev/drbd0;
disk /dev/VolGroup00/share00;
address 192.168.238.180:7789;
meta-disk internal;
}
on test01.example.com {
device /dev/drbd0;
disk /dev/VolGroup00/share00;
address 192.168.238.181:7789;
meta-disk internal;
}
}

という感じになると思う。反対側のマシンにも同じファイルをコピーする。firewallの設定で7789/tcpはあけておく。

DRBDメタデータの作成

モジュールをロードし、drbdのメタデータの作成、および設定の適用。

[root@test00 ~]# modprobe drbd
[root@test00 ~]# drbdadm create-md r0
v08 Magic number not found
v07 Magic number not found
About to create a new drbd meta data block
on /dev/VolGroup00/share00.


==> This might destroy existing data! <==

Do you want to proceed?
[need to type 'yes' to confirm] yes

Creating meta data...
initialising activity log
NOT initialized bitmap (3200KB)
New drbd meta data block sucessfully created.
success
[root@test00 ~]# drbdadm adjust r0
[root@test00 ~]# cat /proc/drbd
version: 8.0.2 (api:86/proto:86)
SVN Revision: 2844 build by admin@test00.example.com, 2007-04-17 17:56:42
0: cs:WFConnection st:Secondary/Unknown ds:Inconsistant/DUnknown C r---
ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0
resync: used:0/31 hits:0 misses:0 starving:0 dirty:0 changed:0
act_log: used:0/127 hits:0 misses:0 starving:0 dirty:0 changed:0

と表示される。

反対側のマシンでも同様に設定をする。

[root@test01 ~]# modprobe drbd
[root@test01 ~]# drbdadm create-md r0
v08 Magic number not found
v07 Magic number not found
About to create a new drbd meta data block
on /dev/VolGroup00/share00.


==> This might destroy existing data! <==

Do you want to proceed?
[need to type 'yes' to confirm] yes

Creating meta data...
initialising activity log
NOT initialized bitmap (3200KB)
New drbd meta data block sucessfully created.
success
[root@test01 ~]# drbdadm adjust r0
[root@test01 ~]# cat /proc/drbd
version: 8.0.2 (api:86/proto:86)
SVN Revision: 2844 build by admin@test00.example.com, 2007-04-17 17:56:42
0: cs:Connected st:Secondary/Secondary ds:Inconsistant/Inconsistant C r---
ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0
resync: used:0/31 hits:0 misses:0 starving:0 dirty:0 changed:0
act_log: used:0/127 hits:0 misses:0 starving:0 dirty:0 changed:0

このように、Secondary/Secondaryになっている事を確認。

DRBDの同期

test00側の/dev/drbd0をまずPrimaryに設定する。一つめは-oが必要。

[root@test00 ~]# drbdsetup /dev/drbd0 primary -o
[root@test00 ~]# cat /proc/drbd
version: 8.0.2 (api:86/proto:86)
SVN Revision: 2844 build by admin@test00.example.com, 2007-04-17 17:56:42
0: cs:SyncSource st:Primary/Secondary ds:UpToDate/Inconsistent C r---
ns:360000 nr:0 dw:0 dr:366336 al:0 bm:21 lo:23 pe:42 ua:220 ap:0
[>...................] sync'ed: 0.4% (102046/102396)M
finish: 0:19:24 speed: 89,672 (89,672) K/sec
resync: used:2/31 hits:22656 misses:23 starving:0 dirty:0 changed:23
act_log: used:0/127 hits:0 misses:0 starving:0 dirty:0 changed:0

Primaryにした瞬間に同期が開始される。この時に、test01側で状態を見てみると、

[root@test01 ~]# cat /proc/drbd
version: 8.0.2 (api:86/proto:86)
SVN Revision: 2844 build by admin@test00.example.com, 2007-04-17 17:56:42
0: cs:SyncTarget st:Secondary/Primary ds:Inconsistent/UpToDate C r---
    ns:0 ns:4118304 dw:4118208 dr:0 al:0 bm:250 lo:5 pe:6709 ua:3 ap:0
        [>...................] sync'ed:  4.0% (98375/102396)M
        finish: 0:21:13 speed: 79,052 (89,796) K/sec
        resync: used:15/31 hits:263835 misses:265 starving:0 dirty:0 changed:265
        act_log: used:0/127 hits:0 misses:0 starving:0 dirty:0 changed:0

という様に、受け側のステータスは対応している。ミラーリングが完了するまで待つ。

[root@test00 ~]# cat /proc/drbd
version: 8.0.2 (api:86/proto:86)
SVN Revision: 2844 build by admin@test00.example.com, 2007-04-17 17:56:42
0: cs:Connected st:Primary/Secondary ds:UpToDate/UpToDate C r---
ns:104854364 nr:0 dw:0 dr:104854364 al:0 bm:6400 lo:0 pe:0 ua:0 ap:0
resync: used:0/31 hits:6546998 misses:6400 starving:0 dirty:0 changed:6400
act_log: used:0/127 hits:0 misses:0 starving:0 dirty:0 changed:0

同期が完了すると、このようになる。

DRBDのPrimary/Primary構成

DRBDでは、Primary側しかmountが出来ない。そのためkeepalivedやheartbeatなどで切り換える際のスクリプト中にdrbdsetupによりPrimaryに変更する必要があるが、両方ともPrimaryにしておけば切り替えるだけで使えそう。

同期が完了したらtest01側でも/dev/drbd0をPrimaryに設定する。

[root@test01 ~]# drbdsetup /dev/drbd0 primary
[root@test01 ~]# cat /proc/drbd
version: 8.0.2 (api:86/proto:86)
SVN Revision: 2844 build by admin@test00.example.com, 2007-04-17 17:56:42
0: cs:Connected st:Primary/Primary ds:UpToDate/UpToDate C r---
ns:0 nr:104854364 dw:104854364 ds:0 al:0 bm:6400 lo:0 pe:0 ua:0 ap:0
resync: used:0/31 hits:6546998 misses:6400 starving:0 dirty:0 changed:6400
act_log: used:0/127 hits:0 misses:0 starving:0 dirty:0 changed:0

これで、Primary/Primary構成になった。

DRBDのPrimary/Primary構成でext3を使ってみる

まず、test00側でmkfs.ext3 /dev/drbd0し、test00とtest01共に/mntにmountする。その上でtest00側にファイルやディレクトリを書き込んでも、test01側には表示されない。今度はtest01側のmountを一旦外して、再度mountすると、先程作成したファイルやディレクトリが出現した。

この様な動作をするため、実際のシステムに適用するにはクラスタファイルシステム(ocfs2 or gfs2)が必須であると言えよう。



2007年04月18日

新システム仕様検討

以下のような感じで設計してみようと思う。

設計思想

  • 子サーバはnetbootにより起動
    • 128台以上あるので設定変更も自動的にしたい
    • IPMIのserial over lanによりシリアルコンソールの代用とする
  • netboot用のサーバを2台用意し、LVSにより自動切り替え
    • IPMIのためのdhcpdおよびserial over lanの踏み台サーバとする
  • 親サーバ用のサーバを2台用意し、LVSにより自動切り替え

子サーバ部

  • マシン : NEC Express5800/110Rb-1h
    • Memory 1GB x2
    • HDD : Seagate ST3160815AS(160GB,8MB) x2
  • OSはCentOS5
    • OSのアップデートは適宜
  • eth0はグローバル、eth1は管理用ネットワーク
  • OSイメージはeth1よりネットワーク上(NFS)から起動
  • logは、localのディスクをmdを使いRAID1の領域に書き込む
    • 起動した時にディスクが初期化がされてなかったら行う
    • log溜めホストにlogを飛ばす
  • 各ホストでの設定変更を補助するためにpuppetを使用

Netbootサーバ部

  • マシン : HP ProLiant DL380 G5
    • Xeon 5148 LV 2.33GHz 1x4MB L2 Dual Coreプロセッサ x2
    • Memory 1GB x6
    • HDD : 146GBホットプラグ対応 10krpm 2.5" SASハードディスク ドライブ x8
      • 7本でRAID6構成、Spareを1本
  • OSはCentOS5
    • OSのアップデートは適宜
  • eth0は管理用ネットワーク、eth1はIPMI用DMZネットワーク
  • dhcpdはeth0/eth1共に供給
    • 2台のマシンからfailoverの設定を行う
    • dhcpd.leasesファイルを共有ディレクトリにいれておく
  • NFSサーバをLVSにより障害時には自動切り替え
  • NFSで提供する領域を何らかの方法でsyncする
    • DRBDを使ってsyncができ、primary/secondaryの切り替えは自動
    • DRBD-8.0からは、ocfs2かgfs2と組み合わせる事でprimary/primaryの構成が取れるらしい
    • dhcpd.leasesファイルを共有ディレクトリに格納するため、できればprimary/primaryの構成を取りたい

親サーバ部

  • マシン : HP ProLiant DL380 G5
    • Xeon 5148 LV 2.33GHz 1x4MB L2 Dual Coreプロセッサ x2
    • Memory 1GB x6
    • HDD : 146GBホットプラグ対応 10krpm 2.5" SASハードディスク ドライブ x8
      • 7本でRAID6構成、Spareを1本
  • OSはCentOS5
    • OSのアップデートは適宜
  • eth0は管理用ネットワーク
  • http / NFSサーバをLVSにより障害時には自動切り替え
  • データ領域をnetbootサーバと同様の方法でsyncする
  • puppetを動かすためのpuppet-serverを動かす

また、これらを実現するための検証を行う。



2007年04月15日

ビフォー

今度自分が関わってるサービスの機器がリースアップを迎えるにあたり、システムを刷新しようという試み。

顧客毎に子サーバを1台割り当て、設定ファイルやlogの保存、バックエンドシステムとの連携を親サーバが担当。

現行システム

  • 親サーバ側
    • P4-2.8G Mem1GB(ホットスタンバイ構成) × 2台
    • 外付けRAID装置 × 2台
  • 子サーバ側
    • Sun Fire B1600インテリジェントシェルフ(ブレードサーバを入れる箱) × 6台
    • Sun Fire B100sブレードサーバ × 128台
  • ネットワーク設備
    • Global側 swtich 1000Base-T × 2台
    • 管理ネットワーク側 switch 100Base-T × 2台
    • シリアルコンソール 16port × 3台

現行システムのいけてない点

  1. 親サーバに障害が発生すると手動で切り替えが必要であり、バックエンドシステム側にもIPアドレスの変更が必要
  2. 顧客が増えた時や、子サーバが故障した際にOSを入れたサーバをわざわざOfficeからDCへ持ち込む必要がある
  3. OSイメージの更新が非常にめんどくさく、更新忘れが発生し、ひいては将来的に障害に繋がってしまう可能性を除去できない
  4. 現状128程度であれば頑張れば手作業で設定変更を行う事も可能だが、200になったら多分無理
  5. 親サーバも子サーバも圧倒的にパフォーマンスが足りない
  6. OSが古い(親サーバ:BSD/OS4.3、子サーバ:Solaris9)
  7. 子サーバのブレードサーバが既に入手不可で顧客に提供可能な在庫が片手ほど
  8. 子サーバのログを親サーバで圧縮しているが4時間かかっても終わらないどころか、顧客が増えるごとに、顧客のログが増えるごとに、その時間は延びるばかり

現行システムのよい点

  1. インテリジェントシェルフ1台につき、ブレードサーバ16台収容可能であり、インテリジェントシェルフからブレードサーバのシリアルに接続可能なため、コンソールのポートを消費しない
  2. インテリジェントシェルフに1000Baseのswitchを内蔵しており、子サーバを収容するためのswitchの数を大幅に減らす事ができる
  3. 比較的電力使用量が少ない

 



2007年04月13日

CentOS5リリース

ようやくCentOS5のリリース

RHEL5がリリースされてから3週間要したわけだが、とりあえず中の人お疲れさまと言いたい。これからこれをベースに様々なサービスを作っていくわけで、待ちに待ったというのが正しいかもしれない。

既にパッケージの品揃えとバージョンについては、RHEL5で確認しているので、それほど混乱はないと思うが、CentOS PlusやExtrasパッケージがどのくらいのタイミングで出てくるかが気になる所。

某所FTPサーバでも昨日rsyncが終わってたので、一応フライングにならない程度に時間をずらして公開。個人的にDVDイメージは別サーバから取得。

明日はCentOS5のインストールから開始かな。



2007年04月09日

livedoor Blog事始め

はじめに

klabの人に影響されたわけでもないが、以前からやろうと思っていて、きっかけがなかったので、やってなかった。

以前は自分の鯖でtDiaryで日記を書いていたものの、鯖を入れ替えたタイミングで設定がめんどくさいのでやめてしまった。

そして、mixiが周りで流行り始めたので、昨年の末までmixiで書いてたが、技術的な事を書くには、いまいち使いにくかった。

社内のWikiに書いても、特に目立った反応があるわけでもないわけで、
というか、あまりに先進的すぎて(いや、世の中ではたいしたことでもないと思うが)、ついてこれてない風味なのかもしれない。

というわけで、このBlogでは自分が持ってる知識を書き貯めていこうかと思っている。

今後取り上げる予定のトピック

  • ディザスタリカバリシステム
    • dhcpd
    • DRBD
    • gfs2
    • keepalived
    • ipvs
  • 大量のホストを管理するための仕組み
    • IPMI
    • puppet


Archives
QRコード
QRコード
livedoor Readerに登録
RSS
livedoor Blog(ブログ)