公司微服务快上线了,微服务都是用Docker容器进行部署的,在同一台主机下,把服务都部署上,注册到Nacos的IP与PORT都是内网的IP与Dockerfile中定义的端口号,看起来好像也没什么问题,经过网关去调用也是能够调通的,请注意这有一个大前提:html
必须把全部服务容器部署在同一台主机上时才能够!node
当服务实例没有部署在同一主机上,好比网关服务在A服务器,服务a在B服务器上,一样注册到Nacos (或其它注册中心) ,此时上报上来的都是内网的IP,那么当外部有请求进来的时候,网关经过Nacos的服务列表,找到了对应的服务a的内网IP,一调用发现调用不通git
ps:内网怎么会通……github
微服务容器能够不在同一台服务器上,互相调用docker
如下分别按上边的“想法”部分来进行说明下问题shell
ifconfig
发现内部网卡只有两个,分别是eth0
与lo
,对应网卡的IP就是内网IP ——仍是没用docker ps
再也直接看不到端口号了,须要额外去docker inspect
——能够用eth0
,有的是ens33
呢?还有更多不可测的状况! ——或许可用最稳妥的办法——使用Docker网络共享,在搜索引擎的帮助下,我决定用Overlay的方式来实现效果数据库
如下简单说下Overlay:json
容器在两个跨主机进行通讯的时候,是使用overlay network这个网络模式进行通讯;若是使用host也能够实现跨主机进行通讯,直接使用这个物理的ip地址就能够进行通讯。overlay它会虚拟出一个网络好比10.0.2.3这个ip地址。在这个overlay网络模式里面,有一个相似于服务网关的地址,而后把这个包转发到物理服务器这个地址,最终经过路由和交换,到达另外一个服务器的ip地址。vim
想要实现Overlay网络,须要引入一个K-V数据库,来保存网络状态信息,包括 Network、Endpoint、IP 等。Consul、Etcd 和 ZooKeeper 都是 Docker 支持的K-V数据库centos
咱们这里使用 Consul,相比其它K-V数据库,Consul提供的界面化方便管理,因此这里使用Consul实现Overlay
经过让每一个服务器的Docker daemon将本身的IP注册到Consul中,来共享Docker内网,这里共享的内网是Overlay网络模式的,也只有在注册的Docker环境下使用同overlay网络的容器,才能互相通信
ps: 建立完成后,不使用overlay网络的跨服务器容器,不能ping通
单节点的Consul实现Overlay网络,使用Docker镜像
服务器OS | 主机IP | Docker版本 | 网卡名 |
---|---|---|---|
Ubuntu Server 18.04 LTS | 192.168.87.133 | 18.09.6 | ens33 |
Ubuntu Server 18.04 LTS | 192.168.87.139 | 18.09.7 | ens33 |
待使用的Consul版本为1.5.2,看Docker Hub上提示漏洞目前最小的。
本测试环境适用于Systemd管理的Linux发行版
Consul没有使用非官方的progrium/consul,主要是由于这个镜像实在太老了,四年前的若是有漏洞也没能及时修复,因此本身去<hub.docker.com>去趟了遍官方的坑!💔
每台运行docker的主机都不能同hostname,可使用
$ sudo hostnamectl set-hostname your-new-hostname
同hostname会致使同名的主机docker没法互相通讯
准备Consul使用镜像在133服务器上启动,因此能够先配置下Docker daemon的启动参数指向133服务器
$ ifconfig #已经去除干扰网卡,记录网卡名为ens33 ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.87.133 netmask 255.255.255.0 broadcast 192.168.87.255 inet6 fe80::20c:29ff:fe02:e00a prefixlen 64 scopeid 0x20<link> ether 00:0c:29:02:e0:0a txqueuelen 1000 (Ethernet) RX packets 156739 bytes 233182466 (233.1 MB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 45173 bytes 2809606 (2.8 MB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 $ vim /etc/docker/daemon.json
保存退出.
cluster-store
:配置的Consul的leader地址,单体直接写,其它软件注意协议
cluster-advertise
: 指定监听的网卡和端口,也能够指定接收订阅消息的IP:PORT
还有一种是直接修改docker.service的,参考以下:
$ cd /etc/systemd/system/multi-user.target.wants $ sudo vim docker.service找到
ExecStart=
字眼,在此行末尾添加以下代码--cluster-store=consul://192.168.87.133:8500 --cluster-advertise=ens33:2375效果以下:
操做效果与以上方法保持一致
接着执行命令,重启docker服务,另外一台服务器操做方式相同,注意网卡名称
$ sudo systemctl daemon-reload && sudo systemctl restart docker
docker run -d --network host -h consul --name=consul --restart=always -e CONSUL_BIND_INTERFACE=ens33 consul:1.5.2
用主机模式的缘由是防止有些端口没有映射出来,还有就是想让Consul识别外部网卡的方式只能host模式,下面给个非host的方式
$ docker run -di -h consul -p 8500:8500 --name=consul consul:1.5.2
$ docker network create -d overlay my_overlay
这里与普通建立网络不一样在于指定了overlay模式的网络,
-d
也能够写为--driver
192.168.87.133:8500
咱们的配置在Key/Value处,
点击docker -> nodes
出现上边的两个节点,分别是两个docker daemon (守护进程) 注册的值
新建两个centos的容器分别在两台服务器上,使用overlay 咱们刚才建立的网络
133服务器
$ docker run -di --network my_overlay --name mycentos1 centos:7
139服务器
$ docker run -di --network my_overlay --name mycentos2 centos:7
--net
全拼为--network
,--
开头的可不加=
查看133服务器mycentos1容器的IP
$ docker inspect -f "{{ .NetworkSettings.Networks.my_overlay.IPAddress}}" mycentos1 10.0.1.2
查看139服务器mycentos2容器的IP
$ docker inspect -f "{{ .NetworkSettings.Networks.my_overlay.IPAddress}}" mycentos2 10.0.1.3
分别从133服务器ping 139服务器的mycentos2的内网IP
反过来ping也是同样的,可是并非让咱们经过外部去访问的,经过同一overlay网络的容器就能够,不信咱们做以下尝试
133服务器
$ docker exec -it mycentos1 bash # ping 10.0.1.3
访问得通,没有丢包,反过来也是同样的,篇幅有限就不试验了
这起码说明,如今的服务的确已经网络互通了,下篇文章咱们来搞下生产用的集群方式
本文系Hellxz学习与实践文章,禁止布布扣、码迷等第三方爬虫网站爬取