在Ubuntu14.04上使用服务发现系统Consul的介绍
介绍
Consul 是一个分布式、高可用、数据中心感知的服务发现和配置系统。 它可用于在灵活而强大的界面中呈现服务和节点,使客户端始终拥有其所属基础架构的最新视图。
Consul 提供了许多不同的功能,用于提供有关您的基础架构的一致且可用的信息。 这包括服务和节点发现机制、标记系统、健康检查、基于共识的选举例程、系统范围的键/值存储等等。 通过在您的组织中利用 consul,您可以轻松地在您的应用程序和服务中建立复杂的意识水平。
在本指南中,我们将向您介绍一些使用 consul 的基础知识。 我们将介绍使 consul 在您的服务器上运行以对其进行测试所需的一般程序。 在下一个指南中,我们将重点介绍在生产环境中设置 consul。
先决条件和目标
在本指南中,我们将熟悉使用 consul 为您的基础设施构建服务发现和配置系统。
对于我们的演示,我们将配置三台服务器和一台客户端。 服务器用于处理查询并维护系统的一致视图。 客户端也是系统的成员,并且可以连接到服务器以获取有关基础架构的信息。 客户端也可能包含将由 consul 监控的服务。
出于本指南和整个系列的目的,我们将配置 4 台计算机。 前三个将是 领事服务器 如上所述。 最后一个是 consul 代理 ,它充当客户端,可用于查询有关系统的信息。
为了让我们稍后实现一些安全机制,我们需要在一个域中命名我们所有的机器。 这样我们就可以在未来利用通配符 SSL 证书。
我们机器的详细信息在这里:
主机名 | IP地址 | 角色 |
---|---|---|
server1.example.com | 192.0.2.1 | 引导领事服务器 |
server2.example.com | 192.0.2.2 | 领事服务器 |
server3.example.com | 192.0.2.3 | 领事服务器 |
agent1.example.com | 192.0.2.50 | 领事客户 |
我们将在此演示中使用 64 位 Ubuntu 14.04 服务器,但任何现代 Linux 服务器都应该同样运行良好。
下载和安装 Consul
我们需要采取的第一步是在我们的每台机器上下载并安装 consul 软件。 应在上面列出的机器的 每个 上执行以下步骤。 您应该以 root 身份登录。
在我们查看 consul 应用程序之前,我们需要获取 unzip
来提取可执行文件。 我们还将使用 screen
应用程序来让我们轻松地在单个终端窗口中拥有多个会话。 这对我们的介绍很有用,因为 consul 通常在不作为服务运行时会占据整个屏幕。
更新本地系统包缓存,然后使用 apt
安装包:
apt-get update apt-get install unzip screen
所以我们不要忘记稍后这样做,现在开始您的屏幕会话:
screen
如果您收到版权信息,请按 Enter。 您将被放回终端窗口,但您现在处于屏幕会话中。
现在,我们可以着手获取 consul 程序了。 consul 项目的页面 提供了 Windows、OS X 和 Linux 二进制包的下载链接。
转到上面的页面并右键单击代表您的服务器的操作系统和体系结构。 在本指南中,由于我们使用的是 64 位服务器,我们将使用“linux”下的“amd64”链接。 选择“复制链接位置”或您的浏览器提供的任何类似选项。
在您的终端中,移动到 /usr/local/bin
目录,我们将在其中保留可执行文件。 键入 wget
和一个空格,然后粘贴您从站点复制的 URL:
cd /usr/local/bin wget https://dl.bintray.com/mitchellh/consul/0.3.0_linux_amd64.zip
现在,我们可以使用之前安装的 unzip
命令提取二进制包。 然后我们可以删除压缩文件:
unzip *.zip rm *.zip
您现在应该在所有服务器上都可以使用 consul
命令。
启动引导服务器
要开始使用 consul,我们需要启动并运行我们的 consul 服务器。 在推荐的多服务器环境中进行配置时,此步骤必须分阶段完成。
我们需要做的第一件事是在我们的一个服务器上以 server
和 bootstrap
模式启动 consul 程序。 服务器模式意味着 consul 将作为服务器实例而不是客户端启动。 引导选项用于第一台服务器。 这允许它在没有选举的情况下将自己指定为集群的“领导者”(因为它将是唯一可用的服务器)。
在指定主机的表中,我们将 server1
指定为引导服务器。 在 server1 上,键入以下命令启动引导程序实例:
consul agent -server -bootstrap -data-dir /tmp/consul
服务器将在当前终端启动,并在事件发生时输出日志数据。 在日志数据的末尾,您将看到以下几行:
. . . 2014/07/07 14:32:15 [ERR] agent: failed to sync remote state: No cluster leader 2014/07/07 14:32:17 [WARN] raft: Heartbeat timeout reached, starting election 2014/07/07 14:32:17 [INFO] raft: Node at 192.0.2.1:8300 [Candidate] entering Candidate state 2014/07/07 14:32:17 [INFO] raft: Election won. Tally: 1 2014/07/07 14:32:17 [INFO] raft: Node at 192.0.2.1:8300 [Leader] entering Leader state 2014/07/07 14:32:17 [INFO] consul: cluster leadership acquired 2014/07/07 14:32:17 [INFO] consul: New leader elected: server1.example.com 2014/07/07 14:32:17 [INFO] consul: member 'server1.example.com' joined, marking health alive
如您所见,由于这是初始节点,因此没有找到集群领导者。 但是,由于我们启用了引导选项,因此该服务器能够自行进入领导者状态,以便使用单个主机启动集群。
启动其他服务器
在 server2
和 server3
上,我们现在可以在没有 引导选项的情况下启动 consul 服务 ,方法是键入:
consul agent -server -data-dir /tmp/consul
对于这些服务器,您还将看到日志条目。 最后,您将看到如下消息:
. . . 2014/07/07 14:37:25 [ERR] agent: failed to sync remote state: No cluster leader 2014/07/07 14:37:27 [WARN] raft: EnableSingleNode disabled, and no known peers. Aborting election. 2014/07/07 14:37:53 [ERR] agent: failed to sync remote state: No cluster leader
发生这种情况是因为它找不到集群领导者并且不能成为领导者本身。 出现这种状态是因为我们的第二个和第三个服务器已启用,但我们的服务器还没有相互连接。
为了相互连接,我们需要将这些服务器相互连接起来。 这可以在任何方向完成,但最简单的是来自我们的 server1
机器。
由于我们在 server1
的当前终端窗口中运行 consul 服务器,因此我们必须使用 screen
创建另一个终端以进行额外的工作。 通过键入以下内容在 server1
的现有屏幕会话中创建一个新的终端窗口:
CTRL-A C
这将打开一个新的终端实例,同时保持我们之前的会话运行。 您可以通过键入以下内容逐步浏览每个现有的终端会话:
CTRL-A N
回到您的新终端,通过引用它们的 IP 地址来加入其他两个实例,如下所示:
consul join 192.0.2.2 192.0.2.3
这应该立即将所有三台服务器加入同一个集群。 您可以通过键入以下内容进行仔细检查:
consul members
Node Address Status Type Build Protocol server1.example.com 192.0.2.1:8301 alive server 0.3.0 2 server2.example.com 192.0.2.2:8301 alive server 0.3.0 2 server3.example.com 192.0.2.3:8301 alive server 0.3.0 2
您也可以从任何其他服务器获取此信息,方法是如上所述在屏幕中创建一个新的终端会话并发出相同的命令。
删除引导服务器并重新加入为常规服务器
我们将所有三台服务器都加入了一个集群,但我们还没有完成。
目前,由于 server1
是在引导模式下启动的,因此它可以在不咨询其他服务器的情况下做出决定。 由于它们应该平等地操作并按法定人数做出决定,因此我们希望在集群启动后删除此特权。
为此,我们需要停止 server1
上的 consul 服务。 这将允许剩余的机器选择一个新的领导者。 然后我们可以在没有引导选项的情况下重新启动 server1
上的 consul 服务并重新加入集群。
在 server1 上,切换回运行 consul 的终端:
CTRL-A N
通过键入以下内容停止服务:
CTRL-C
现在,在没有引导选项的情况下重新启动服务:
consul agent -server -data-dir /tmp/consul
切换回打开的终端并通过连接集群中的两台服务器之一重新加入集群:
CTRL-A N consul join 192.0.2.2
您现在应该可以平等地使用您的三台服务器。 它们将相互复制信息,并将处理单个服务器不可用的情况。 现在,其他服务器也可以加入集群,只需在没有引导程序的情况下启动服务器并加入集群。
作为客户端加入集群并提供 Web UI
现在服务器集群可用,我们可以继续使用客户端计算机进行连接。
我们将把 consul web UI 放在我们的客户端机器上,这样我们就可以与集群交互并监控它的运行状况。 为此, 访问 Web UI 的下载页面。 右键单击下载按钮并选择“复制链接位置”或任何可用的类似选项。
在您的客户端计算机上,切换到您的主目录。 键入 wget
和一个空格,然后粘贴您从页面复制的 URL:
cd ~ wget https://dl.bintray.com/mitchellh/consul/0.3.0_web_ui.zip
下载完成后,解压缩并删除存档:
unzip *.zip rm *.zip
将有一个名为 dist
的目录,其中包含呈现 consul Web UI 所需的所有文件。 我们只需要在连接到集群时指定这个目录。
要连接到集群,我们将使用类似的调用来调用我们用于服务器的 consul 代理。 但是,我们将使用不同的标志。
我们不会使用 server
标志,因为我们想在客户端模式下操作。 默认情况下,每个节点的客户端接口都可以使用本地环回接口访问。 由于我们要远程访问 Web UI,因此我们必须指定客户端的公共 IP 地址。
我们必须将 consul 指向包含 Web UI 的目录才能提供该内容。 此外,我们将通过传递集群中一台服务器的 IP 地址来立即加入集群。 这将使我们避免事后加入。 我们也可以使用服务器示例更早地完成此操作。
最后,我们的连接命令相当长。 它看起来像这样:
consul agent -data-dir /tmp/consul -client 192.0.2.50 -ui-dir /home/your_user/dir -join 192.0.2.1
这会将我们的客户端计算机作为常规的非服务器代理连接到集群。 此代理将响应其公共 IP 地址上的请求,而不是通常的 127.0.0.1
接口。 因此,您需要在任何指定 rpc-addr
的 consul 命令中添加一个附加标志。
例如,如果您想从客户端查询成员列表,则必须通过传入您选择的替代接口和端口来执行此操作:
consul members -rpc-addr=192.0.2.50:8400
Node Address Status Type Build Protocol agent1 192.0.2.50:8301 alive client 0.3.0 2 server2 192.0.2.2:8301 alive server 0.3.0 2 server1 192.0.2.1:8301 alive server 0.3.0 2 server3 192.0.2.3:8301 alive server 0.3.0 2
这可能看起来很麻烦,但它为我们提供了访问 consul web 界面的机会。 您可以通过访问您的客户端的 IP 地址进入 Web 界面,然后在您的 Web 浏览器中输入 :8500/ui
:
http://192.0.2.50:8500/ui
主界面将如下所示:
您可以单击各种菜单并浏览界面。 这为您提供了一种可视化集群以及机器和服务运行状况的好方法。
添加服务和检查
现在,我们要向 consul 添加服务,这是设置它的主要用例。 您可以通过多种方式添加服务,但最简单的方法是创建一个配置目录来存储您的服务定义。
服务与包含服务定义的节点相关联。 因此,如果我们有一个 Web 服务器,我们应该在该服务器上安装 consul 代理并在那里创建一个服务定义文件。
出于我们的目的,我们将在客户端上安装 Nginx 来演示这一点。 通过键入以下内容终止当前客户端会话:
CTRL-C
通过键入以下内容在客户端上安装 Nginx:
apt-get install nginx
现在,我们可以创建一个配置目录来存储我们的服务定义:
mkdir ~/services
在这个目录中,我们将创建一个描述我们的 Web 服务的 JSON 文件。 我们称之为 web.json
:
nano ~/services/web.json
在这个文件中,我们需要为我们的服务定义包含一个结构。 在这个结构中,我们将为服务的健康检查定义一个子结构,以便我们能够可靠地判断它是否正在运行。
基本轮廓如下所示:
{ "service": { . . . "check": { . . . } } }
对于服务,我们需要为服务定义一个名称并告诉 consul 它应该检查哪个端口。 此外,我们可以给它一个标签列表,我们可以使用这些标签对服务进行任意分类,以实现我们自己的排序目的。
对于我们的示例,如下所示:
{ "service": { "name": "web server", "port": 80, "tags": ["nginx", "demonstration"], "check": { . . . } } }
这就是我们定义服务本身所需的全部内容。 但是,我们还想定义一种方法,使 consul 可以验证服务的健康状况。 这通常相当简单,并且会复制普通系统管理员的手动检查。
对于我们的服务,我们将使用 curl
作为 自己的文档 中的 consul 项目列表来实现一个简单的 Web 请求。 我们实际上并不需要知道 curl 能够检索什么,我们只关心命令是否能够在没有任何错误的情况下执行。 因此,我们可以丢弃任何输出。
我们还需要设置运行检查的时间间隔。 这始终是性能和最新信息之间的折衷。 我们将使用 10 秒,因为我们想相对较快地知道是否有问题:
{ "service": { "name": "web server", "port": 80, "tags": ["nginx", "demonstration"], "check": { "script": "curl localhost:80 > /dev/null 2>&1", "interval": "10s" } } }
完成后保存并关闭文件。
现在,我们可以简单地重新启动客户端 consul 会话,并将此目录指向具有服务定义的目录:
consul agent -data-dir /tmp/consul -client 192.0.2.50 -ui-dir /home/your_user/dist -join 192.0.2.1 -config-dir /home/your_user/services
这将重新启动节点并将其连接到集群。 如果您返回 Web 界面,您现在应该会看到一个服务:
回到您的客户端,您可以创建一个新终端并暂时停止 Web 服务器:
CTRL-A C service nginx stop
刷新 Web UI 时,您可以看到 Web 服务检查现在失败,正如预期的那样:
这表明我们的健康检查正在按预期工作。
结论
你现在应该对 consul 的工作原理有了一个基本的了解。 我们在本指南中提供的演示并不完全是在生产中处理 consul 的最佳方式,而是用于让您快速了解该软件的有用功能。
在 下一篇指南 中,我们将介绍如何在生产环境中使用 consul。 我们会将所有配置细节放在文件中以便于参考,并创建新贵脚本以在启动时启动服务。