公司微服務快上線了,微服務都是用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學習與實踐文章,禁止布布扣、碼迷等第三方爬蟲網站爬取