Serf を systemd を使い、サーバのブート時に自動起動する設定方法をまとめました。systemd は SysV init スクリプトにかわり、デーモンの起動・停止やリソース設定を行う事が出来ます。systemd については、@enakai00 さんのスライドが参考になります m(__)m
Linux女子部 systemd徹底入門
http://www.slideshare.net/enakai/linux-27872553
■動機と目的
Raspberry Pi 上で監視を行うためです。Raspberry Pi 上は pidora で運用中(Fedora 18 の ARM 特化ディストリビューション。pidora インストール手順はこちら)。電源を入れると DHCP で接続する設定のため、都度 IP アドレスが変更になります。
そのため、IP アドレスを知る為には、通知するスクリプトを入れ込むか、ディスプレイに接続する、あるいは LED で表示したり、音声通知という方法がありますが正直面倒。楽に把握する方法はあるはず。お金もかけたくない。それに、将来的には監視も楽にしたいので、検証として、まず Serf の自動起動を試みようとしました。
※ 2013/11/12 追記: Serf を使った IP アドレス通知は、別記事をご覧下さい。
【試してみた】RaspberryPi起動・停止時にSerfで画面に通知する方法
http://pocketstudio.jp/log3/2013/11/12/raspberrypi-notify-with-serf/
ところが、Fedora 18 は systemd が標準で稼働しており、init 系のスクリプトでは動きません。そこで、良い機会なので systemd を用いた設定を行います。
なお、この検証は Fedora 19 上で行いました。
■設定方針
単純に systemd に登録しても、IP アドレスを認識する前(ネットワークを認識前)に serf agent が起動しても、以下の様に自分しか見えていません。非常に残念な感じです。
$ serf members web1 127.0.0.1 alive
ネットワーク疎通後に serf agent を起動するため、NetworkManager Wait Online を有効にする方法を行います。別解として NetworkManager Dispacher を使う方法もありますが、これは後述します。
■Network Manager Wait Online での設定手順
まずは systemd の Unit 定義ファイルを設置します。
# vi /etc/systemd/system/serf.service
ファイルの中身は、以下の様にします。
[Unit] Description=Serf agent Requires=NetworkManager-wait-online.service After=NetworkManager-wait-online.service [Service] Type=simple Restart=always ExecStart=/usr/local/bin/serf agent User=nobody Group=nobody [Install] WantedBy=multi-user.target
[Unit]の中で “Requires=” と “After=” の行がありますが、この依存関係の設定がポイントです。ネットワークに疎通した処理を行った後、serf agent の起動を試みます。
[Serfice]の ExecStart のパスは、/usr/local/bin/serf 以外の場合、適当に書き換えて下さい。その他 -join 等のコマンドや、設定ファイルの指定 ( -config-file= ) が必要であれば、追記します。オプション等の詳細は、こちらをご覧くだしあ。
次に、serf.service を systemd で自動起動する設定にします。
# systemctl enable serf.service ln -s '/etc/systemd/system/serf.service' '/etc/systemd/system/multi-user.target.wants/serf.service'
ファイルの変更を行ったので、systemd を読み込み直します。
# systemctl --system daemon-reload
status で Loaded: が enabled になっている事を確認します。
# systemctl status serf.service
serf.service - Serf agent
Loaded: loaded (/etc/systemd/system/serf.service; enabled)
ここまで来たら、起動・停止を systemctl を使って操作できます。
起動は start です。
# systemctl start serf.service
正常に動作しているかは serf members 等のコマンドを実行する方法と、systemctl で確認する方法があります。
# systemctl status serf.service
serf.service - Serf agent
Loaded: loaded (/etc/systemd/system/serf.service; enabled)
Active: active (running) since 水 2013-11-06 22:18:57 JST; 4s ago
Main PID: 1223 (serf)
CGroup: name=systemd:/system/serf.service
mq1223 /usr/local/bin/serf agent
11月 06 22:18:57 web1 serf[1223]: ==> Serf agent running!
11月 06 22:18:57 web1 serf[1223]: Node name: 'web1'
11月 06 22:18:57 web1 serf[1223]: Bind addr: '0.0.0.0:7946'
11月 06 22:18:57 web1 serf[1223]: RPC addr: '127.0.0.1:7373'
11月 06 22:18:57 web1 serf[1223]: Encrypted: false
11月 06 22:18:57 web1 serf[1223]: ==> Log data will now stream in as it occurs:
11月 06 22:18:57 web1 serf[1223]: 2013/11/06 22:18:57 [INFO] Serf agent starting
11月 06 22:18:57 web1 serf[1223]: 2013/11/06 22:18:57 [INFO] serf: EventMemberJoin:....16
11月 06 22:18:57 web1 serf[1223]: 2013/11/06 22:18:57 [INFO] Serf agent started
11月 06 22:18:58 web1 serf[1223]: 2013/11/06 22:18:58 [INFO] agent: Received event:...oin
“Active: active (running)”であれば、正常に動作しています。もしエラーが出て起動しない場合は、画面に出ているメッセージやログ ( /var/log/messages ) を辿って状況を調査します。
停止は stop です。
# systemctl stop serf.service
最後に、サーバの reboot を行い、再起動後に serf agent が起動するか確認します。正常であれば、ブート直後に serf が起動します。-join オプションがあれば、自動的にクラスタに加わるでしょう。また、ログ /var/log/messages からも、
Nov 6 22:12:09 web1 systemd[1]: Started Network Manager Wait Online. Nov 6 22:12:09 web1 systemd[1]: Starting Network. Nov 6 22:12:09 web1 systemd[1]: Reached target Network. (snip) Nov 6 22:12:09 web1 systemd[1]: Starting The Apache HTTP Server... Nov 6 22:12:09 web1 systemd[1]: Starting OpenSSH server daemon... Nov 6 22:12:09 web1 systemd[1]: Starting RPC bind service... Nov 6 22:12:09 web1 systemd[1]: Started Login and scanning of iSCSI devices. Nov 6 22:12:09 web1 systemd[1]: Starting Serf agent...
ネットワーク疎通後に serf agent が起動したことが分かります。
serf members コマンドでも、ネットワーク情報が認識されている事がわかります。
$ serf members web1 192.168.11.16 alive
以上で設定完了です。
このように、systemd の自分用の雛形を作っておけば、対象サーバが増えても、比較的簡単に serf を扱えるようになるのではないでしょうか。また、serf のイベントによって発生する監視設定なども、捗ると思います。
■別解:/etc/rc.local 相当の処理を NetworkManager Dispatcher で行う
systemd では rc.local にあたるファイルがありません。しかし Dispatcher を使えば、ディレクトリ /etc/NetworkManager/dispatcher.d/ に設置したファイルをスクリプトとして逐次実行させることができます。
この方法は、単純に serf agent をスクリプトとして起動します。start / stop といった、serf の操作をしない環境であれば、こちらでも良いかもしれません。
まず、NetworkManager-dispatcher を有効にします。事前に status で確認し、有効になっていればこの手順は不要。
# systemctl enable NetworkManager-dispatcher ln -s '/usr/lib/systemd/system/NetworkManager-dispatcher.service' '/etc/systemd/system/dbus-org.freedesktop.nm-dispatcher.service' ln -s '/usr/lib/systemd/system/NetworkManager-dispatcher.service' '/etc/systemd/system/multi-user.target.wants/NetworkManager-dispatcher.service'
次に、ディレクトリを移動します。
# cd /etc/NetworkManager/dispatcher.d/
ここに設置されているファイルは全て実行されます。init スクリプト風に、数字の若い順番のファイル(スクリプト)から実行されます。
# ls -al 合計 20 drwxr-xr-x. 1 root root 102 6月 28 02:13 . drwxr-xr-x. 1 root root 122 6月 28 02:13 .. -rwxr-xr-x. 1 root root 175 5月 31 16:49 00-netreport -rwxr-xr-x. 1 root root 108 5月 29 06:18 04-iscsi -rwxr-xr-x. 1 root root 111 4月 22 2013 10-sendmail -rwxr-xr-x. 1 root root 933 5月 15 06:41 11-dhclient -rwxr-xr-x. 1 root root 317 5月 9 19:18 20-chrony
利用していないものは、rm で削除します。
整理した後、serf 用のファイルを設置します。
# touch 50-serf # chmod 755 ./50-serf # cat <<EOF > ./50-serf #!/bin/sh systemctl start serf EOF
systemctl ~の行は「/usr/local/bin/serf agent &」でも良いかもしれません。
あとは再起動して動作を確認できます。もしこちらを無効にしたい場合は、次のように実行します。
# systemctl disable NetworkManager-dispatcher rm '/etc/systemd/system/multi-user.target.wants/NetworkManager-dispatcher.service' rm '/etc/systemd/system/dbus-org.freedesktop.nm-dispatcher.service'
これで元通りです。
■参考 URL
Linux女子部 systemd徹底入門
http://www.slideshare.net/enakai/linux-27872553
NetworkManager (日本語) – ArchWiki
https://wiki.archlinux.org/index.php/NetworkManager_(%E6%97%A5%E6%9C%AC%E8%AA%9E)