consul简介
consul是微服务治理方案,提供注册/发现、k/v存储、健康检查以及多数据中心部署的能力。
单节点安装如下:
docker pull consul:0.9.2
启动consul:
docker run -it -p 8500:8500 consul:0.9.2
浏览器访问:localhost:8500,可以看到consul的web UI。
consul可以作为server或client模式运行。
- consul server:consul server之间彼此通信并选举一个leader。
- consul client:集群中的每个节点都有自己的consul client,它负责监控运行在该节点上的服务的健康、与consul server通信。通常和应用服务运行在一个节点中,一个consul client仅仅和某一个consul server通信。
- 集群中的所有client和server共享状态信息:即当一个应用服务注册到一个client,这个信息将在所有与它连接的client和server上都共享可用了。
本文着重描述consul集群方式部署,不熟悉docker也没关系,本文也有很多docker概念讲解。
基础准备
1、docker安装包
docker for linux/mac ,此安装包包含:
-
docker引擎
-
docker-machine:虚拟机管理
-
swarm mode:docker引擎内置的容器编排功能,包括容器集群化和调度。
不要混淆swarm mode和docer swarm。
swarm mode是1.12版提供的能力,集成在docker引擎中,没有和machine、compose集成,内置了k/v存储,并集成了overlay networks支持。
而docker swarm是1.12版之前的集群方案,是独立的工具。在docker1.12之前,创建docker集群是需要用docker swarm的,并且需要额外的k/v存储(consul、etcd等)同步网络配置,保证节点在一个容器中。
-
docker-compose:服务编排组件
2、virtualbox
虽然macOS自带HyperKit虚拟解决方案,但因为docker 没有HyperKit driver,所以需要用virtualbox,手动下载安装或者docker早期解决方案Toolbox安装过也可。
架构设计
最初的架构设计是这样的:
这种架构也能建成功,但考虑到对swarm集群的理解不要太狭隘,重新设计了另外的架构。
虽然不是所有的服务都适合部署到swarm集群,但是consul是适合的,部署的方式是swarm 的manager节点和consul server重合,swarm的worker节点和consul client重合。
重新设计架构如下:
实施
1、创建4个虚拟机
写一个shell脚本crete_vms.sh批量创建:
#!/bin/sh
#创建4个虚拟机
set -e
vms=("vm1" "vm2" "vm3" "vm4")
for vm in ${vms[@]}
do
docker-machine create \
-d virtualbox \
--virtualbox-memory "1024" \
--virtualbox-cpu-count "1" \
--virtualbox-disk-size "2000" \
${vm}
done
docker-machine ls
给这个脚本授权:sudo chmod a+x create_vms.sh,并执行后可以看到虚拟机创建完成。
小提示:
docker-machine 会自动加载一个Boot2Docker ISO用于构建docker容器运行环境。
2、构建swarm集群
2.1 用swarm mode方式将这4台虚拟机构建成一个集群
首先需要在一台机器上初始化swarm,这里在vm1上进行初始化,先绑定vm1环境:
eval $(docker-machine env vm1)
然后初始化:
docker swarm init --advertise-addr $(docker-machine ip vm1)
这时,vm1变成一个集群中的manager节点了。
2.2 接下来将vm2作为一个manager节点加入这个swarm 先查询加入命令:
docker swarm join-token manager
To add a manager to this swarm, run the following command: docker swarm join --token SWMTKN-1-64eiwxk3wzoau20f7iv56fw0apgsxsk0gnzwb1e6okbezd373b-eyhb3sbu3fkcj8uyzw1bigayj 192.168.99.100:2377
然后绑定vm2环境:
eval $(docker-machine env vm2)
执行加入命令:
docker swarm join --token SWMTKN-1-64eiwxk3wzoau20f7iv56fw0apgsxsk0gnzwb1e6okbezd373b-eyhb3sbu3fkcj8uyzw1bigayj 192.168.99.100:2377
2.3 将vm3和vm4作为worker节点加入这个swarm 先查询加入命令:
docker swarm join-token worker
To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-64eiwxk3wzoau20f7iv56fw0apgsxsk0gnzwb1e6okbezd373b-8ern27gy685jifwq7b9cjvhcn 192.168.99.100:2377
绑定vm3环境:
eval $(docker-machine env vm3)
执行加入命令:
docker swarm join --token SWMTKN-1-64eiwxk3wzoau20f7iv56fw0apgsxsk0gnzwb1e6okbezd373b-8ern27gy685jifwq7b9cjvhcn 192.168.99.100:2377
绑定vm4环境:
eval $(docker-machine env vm4)
执行加入命令:
docker swarm join --token SWMTKN-1-64eiwxk3wzoau20f7iv56fw0apgsxsk0gnzwb1e6okbezd373b-8ern27gy685jifwq7b9cjvhcn 192.168.99.100:2377
至此,swarm集群创建完成! 切换到manager 节点查看集群信息:
eval $(docker-machine env vm1)
docker node ls
MANAGER STATUS显示为Reachable表示该节点是一个manager,空表示是一个worker。
可以在swarm manager节点环境下查看网络信息:
docker network ls
可以看到ingress的网络是属于swarm的,其他的都是本地(local)。swarm集群中的节点是自动加入overlay网络的。
小提示:
docker-machine env vm的作用是查看vm的环境变量,而eval $(docker-machine env vm)是执行,即将当前shell与指定的虚拟机配置环境进行绑定,关掉shell也就释放了这种绑定的环境。这个命令的最好使用场景就是:虚拟机中不需要安装docker compose、machine等、也不需要上传配置文件到虚拟机,就可以在当前shell中执行虚拟机中不存在的命令和文件来操作虚拟机容器和服务。
如果要解绑,执行解绑命令:
eval $(docker-machine env -u)
3、构建consul集群
3.1 先创建一个consul server leader,写个consul-server-init.yml文件:
version: '3.3'
services:
consul-server:
image: consul:0.9.2
environment:
- "CONSUL_LOCAL_CONFIG={\"disable_update_check\": true}"
- "CONSUL_CLIENT_INTERFACE=eth0"
- "CONSUL_BIND_INTERFACE=eth1" #容器启动时自动绑定eth1端口的IP
entrypoint:
- consul
- agent
- -server
- -bootstrap #作为一个集群启动
- -data-dir=/consul/data
- -advertise={{ GetInterfaceIP "eth1" }}
- -client=0.0.0.0 #consul服务侦听地址提供HTTP、DNS、RPC等服务,默认是127.0.0.1,对外提供服务需改成0.0.0.0
- -ui
ports:
- 8300:8300 #server rpc address
- 8301:8301 #CLuster Serf Addr LAN
- 8301:8301/udp
- 8302:8302 #Cluster Serf Addr WAN
- 8302:8302/udp
- 8400:8400 #cli rpc endpoint
- 8500:8500 #Web UI, http api
- 8600:53/udp #DNS服务
network_mode: host #此处指定host模式才能绑定到eth1
切换到vm1 manager节点
eval $(docker-machine env vm1)
docker-compose -f consul-server-init.yml up -d
如果启动报错,可以通过docker logs container_id来查看错误信息,然后再docker-compose -f consul-server-init.yml down掉它。
3.2 再写一个consul-server-join.yml用来创建consul server follower加入该集群。
version: '3.3'
services:
consul-server:
image: consul:0.9.2
environment:
- "CONSUL_LOCAL_CONFIG={\"disable_update_check\": true}"
- "CONSUL_CLIENT_INTERFACE=eth0"
- "CONSUL_BIND_INTERFACE=eth1" #容器启动时自动绑定eth1端口的IP
entrypoint:
- consul
- agent
- -server
- -data-dir=/consul/data
- -retry-join=192.168.99.100 #加入一个集群
- -advertise={{ GetInterfaceIP "eth1" }}
- client=0.0.0.0
- -ui
ports:
- 8300:8300 #server rpc address
- 8301:8301 #CLuster Serf Addr LAN
- 8301:8301/udp
- 8302:8302 #Cluster Serf Addr WAN
- 8302:8302/udp
- 8400:8400 #cli rpc endpoint
- 8500:8500 #Web UI, http api
- 8600:53/udp #DNS服务
network_mode: host #此处指定host(宿主机)模式才能绑定到eth1
切换到vm2环境
eval $(docker-machine env vm2)
docker-compose -f consul-server-join.yml up -d
3.3 写一个consul-client.yml来创建consul client并加入集群
version: '3.3' #第三版开始支持swarm mode集群的compose-file编排
services:
consul-agent:
image: consul:0.9.2
environment:
- "CONSUL_LOCAL_CONFIG={\"disable_update_check\": true}"
- "CONSUL_CLIENT_INTERFACE=eth0"
- "CONSUL_BIND_INTERFACE=eth1" #容器启动时自动绑定eth1端口的IP
entrypoint:
- consul
- agent
- -data-dir=/consul/data
- -advertise={{GetInterfaceIP "eth1"}}
- -retry-join=192.168.99.100 #consul server的地址,以便使该client与 server组成同一个集群
- -retry-join=192.168.99.101
network_mode: host #此处指定host(宿主机)模式才能绑定到eth1
分别切换到vm3和vm4环境执行创建:
eval $(docker-machine env vm3)
docker-compose -f consul-client.yml up -d
eval $(docker-machine env vm4)
docker-compose -f consul-client.yml up -d
到此为止,consul集群创建完成,查看集群信息:
docker exec -t <vm1容器id> consul members
这里我故意把vm3服务离开了。
小结:
consul不适合用1.13的deploy部署,还是写运维shell方式部署最省事,我上面为了讲清楚很多概念一步一步描述的。 deploy部署的话默认会虚拟出一个集群vip,多个相同服务绑定到这个共同的vip上对外提供服务。
访问http://192.168.99.100:8500,可以看到consul管理界面:
下一篇文章演示Registrator和应用的部署。
@i5ting 编辑器有待提高,写文章真心累。markdown标准语法预览的时候显示不正确以至于一直耿耿于怀不敢发布。
@m3shine 感谢,辛苦,写的很详细嘛
@i5ting 你不会理解错了吧?我是说cnode的编辑器 😄
@m3shine 知道,没那么傻,哈哈
文章很给力,为什么不使用k8s而使用swarm,有什么考虑吗? 我们公司也是用consul来进行服务注册和心跳检查和用它的UI来设置k/v储存
@zy445566 部署成本相对比较低,适合小型团队。
swarm mode自带服务发现的
@zy445566 具体选型的考虑倒没有,实现微服务的技术很多,这只是其中一种。
@coordcn 太喜欢你了
@richenlin 你这一句话,我过几天再来答复你