如何在多个UbuntuVPS上设置Serf集群
介绍
Serf 是一个去中心化的服务编排和服务发现工具。 它具有极强的容错性和分散性,没有像其他类似工具那样的单点故障。 Serf 可用于触发跨系统集群的任何事件以及执行监控职责。 它建立在为去中心化通信而设计的 Gossip 协议之上。 为了让一个节点加入一个 Serf 集群,该节点只需要最初知道集群中另一个节点的地址。 一旦节点加入,所有成员信息都会在整个集群中传播。 Gossip 协议使 Serf 非常容易设置和配置。
使用多个 VPS
Serf 旨在跨多个 VPS 和机器运行,并与 nix、windows 和 Mac OS 系统兼容。 本教程将向您展示如何在两个不同的 Ubuntu 服务器上设置 Serf。
在本教程中,服务器将命名为 SerfNode1 和 SerfNode2。 您需要知道每台服务器的 IP 地址; 以下 IP 地址用于表示本教程中的每个 VPS。 [无论您在教程中的何处看到这些 IP 地址,都将用您自己的 IP 地址替换它们]。
SerfNode1 | 1.1.1.1
SerfNode2 | 2.2.2.2
安装农奴
这需要在 SerfNode1 和 SerfNode2 上完成
下载最新的 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 添加到二进制目录,以便可以从任何地方执行它:
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 &
注意:“&”告诉命令在后台执行
告诉 SerfNode2 加入 SerfNode1:
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 集群,您只需要指示 VPS 加入另一个已经在集群中的 Serf 代理。 Gossip 协议自动通知集群中的所有其他 Serf 代理新的 VPS。
事件和事件处理
Serf 如此出色的另一个原因是事件处理非常简单。 让我们首先向集群发送一个事件。
发送一个简单的用户事件
在 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
现在我们将创建一个自定义事件脚本,将“写入文件”写入 /usr/src 目录中的文本文件。 当用户发送 'write' 事件时,它将执行此脚本。
首先让我们创建我们的事件处理程序。 事件处理程序可以是任何可执行文件——在我们的例子中,我们将使用 bash 文件。
切换到 /usr/src 目录:
cd /usr/src
打开纳米:
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} 是我们发送的事件的名称。 请注意如何使用 if 语句来设置不同的事件。
按 Ctrl + X 退出 nano
按 Y 保存
点击进入
使脚本可执行:
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
现在您应该在目录中看到 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 保存
点击进入
该脚本将触发一个 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 保存
点击进入
使脚本可执行:
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
现在,您拥有了一个功能强大的内存监控工具,可以分布在多个虚拟服务器上。
农奴事件详解
以下是创建自定义事件处理脚本时派上用场的一些变量。 这些直接取自[[“%3Ca|http://serfdom.io]] [[“%3C/a|”>农奴网站。]]
SERF_EVENT
是正在发生的事件类型。 这将是成员加入、成员离开、成员失败或用户之一。SERF_SELF_NAME
是正在执行事件处理程序的节点的名称。SERF_SELF_ROLE
是正在执行事件处理程序的节点的角色。- 如果
SERF_EVENT
是“用户”,则SERF_USER_EVENT
是用户事件类型的名称。 - 如果
SERF_EVENT
是“用户”,则SERF_USER_LTIME
是用户事件的 LamportTime。
触发事件时,事件命令的布局如下:
serf event [SERF_EVENT_NAME] [PAYLOAD]
- 有效负载是事件名称之后的任何内容。 有效负载被脚本解释为标准输入。
- 当使用自定义用户事件时,应使用 SERF_USER_EVENT 变量而不是 SERF_EVENT 变量。
结论
Serf 是跨机器集群触发事件的好方法。 它简单、轻量且容错。 除了这些强大的功能之外,它还非常分散,没有单点故障。 一些示例用例包括:系统配置、部署、安全更新、消息广播和服务器监控。 Serf 也非常可定制,可以适应各种问题的解决方案。
有关 Serf 的更多信息和文档, [[“%3Ca|请访问 http://www.serfdom.io]] [[“%3C/a|”>这里]]。