由于 Consul 是由 Hashicorp 公司开发的,而这个公司旗下还有一款著名的虚拟化工具 Vagrant,所以这篇教程我们基于 Vagrant 在本地通过虚拟机来演示如何搭建一个包含多个服务端和客户端代理的 Consul 集群。
初始化虚拟机
我们将搭建一个包含两个 Consul Server,一个 Consul Client 的集群环境,前面我们介绍 Consul 原理的时候已经提到过,Server 比较重,负责所有数据的存储并保证一致性,Client 则比较轻量级,只负责健康检查和请求转发,首先我们在本地用户家目录下创建一个 Consul
目录作为 Consul 虚拟机的工作台,然后在该目录下创建一个 Vagrantfile
来存储虚拟机配置信息:
cd ~
mkdir Consul
cd Consul
touch Vagrantfile
然后编辑 Vagrantfile
内容如下(从 https://github.com/hashicorp/consul/blob/master/demo/vagrant-cluster/Vagrantfile 示例文件中拷贝过来粘贴):
# -*- mode: ruby -*-
# vi: set ft=ruby :
$script = <<SCRIPT
echo "Installing dependencies ..."
sudo apt-get update
sudo apt-get install -y unzip curl jq dnsutils
echo "Determining Consul version to install ..."
CHECKPOINT_URL="https://checkpoint-api.hashicorp.com/v1/check"
if [ -z "$CONSUL_DEMO_VERSION" ]; then
CONSUL_DEMO_VERSION=$(curl -s "${CHECKPOINT_URL}"/consul | jq .current_version | tr -d '"')
fi
echo "Fetching Consul version ${CONSUL_DEMO_VERSION} ..."
cd /tmp/
curl -s https://releases.hashicorp.com/consul/${CONSUL_DEMO_VERSION}/consul_${CONSUL_DEMO_VERSION}_linux_amd64.zip -o consul.zip
echo "Installing Consul version ${CONSUL_DEMO_VERSION} ..."
unzip consul.zip
sudo chmod +x consul
sudo mv consul /usr/bin/consul
sudo mkdir /etc/consul.d
sudo chmod a+w /etc/consul.d
SCRIPT
# Specify a Consul version
CONSUL_DEMO_VERSION = ENV['CONSUL_DEMO_VERSION']
# Specify a custom Vagrant box for the demo
DEMO_BOX_NAME = ENV['DEMO_BOX_NAME'] || "debian/stretch64"
# Vagrantfile API/syntax version.
# NB: Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = DEMO_BOX_NAME
config.vm.provision "shell",
inline: $script,
env: {'CONSUL_DEMO_VERSION' => CONSUL_DEMO_VERSION}
config.vm.define "n1" do |n1|
n1.vm.hostname = "n1"
n1.vm.network "private_network", ip: "172.20.20.10"
end
config.vm.define "n2" do |n2|
n2.vm.hostname = "n2"
n2.vm.network "private_network", ip: "172.20.20.11"
end
end
接下来,在该目录下运行如下命令初始化并启动上面配置的两个 Consul Server 节点对应的虚拟机(IP 分别为 172.20.20.10
和 172.20.20.11
):
vagrant up
如果感觉这种方式下载太慢,可以将其中的链接拷贝出来:https://vagrantcloud.com/debian/boxes/stretch64/versions/9.9.1/providers/virtualbox.box,粘贴到浏览器地址栏然后回车下载,浏览器中下载还是慢的话,就再把浏览器解析出来的下载地址拷贝到下载软件去下载:
可以看到,下载速度快了很多,下载完成后,在本地将下载的 box 文件手动添加到 Vagrant 里面,通过 name
选项指定 box 名称,这里的 name
和 Vagrantfile
文件中的 DEMO_BOX_NAME
值保持一致,默认是 debian/stretch64
:
vagrant box add --name debian/stretch64 /path/to/virtualbox
然后再到 Vagrantfile
所在目录运行 vagrant up
命令,即可快速完成虚拟机安装:
…
检查服务端 Consul 安装
安装完成后,我们来检查下虚拟机环境是否符合预期,这里我们只安装了两个虚拟机,用于模拟 Consul Server 服务端节点,而 Consul Client 则运行在本地,与 Go Micro 搭建的微服务部署在一起。
首先运行 vagrant status
查看虚拟机盒子状态,可以看到已经上面安装的两个虚拟机已经运行起来了:
打开 VirtualBox,也可以在虚拟机列表中看到这两个虚拟机:
接下来,我们分别进入这两个虚拟机,检查 Consul 是否安装成功:
启动 Consul Server 集群
从上面的截图中可以看到 Consul 在服务端都已经安装成功,接下来,我们要以 Server 模式启动它们,并将它们组合到同一个数据中心集群,打开两个终端窗口,一个通过 vagrant ssh n1
进入节点 n1
,以服务器模式启动 Consul:
consul agent -server -bootstrap-expect=2 \
-data-dir=/tmp/consul -node=agent-one -bind=172.20.20.10 \
-config-dir=/etc/consul.d
另一个通过 vagrant ssh n2
进入节点 n2
,同样以服务器模式启动 Consul:
consul agent -server -bootstrap-expect=2 \
-data-dir=/tmp/consul -node=agent-two -bind=172.20.20.11 \
-enable-script-checks=true -config-dir=/etc/consul.d
此时,两个服务器节点的 Consul Server 代理都已经运行起来了,但它们还不知道彼此,要将它们加入到一个集群,可以这么做,进入 n1
虚拟机,运行如下命令:
将 n2
节点对应的 IP 地址 172.20.20.11
加入进来,这样,运行 consul members
就能看到它们已经处于同一个数据中心了(默认是 dc1
):
反之,也可以在 n2
上运行该命令,将 IP 地址调整为 n1
节点的 IP
地址即可。
同时可以在 Consul 日志中看到选举 n1
为 Leader 节点(在各自节点上可以通过 consul info
查看明细):
启动 Consul 客户端代理
接下来,我们回到本地,通过如下命令以 Client 模式启动 Consul 代理:
consul agent -node=agent-client -bind=172.20.20.1 -data-dir=/tmp/consul
同样,如果没有加入到集群中,也是看不到其它 Consul 代理的,我们可以通过和服务端一样的方式将其加入到集群中(加入任何一个节点即可),然后就可以看到集群中的所有节点了,包括服务端和客户端 Consul 代理:
这个时候,如果中断 Consul 服务端/客户端代理进程,会导致对应节点状态为 failed
,即不可用:
我们可以带上 -rejoin
选项再次启动中断的节点代理,表示重新加入之前的集群,同时带上 -ui
选项表示启动 Web UI 可视化界面:
consul agent -node=agent-client -bind=172.20.20.1 -data-dir=/tmp/consul -ui -rejoin
再次运行 consul members
命令,可以看到对应节点的 Consul 代理进程已经恢复正常了:
在浏览器中访问 http://localhost:8500/ui/dc1/nodes
,可以看到所有有效的节点信息:
简单测试
接下来,我们简单测试下 Consul 的 KV 存储功能,在客户端机器上运行如下代码:
consul kv put hello world
然后在服务端机器即可访问到对应的存储信息,因为客户端代理并不会做存储和同步,这些请求会转发到服务端,最终由 Leader 完成存储和同步:
consul kv get hello
然后我们来测试下服务注册和发现功能是否正常,在本地启动 Greeter 微服务:
服务注册时,同样会经由客户端运行的代理将请求转发给服务端 Leader 节点进行存储和同步,登录到 n1
节点,运行如下命令即可看到对应注册的所有服务:
接下来,在本地运行客户端请求代码:
可以看到,服务发现功能也是 OK 的,这个服务请求同样会经由客户端 Consul 代理转发到服务端代理进行查询,并将服务节点信息返回,再由对应节点运行的微服务进程对请求进行处理和返回。
当然,我们还可以基于 Docker 来模拟 Consul 集群,关于 Docker 编排部分,我们在后面运维部分再详细介绍。