2013/05/05

RaspberryPiでLVS+keepalivedを使ってHA構成にしてみた

RaspberryPiは手軽なLinux実行環境ですが、定格で5V/700mAが必要です。 古いPCやUSBハブに接続した場合には、うまく動かない可能性があります。

iPadやタブレットで充電に1000mA(==1A)が必要な状況なので、それほどUSBの電源周りも余裕のある設計になっているものも多くあるはずです。

とはいえ、USB2の定格は5V/500mAなので古めのPCや電源付きUSBハブにいろいろな機器を接続した場合には動作が不安定になる可能性があります。

またカーネルに3.6-trunk-rpiを選択した時には、2013年5月5日時点では、ファイルシステムに負荷をかけるようなタイミングでBUG: scheduling while atomic: swapper/...のエラーが出てまともに動きませんでした。

対応linuxカーネルの有効化

基本的な環境はarmelhfアーキテクチャのRaspbian "wheezy" をインストールした状態です。

Raspbianのカーネルは3.6.11#371版ですが、ip_vsモジュールなどは導入されていません。

このためパッケージからip_vsモジュールの含まれているイメージを導入します。

$ sudo apt-get install linux-image-3.2.0-4-rpi
起動時のカーネルイメージの変更

linux-image-*パッケージを導入しただけでは、再起動をしても引き続きRaspbianの付属カーネルが使われます。 ポイントは次のとおりです。

  • zImageを/boot/kernel.imgのファイル名でコピーする
  • initrdイメージがある場合は/boot/config.txtに記入する
/boot/kernel.imgファイルの置き換え

既存のkernel.imgファイルは退避して、vmlinuz-3.6-trunk-rpiファイルをコピーします。

$ cd /boot
$ sudo mv kernel.img kernel.3.6.11#371.img
$ sudo cp vmlinuz-3.2.0-4-rpi kernel.img

ちなみに/bootはvfatなので、ハードリンクなどを使う事はできません。 基本的にはcopyで対応することになります。

/boot/config.txtファイルの書き換え

initrdを使用している場合には、対象のファイル名をconfig.txtに書き換えます。

...
ramfsfile=initrd.img-3.2.0-4-rpi
ramfsaddr=0x00a00000
initramfs initrd.img-3.2.0-4-rpi 0x00a00000
...

ちゃんと確認していませんが、/bootにあるものとしてファイル名だけを記述しています。

再起動でカーネルの確認

とりあえず再起動して動作を確認します。

うまく行かない場合には別のPCに接続して編集内容を確認します。 /boot以下はVFAT領域なので、問題なく扱えるはずです。

ramfsaddrなどを指定しないと、initrdのイメージが展開されない事になります。 うまくいけばdmesgに次のようなメッセージが表示されます。

$ dmesg | grep init
...
[    1.049760] Unpacking initramfs...
[    1.710015] Freeing initrd memory: 4476K
...

パッケージの導入

ipvsadmとkeepalivedを使いますが、ipvsadmはkeepalivedの導入時に自動的にインストールされます。

keepalivedの導入

パッケージを導入します。

$ sudo apt-get install keepalived

設定

パッケージを導入しても設定ファイルは一切導入されないので、過去のログをみながら設定ファイルを構成します。

/etc/keepalived/keepalived.confの編集

今回はWebサーバではなくて、ESXi上に構成しているLDAPサーバに対してHA構成を取っています。

振り先の設定

LDAPサーバ側にいくつか設定が必要です。

/etc/sysctl.confの編集

対象サーバが1台しかない場合には、問題になりませんが、複数のslave LDAPサーバに処理を分散させるような場合にはサービス(仮想)IPとMACアドレスが強力に結びついてしまうと、ルータからダウンしたLDAPサーバに常に処理が振られてしまうのでARPリクエストに反応しないように変更する必要があります。

/etc/sysctl.confへの追加内容

net.ipv4.conf.eth0.arp_ignore=1
net.ipv4.conf.eth0.arp_announce=2

設定を反映させます。

$ sudo sysctl -p

sysctlコマンド実行後の画面出力

net.ipv4.conf.eth0.arp_ignore = 1
net.ipv4.conf.eth0.arp_announce = 2
サービス(仮想)IPの設定

IPレベルではリクエストは2台のRaspberryPiで共有されるサービス用の(仮想)IP宛てのパケットがLDAPサーバに到着します。

自分宛てのパケットだと認識しないといけないので、loopback(lo)にIPを設定します。 まだ未使用のlo:0デバイスを使います。他に使用している場合には、lo:1,lo:2など適当な番号に変更してください。

/etc/network/interfacesファイルへの追加内容

auto lo:0
iface lo:0 inet static
  address 192.168.1.182
  netmask 255.255.255.255

さいごに

RaspberryPiを入手して、いろいろ試していますが、電源の品質とカーネルの安定性が一番の問題でした。

電源はUSBハブから取っていますが、マウス、キーボードなどは本体に直接つないで他の機器はつないでいません。

PCなどに接続する場合には、2つ口の片側に接続する事で500mA 2つ分の1000mAまで電流が取れるものが多いようです。 最近ではiPadやタブレットに対応した急速充電可能なタイプであれば、1000mAまで取れるので問題ないでしょう。

SDカードはTranscendのClass10 UHS-I対応16GBと、PanasonicのClass 10 SDHC 8GBのカードを使っています。 他のARM系ボードでも使っていますが、これまでのところ問題は起きていません。

この他にも$ sudo raspi-configで変更できるパラメータは少し変更していて、安定して動くようになってから900MHzへのオーバークロックやVRAMを16Mに変更したり、

tail -5 /boot/config.txtの実行結果

# for more options see http://elinux.org/RPi_config.txt
gpu_mem=16
core_freq=250
sdram_freq=450
over_voltage=2

この記事で取り上げた品々