一、前言
当我们开发好微服务之后,考虑到灵活快速持续部署的需要,通常会考虑将其Docker镜像化并在Docker环境下运行。由于微服务个数通常会较多,把所有微服务部署在一台docker主机上是不现实的,因此需要考虑到跨主机通信的问题,对实际部署必然会提出以下几点要求:
1. 微服务作为一个docker container可以在任意host上运行;
2. 同一host上可以运行多个相同的微服务;
3. 运行在同一个host上的微服务之间可以相互通信;
4. 运行在不同host上的微服务也可以相互通信;
5. 每个微服务的ip地址不受host所在本地局域网ip地址段限制,即拥有独立网段,避免占用本地IP地址,同时确保container数量受限尽量小;
6. 每个微服务container避免通过端口暴露的方式相互通信,确保不会因端口独占而导致无法灵活部署。
综上原因,docker swarm模式下将各微服务加入同一个overlay network网络的方式实现微服务之间的相互通信。
二、总体架构图(来源网络)
说明:
如图所示,假设本地局域网段10.159.62.0/24中存在主机10.159.62.231,10.159.62.232和10.159.62.233互联互通
每个主机上都运行dockerengine,通过docker engine运行若干个docker container,例如图中的Order,Billing等等。
将这3台主机建立成为一个dockerswarm集群
创建一个docker overlay网络(网段10.10.0.0/24),每个主机上的container都被加入到该overlay网络中,通过overlay网络实现跨主机的container相互通信
假设console,terminal和api这三个服务均需要暴露端口到物理网络,因为物理网络10.159.62.0/24无法直接访问overlay网络中的container,需要container中映射端口到物理网络。
overlay网络中的container默认通过与主机之间的bridge访问物理网络。
三、创建Swarm 集群
1.准备机器3台
l172.17.0.201
l172.17.0.143
l172.17.0.89
在主机201上创建管理节点
$ docker swarm init --advertise-addr 172.17.0.201
执行完会显示
Swarm initialized: current node (vjvp9h9cu1q1umerisj579g4r) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-5fv3wqbq809m85y3h4f6xptmls4wxdn4evntgvij9fkldon6af-8n05wlyxoq3ckmv4bd5pj3x4g 172.17.0.201:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
swarm集群需要使用到相同的Overlay network(网卡),所以我们应该给另外的节点也设置为管理节点,通过命令docker swarm join-token manager
在201,89服务器生成管理节点token(也可以先成工作节点,再升级为管理节点)执行完会显示:
To add a manager to this swarm, run the following command:
docker swarm join --token SWMTKN-1-5fv3wqbq809m85y3h4f6xptmls4wxdn4evntgvij9fkldon6af-8i3ekx4n8ht9nezb8pk4s8hft 172.17.0.201:2377
2. 在主机143上创建管理节点
$ docker swarm join --token SWMTKN-1-5fv3wqbq809m85y3h4f6xptmls4wxdn4evntgvij9fkldon6af-8i3ekx4n8ht9nezb8pk4s8hft 172.17.0.201:2377
3.在主机89上创建管理节点
$ docker swarm join --token SWMTKN-1-5fv3wqbq809m85y3h4f6xptmls4wxdn4evntgvij9fkldon6af-8i3ekx4n8ht9nezb8pk4s8hft 172.17.0.201:2377
通过任意一个节点命令可以查询节点名称
docker node ls(目前设置的为两个节点)
节点的hostname 没有可读性,可以通过下面命令修改各个服务器的hostname(不设置可以忽略此部分)
# hostnamectl set-hostname manger201 # systemctl restart docker
再次docker node ls如下
四、构建Overlay network(容器互通的关键)
在管理节点主机201上执行
docker network create -d overlay --subnet=10.10.0.0/16 --gateway=10.10.0.254 --attachable=true my-network-overlay
通过docker network ls命令查看到生成的集群网卡,另外两台服务器节点通过该命令也可以查看到这个集群网络
扩展部分(dubbo2.7.X版本以上需要设置)
由于dubbo2.7.6后zk注册中心消费者使用的容器ip是docker swarm network网卡的docker_gwbridge
需要将集群中所有节点的
docker_gwbridge改为相同的网段,否则远程调用将调用不通(nacos注册中心用的是my-network-overlay网段,不需要设置docker_gwbridge),修改方式参考:
https://www.cnblogs.com/yyxianren/p/10892066.html
查看当前网段
docker network inspect docker_gwbridge
删除网段
docker network rm docker_gwbridge
如果报次错需要先解散集群再进行删除操作
Error response from daemon: error while removing network: network docker_gwbridge id 6bb302db0876b57762afbe49d0c3df1641a9da59c20d4640530c53585f9b457b has active endpoints
使用以下命令先解散集群再删除:
docker swarm leave
docker network rm docker_gwbridge
service docker restart
如果为从管理节点143,89,先降级为任务节点,再解散
如果为主管理节点201,则需要重新初始化集群和重建Overlay network网络,按步骤三和步骤四进行操作
生成网段,由于是docker_gwbridge 网卡scope 是local,所以需要所有集群节点进行重新生成
docker network create --subnet 172.21.0.0/20 --gateway 172.21.0.1 -o com.docker.network.bridge.enable_icc=false -o com.docker.network.bridge.name=docker_gwbridge docker_gwbridge
五、部署服务
根据上文架构图中所示分别在各主机上执行类似的命令,将各微服务docker container启动起来。
对于不需要暴露端口的微服务,命令类似如下
$ docker run --name order --network=my-network-overlay 10.159.62.231/somecom/order:1.0.0 &
通过--network=my-network-overlay 加入到集群同一网段,这样就可以实现跨主机的容器联通