微服务实践专题系列(二):基于Docker swarm mode集群的consul集群部署

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安装过也可。

架构设计

最初的架构设计是这样的:
微服务实践专题系列(二):基于Docker swarm mode集群的consul集群部署_第1张图片

这种架构也能建成功,但考虑到对swarm集群的理解不要太狭隘,重新设计了另外的架构。

虽然不是所有的服务都适合部署到swarm集群,但是consul是适合的,部署的方式是swarm 的manager节点和consul server重合,swarm的worker节点和consul client重合。

重新设计架构如下:
微服务实践专题系列(二):基于Docker swarm mode集群的consul集群部署_第2张图片

实施

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

微服务实践专题系列(二):基于Docker swarm mode集群的consul集群部署_第3张图片

可以看到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 consul members
图片描述
这里我故意把vm3服务离开了。

小结:
consul不适合用1.13的deploy部署,还是写运维shell方式部署最省事,我上面为了讲清楚很多概念一步一步描述的。
deploy部署的话默认会虚拟出一个集群vip,多个相同服务绑定到这个共同的vip上对外提供服务。

访问http://192.168.99.100:8500,可以看到consul管理界面:
微服务实践专题系列(二):基于Docker swarm mode集群的consul集群部署_第4张图片

下一篇文章演示Registrator和应用的部署。

你可能感兴趣的:(服务治理,docker,swarm,consul,微服务)