序章


Serfは、分散型のサービスオーケストレーションおよびサービス検出ツールです。 非常にフォールトトレラントで分散化されており、他の同様のツールのような単一障害点はありません。 Serfを使用して、システムのクラスター全体で任意のイベントをトリガーしたり、監視業務を実行したりできます。 これは、分散型通信用に設計されたゴシッププロトコルの上に構築されています。 ノードがSerfクラスターに参加するには、ノードはクラスター内の他の1つのノードのアドレスを最初に知っているだけで済みます。 ノードが参加すると、すべてのメンバーシップ情報がクラスター全体に伝達されます。 Gossipプロトコルにより、Serfのセットアップと構成が非常に簡単になります。

複数のVPSを使用する


Serfは、複数のVPSおよびマシンで実行するように設計されており、nix、windows、およびMacOSシステムと互換性があります。 このチュートリアルでは、2つの異なるUbuntuサーバーでSerfをセットアップする方法を説明します。

このチュートリアルでは、サーバーの名前はSerfNode1およびSerfNode2になります。 各サーバーのIPアドレスを知っている必要があります。 このチュートリアルでは、次のIPアドレスを使用して各VPSを表します。 [チュートリアルでこれらのIPアドレスが表示されている場合は、それらを独自のIPアドレスに置き換えます]。

SerfNode1 | 1.1.1.1

SerfNode2 | 2.2.2.2


Serfのインストール


これは、SerfNode1SerfNode2の両方で実行する必要があります。

最新のSerfパッケージをダウンロードします。

wget https://dl.bintray.com/mitchellh/serf/0.3.0_linux_amd64.zip

パッケージを解凍するには、解凍ツールをインストールします。

apt-get install unzip

Serfパッケージを解凍します。

unzip 0.3.0_linux_amd64.zip

Serfをbinariesディレクトリに追加して、どこからでも実行できるようにします。

mv serf /usr/local/bin

Serfクラスターの作成


SerfNode1で最初のSerfノードを開始します。

serf agent -node=**SerfNode1** -bind=1.1.1.1:7496 

以下の出力のようなものが表示されます。

==> Starting Serf agent...
==> Starting Serf agent RPC...
==> Serf agent running!
    Node name: '**SerfNode1**'
    Bind addr: '1.1.1.1:7496'
     RPC addr: '127.0.0.1:7373'
    Encrypted: false
     Snapshot: false
      Profile: lan

==> Log data will now stream in as it occurs:

    2014/01/18 21:57:57 [INFO] Serf agent starting
    2014/01/18 21:57:57 [WARN] Binding to public address without encryption!
    2014/01/18 21:57:57 [INFO] serf: EventMemberJoin: **SerfNode1** 1.1.1.1
    2014/01/18 21:57:58 [INFO] agent: Received event: member-join
    

注:nodeパラメーターはノードの名前を指定し、bindはバインドするIPアドレスとポートを表します。

SerfNode2 で、Serfエージェントをバックグラウンドで起動します。

serf agent -node=**SerfNode2** -bind=2.2.2.2:7497 -rpc-addr=127.0.0.1:7373 &

注:「&」は、コマンドをバックグラウンドで実行するように指示します

SerfNode2SerfNode1に参加するように指示します。

serf join 1.1.1.1:7496

次のような出力が表示されます。

...
    2014/01/18 22:03:04 [INFO] serf: EventMemberJoin: **SerfNode2** 2.2.2.2
    2014/01/18 22:03:05 [INFO] agent: Received event: member-join1922
...

素晴らしい! これで、小さな作業用Serfクラスターができました。 追加のサーバーをセットアップするには、SerfNode2で行ったプロセスを繰り返すだけです。 Serfクラスターに参加するには、クラスター内にすでに存在する他の1つのSerfエージェントに参加するようにVPSに指示する必要があります。 Gossipプロトコルは、クラスター内の他のすべてのSerfエージェントに新しいVPSを自動的に通知します。

イベントとイベント処理


Serfがとても素晴らしいもう1つの理由は、イベント処理がいかに簡単かということです。 まず、クラスターにイベントを送信しましょう。

簡単なユーザーイベントの送信


SerfNode2 で、次のコマンドを実行します。

serf event hello

SerfNode1 では、次のようなものが表示されます。

2014/01/16 15:48:05 [INFO] agent: Received event: user-event: hello

うわー! 最初のイベントをクラスターに送信しました。 わかりました、それはクールですべてですが、このイベントは実際にはあまり効果がありません。

カスタムイベントハンドラーの作成


次に、カスタムイベント処理を構成します。 Serfは、デプロイメント、セキュリティ更新、システム構成などを開始するために、クラスター全体でカスタムイベントをトリガーできます。 スクリプト化できるLinuxマシン上のイベントはすべて、Serfがトリガーできます。

簡単な例から始めましょう。

SerfNode1 で、Ctrl+Cを押してSerfエージェントを停止します。 以下の出力が得られるはずです。

    2014/01/16 15:58:54 [INFO] agent: requesting serf shutdown
    2014/01/16 15:58:54 [WARN] Shutdown without a Leave
    2014/01/16 15:58:54 [INFO] agent: shutdown complete

次に、「writtentofile」を/usr/srcディレクトリ内のテキストファイルに書き込むカスタムイベントスクリプトを作成します。 ユーザーが「書き込み」イベントを送信すると、このスクリプトが実行されます。

まず、イベントハンドラーを作成しましょう。 イベントハンドラーは任意の実行可能ファイルにすることができます。この場合、bashファイルを使用します。

/ usr/srcディレクトリに切り替えます。

cd /usr/src

nanoを開く:

nano handler.sh

イベントハンドラーには次のスクリプトを使用します。

 #!/bin/bash
if [ "${SERF_USER_EVENT}" = "write" ]; then
        echo "written to file" >> test.txt
fi

echo "${SERF_USER_EVENT}"

注:$ {SERF_USER_EVENT}は、送信するevntの名前です。 ifステートメントを使用してさまざまなイベントを設定する方法に注目してください。

Ctrl+Xを押してnanoを終了します

Yを押して保存します

Enterキーを押します

スクリプトを実行可能にします。

chmod +x handler.sh

ここでSerfエージェントを再起動しますが、今回は作成したばかりのイベントハンドラーを使用します。

serf agent -log-level=debug -event-handler=./handler.sh -node=**SerfNode1** -bind=1.1.1.1:7496

(オプションのステップ)

各Serfエージェントは、独自のイベントハンドラーを持つことができます。 SerfNode2 のカスタムイベントハンドラーが必要な場合は、 SerfNode1 の場合と同じイベントハンドラー作成プロセスを実行するか、イベントハンドラースクリプトをにコピーするだけです。 SerfNode2サーバーの/usr/ srcディレクトリで、次のコマンドを実行します。

SerfNode2 で、Serfクラスターを離れます。

serf leave

/ usr/srcディレクトリに移動します。

cd /usr/src

カスタムイベントハンドラーを使用して、バックグラウンドでSerfエージェントを起動します。

serf agent -log-level=debug -event-handler=./handler.sh -node=**SerfNode2** -bind=2.2.2.2:7496 &

イベントハンドラーのテスト


SerfNode2 で、SerfNode1に再参加します。

serf join 1.1.1.1:7496

次のコマンドを実行します。

serf event write 

SerfNode1 で、/ usr/srcディレクトリに切り替えます。

cd /usr/src

これで、directoyにtest.txtファイルが表示されます。 このファイルは、SerfNode2からSerfイベントをトリガーしたときに作成されました。 かなり気の利いたえ? それでは、もう少し高度なことをしましょう。

空きメモリ監視の設定


サーバーのクラスター上の空きメモリを中央サーバーに記録するカスタムイベントハンドラーをセットアップします。

SerfNode1 で、Ctrl+Cを押してSerfクラスターを終了します。

/ usr/srcディレクトリにいることを確認してください。

cd /usr/src

handler.shスクリプトを開きます。

nano handler.sh

スクリプトを次のように変更します。

 #!/bin/bash
if [ "${SERF_USER_EVENT}" = "mem" ]; then
   serf event memresponse "$(awk '/MemTotal/ {printf( "%.2f\n", $2 / 1024 ) }'              /proc/meminfo) MB from $(wget -qO- http://ipecho.net/plain ; echo) at $(date)"
fi

Ctrl+Xを押してnanoを終了します

Yを押して保存します

Enterキーを押します

このスクリプトは、次の形式で仮想サーバーの空きメモリを返すSerfイベントをトリガーします。

490 MB from 1.1.1.1 at Sun Jan 19 00:37:22 EST 2014

これをVPSに記録する方法が必要です

SerfNode2 で、Serfクラスターを離れます。

serf leave

/ usr/srcディレクトリにいることを確認してください。

cd /usr/src

ハンドラスクリプトを作成します。

nano handler.sh

スクリプトには以下を使用します。

 #!/bin/bash
if [ "${SERF_USER_EVENT}" = "memresponse" ]; then
    cat >> mem.txt
    echo "\n" >> mem.txt
fi

Ctrl+Xを押してnanoを終了します

Yを押して保存します

Enterキーを押します

スクリプトを実行可能にします。

chmod +x handler.sh

SerfNode1でエージェントを起動します。

serf agent -log-level=debug -event-handler=./handler.sh -node=**SerfNode1** -bind=1.1.1.1:7496

SerfNode2でエージェントを起動します。

serf agent -log-level=debug -event-handler=./handler.sh -node=**SerfNode2** -bind=2.2.2.2:7496 &

SerfNode2 で、 SerfNode12に再参加します。

serf join 1.1.1.1:7496

‘mem’イベントをトリガーします。

serf event mem

mem.txtファイルを確認してください。

nano mem.txt

これで、複数の仮想サーバーに分散できる機能するメモリ監視ツールができました。

農奴イベントの詳細


以下は、カスタムイベント処理スクリプトを作成するときに役立つ変数の一部です。 これらはhttp://serfdom.ioから直接取得されます ”>農奴のウェブサイト。

  • SERF_EVENT 発生しているイベントタイプです。 これは、member-join、member-leave、member-failed、またはuserのいずれかになります。

  • SERF_SELF_NAME イベントハンドラーを実行しているノードの名前です。

  • SERF_SELF_ROLE イベントハンドラーを実行しているノードの役割です。

  • SERF_USER_EVENT は、ユーザーイベントタイプの名前です。 SERF_EVENT 「ユーザー」です。

  • SERF_USER_LTIME は、ユーザーイベントのLamportTimeです。 SERF_EVENT 「ユーザー」です。

イベントがトリガーされたときのイベントコマンドのレイアウトは次のとおりです。

serf event [SERF_EVENT_NAME] [PAYLOAD]
  • ペイロードは、イベント名に続くものです。 ペイロードは、スクリプトによってstdinとして解釈されます。

  • カスタムユーザーイベントを使用する場合は、SERF_EVENT変数の代わりにSERF_USER_EVENT変数を使用する必要があります。

結論


Serfは、マシンのクラスター全体でイベントをトリガーするための優れた方法です。 シンプル、軽量、フォールトトレラントです。 これらの優れた機能に加えて、それは非常に分散化されており、単一障害点がありません。 使用例としては、システム構成、展開、セキュリティ更新、メッセージブロードキャスト、サーバー監視などがあります。 Serfも非常にカスタマイズ可能であり、さまざまな問題の解決策となるように適合させることができます。

Serfの詳細とドキュメントは、 http://www.serfdom.ioにあります。 ”>ここ