Docker Overlay網路的一些總結
在早期的docker版本中,是不支援跨主機通訊網路驅動的,也就是說明如果容器部署在不同的節點上面,只能通過暴露埠到宿主機上,再通過宿主機之間進行通訊。隨著docker swarm叢集的推廣,docker也有了自家的跨主機通訊網路驅動,名叫overlay,overlay網路模型是swarm叢集容器間通訊的載體,將服務加入到同一個網段上的Overlay網路上,服務與服務之間就能夠通訊。
容器之間可互相通訊
overlay網路模型在docker叢集節點間的加入了一層虛擬網路,它有獨立的虛擬網段,意味著docker容器傳送的內容,會先發送到虛擬子網,再由虛擬子網包裝為宿主機的真實網址進行傳送。
也意味著在overlay網路模型上,docker不會暴露埠給宿主機,所有有關網路的事情都交給overlay去處理了,這樣的好處就是在同一臺伺服器,不會引起埠衝突,理解這點非常重要。
下面我畫個模型圖給大家理解下:
在早期使用docker進行微服務部署時,你肯定幹過將docker容器所在宿主機的ip作為註冊地址,因為如果你將容器內的ip作為註冊地址,其他服務將不可訪問你的服務,只有一條路,就是將宿主機的ip掛在容器內部處理,或者在容器內部新增ip地址環境變數來處理。
當使用docker swarm進行叢集服務部署時,這個問題自然也就隨之解決了,當服務已加入到overlay網路中,服務容器內會獲得一個overlay網路的一個地址,如下:
而dubbo預設會拿eth0的ip作為註冊地址,因此服務只需要將docker容器的ip地址作為註冊地址就行了,只要服務與服務之間在同一個ovelay網段下,就可以進行通訊。
這裡我特別做了一個驗證,如下:
提供者和消費者同時部署了2個例項,在相同overlay網段下,相互之間是可通訊的。
負載均衡特性
前面我也說了,服務的埠會交給overlay網路去處理。在Overlay網路下,即使該節點並沒有部署指定服務,也會監聽該服務的埠,docker通過這個特性實現了訪問任意一個節點+服務對應埠,就可以訪問服務,而且還具備負載均衡特性。
基於該特性,我突發奇想,我把服務的閘道器加入集群后,無需關心閘道器被分配在哪個節點上,只需要在叢集再上一層nginx層配置若干個節點ip+閘道器服務埠,就可實現雙層負載均衡,即nginx訪問閘道器時的負載均衡,訪問叢集時的負載均衡。如果此時你正在搭建docker swarm叢集,我建議你把閘道器專案同時加入到叢集中,再通過nginx做雙層負載均衡。
swarm load balancer:
Compose編排檔案的網路選擇
編排檔案有個不太靈活的地方, 初次使用它來建立swarm叢集的人可能會犯一些錯誤,比如說:
1.如果你沒有指定網路,它會給你預設建立一個網路,如:
stackname_default
2.假如兩個stack棧分別屬於不同的overlay網路,那麼不同stack棧的服務是不可以進行通訊的。
3.如果你指定一個網路,沒有寫name屬性的,那麼它會在你指定的網路名字前面加個stackname,這本就不是我們設定好的名字,也不知道docker為什麼要這麼做。
4.如果該網路已存在,在部署時還會報錯,不會智慧將該stack服務地加入該網路中。
基於上面幾點坑爹的想不明白docker為什麼這麼做的問題,我建議你在部署服務前,先通過命令建立一個網路:
$ sudo docker network create -d overlay chaos_net
為了防止overlay的網路會跟其它網路有衝突,更嚴謹的做法是自定義overlay網段:
$ sudo docker network create -d overlay --subnet=10.0.15.0/24 chaos_net
在編排檔案的networks上配置defualt屬性,在defualt屬性下面新增external屬性,在其下面填寫剛剛生成的網路的名稱:
networks: default: external: name: chaos_net
官方解析如下圖所示:
這麼做的好處是可以靈活地將不同stack服務棧加入到相同網路下,也可避免上面提到的幾個坑。