常見的跨主機(jī)通信方案主要有以下幾種:
形式 | 描述 |
---|---|
Host模式 | 容器直接使用宿主機(jī)的網(wǎng)絡(luò),這樣天生就可以支持跨主機(jī)通信。這樣方式雖然可以解決跨主機(jī)通信的問題,但應(yīng)用場景很有限,容易出現(xiàn)端口沖突,也無法做到隔離網(wǎng)絡(luò)環(huán)境,一個(gè)容器崩潰很可能引起整個(gè)宿主機(jī)的崩潰。 |
端口綁定 | 通過綁定容器端口到宿主機(jī)端口,跨主機(jī)通信時(shí)使用:主機(jī)IP:端口的方式訪問容器中的服務(wù)。顯然,這種方式僅能支持網(wǎng)絡(luò)棧的4層及以上的應(yīng)用,并且容器與宿主機(jī)緊耦合,很難靈活的處理問題,可擴(kuò)展性不佳。 |
定義容器網(wǎng)絡(luò) | 使用Open vSwitch或Flannel等第三方SDN工具,為容器構(gòu)建可以跨主機(jī)通信的網(wǎng)絡(luò)環(huán)境。 這類方案一般要求各個(gè)主機(jī)上的Dockero網(wǎng)橋的cidr不同,以避免出現(xiàn)IP沖突的問題,限制容器在宿主機(jī)上可獲取的IP范圍。并且在容器需要對(duì)集群外提供服務(wù)時(shí),需要比較復(fù)雜的配置,對(duì)部署實(shí)施人員的網(wǎng)絡(luò)技能要求比較高。 |
容器網(wǎng)絡(luò)發(fā)展到現(xiàn)在,形成了兩大陣營:
-
Docker
的CNM
-
Google、
Coreos、
Kuberenetes
主導(dǎo)的CNI
CNM和CNI是網(wǎng)絡(luò)規(guī)范或者網(wǎng)絡(luò)體系,并不是網(wǎng)絡(luò)實(shí)現(xiàn)因此并不關(guān)心容器網(wǎng)絡(luò)的實(shí)現(xiàn)方式( Flannel或者Calico等), CNM和CNI關(guān)心的只是網(wǎng)絡(luò)管理
網(wǎng)絡(luò)類型 | 描述 |
---|---|
CNM (Container Network Model) | CNM的優(yōu)勢在于原生,容器網(wǎng)絡(luò)和Docker容器,生命周期結(jié)合緊密;缺點(diǎn)是被Docker “綁架”。支持CNM網(wǎng)絡(luò)規(guī)范的容器網(wǎng)絡(luò)實(shí)現(xiàn)包括:Docker Swarm、overlay、Macvlan & IP networkdrivers、 Calico、Contiv、?Weave等。 |
CNI ( Container Network Interface) | CNI的優(yōu)勢是兼容其他容器技術(shù)(如rkt)及上層編排系統(tǒng)(Kubernetes&Mesos),而且社區(qū)活躍勢頭迅猛;缺點(diǎn)是非Docker原生。支持CNI網(wǎng)絡(luò)規(guī)范的容器網(wǎng)絡(luò)實(shí)現(xiàn)包括:Kubernetes、 Weave、Macvlan、Calico、Flannel、ContivMesos CNI等。 |
但從?網(wǎng)絡(luò)實(shí)現(xiàn)角度,又可分為:
網(wǎng)絡(luò)實(shí)現(xiàn)角度 | 描述 |
---|---|
隧道方案 | 隧道方案在laas層的網(wǎng)絡(luò)中應(yīng)用也比較多,它的主要缺點(diǎn)是隨著節(jié)點(diǎn)規(guī)模的增長復(fù)雜度會(huì)提升,而且出了網(wǎng)絡(luò)問題后跟蹤起來比較麻煩,大規(guī)模集群情況下這是需要考慮的一個(gè)問題。 |
路由方案 | 一般是基于3層或者2層實(shí)現(xiàn)網(wǎng)絡(luò)隔離和跨主機(jī)容器互通的,出了問題也很容易排查。 Calico :基于BGP協(xié)議的路由方案,支持很細(xì)致的ACL控制,對(duì)混合云親和度比較高。 Macvlan:從邏輯和Kernel層來看,是隔離性和性能最優(yōu)的方案?;诙痈綦x,所以需要一層路由器支持,大多數(shù)云服務(wù)商不支持,所以混合云上比較難以實(shí)現(xiàn)。 |
Docker主機(jī)之間容器通信解決方案:
- 橋接宿主機(jī)網(wǎng)絡(luò)
- 端口映射
- docker網(wǎng)絡(luò)驅(qū)動(dòng):
- 1、 Overlay:基于VXLAN封裝實(shí)現(xiàn)Docker原生Overlay網(wǎng)絡(luò)。
- 2、Macvlan:Docker主機(jī)網(wǎng)卡接口邏輯上分為多個(gè)子接口,每個(gè)子接口標(biāo)識(shí)一個(gè)VLAN。容器接口直接連接Docker主機(jī)網(wǎng)卡接口,通過路由策略轉(zhuǎn)發(fā)到另一臺(tái)Docker主機(jī)。
第三方網(wǎng)絡(luò)項(xiàng)目:
- 隧道方案:
- Flannel:支持UDP和VXLAN封裝傳輸方式
- Weave:支持UDP(sleeve模式)和VXLAN(優(yōu)先fastdp模式)
- OpenvSwitch:支持VXLAN和GRE協(xié)議
- 路由方案:
- Calico:支持BGP協(xié)議和IPIP隧道。每臺(tái)宿主機(jī)作為虛擬路由,通過BGP協(xié)議實(shí)現(xiàn)不同主機(jī)容器間通信。
1、overlay網(wǎng)絡(luò)模式
? ? 在早期的docker版本中,是不支持跨主機(jī)通信網(wǎng)絡(luò)驅(qū)動(dòng)的,也就是說如果容器部署在不同的節(jié)點(diǎn)(公網(wǎng)或局域網(wǎng)里不同的主機(jī))上面,只能通過暴露端口到宿主機(jī)上,在通過宿主機(jī)之間進(jìn)行通信。隨著docker?swarm集群的推廣,docker有了自己的跨主機(jī)通信的網(wǎng)絡(luò)驅(qū)動(dòng),名叫overlay,overlay網(wǎng)絡(luò)模型是swarm集群容器通信的載體,將服務(wù)加入到同一個(gè)網(wǎng)段的overlay網(wǎng)絡(luò)上,服務(wù)與服務(wù)之間就能夠通信。所以,Overlay網(wǎng)絡(luò)實(shí)際上是目前最主流的容器跨節(jié)點(diǎn)數(shù)據(jù)傳輸和路由方案。
? ? ?內(nèi)置跨主機(jī)的網(wǎng)絡(luò)通信一直是Docker備受期待的功能,在1.9版本之前,社區(qū)中就已經(jīng)有許多第三方的工具或方法嘗試解決這個(gè)問題,例如Macvlan、Pipework、Flannel、Weave等。雖然這些方案在實(shí)現(xiàn)細(xì)節(jié)上存在很多差異,但其思路無非分為兩種: 二層VLAN網(wǎng)絡(luò)和Overlay網(wǎng)絡(luò)
? ? ?簡單來說,二層VLAN網(wǎng)絡(luò)解決跨主機(jī)通信的思路是把原先的網(wǎng)絡(luò)架構(gòu)改造為互通的大二層網(wǎng)絡(luò),通過特定網(wǎng)絡(luò)設(shè)備直接路由,實(shí)現(xiàn)容器點(diǎn)到點(diǎn)的之間通信。這種方案在傳輸效率上比Overlay網(wǎng)絡(luò)占優(yōu),然而它也存在一些固有的問題。這種方法需要二層網(wǎng)絡(luò)設(shè)備支持,通用性和靈活性不如后者。由于通常交換機(jī)可用的VLAN數(shù)量都在4000個(gè)左右,這會(huì)對(duì)容器集群規(guī)模造成限制,遠(yuǎn)遠(yuǎn)不能滿足公有云或大型私有云的部署需求; 大型數(shù)據(jù)中心部署VLAN,會(huì)導(dǎo)致任何一個(gè)VLAN的廣播數(shù)據(jù)會(huì)在整個(gè)數(shù)據(jù)中心內(nèi)泛濫,大量消耗網(wǎng)絡(luò)帶寬,帶來維護(hù)的困難。相比之下,Overlay網(wǎng)絡(luò)是指在不改變現(xiàn)有網(wǎng)絡(luò)基礎(chǔ)設(shè)施的前提下,通過某種約定通信協(xié)議,把二層報(bào)文封裝在IP報(bào)文之上的新的數(shù)據(jù)格式。這樣不但能夠充分利用成熟的IP路由協(xié)議進(jìn)程數(shù)據(jù)分發(fā);而且在Overlay技術(shù)中采用擴(kuò)展的隔離標(biāo)識(shí)位數(shù),能夠突破VLAN的4000數(shù)量限制支持高達(dá)16M的用戶,并在必要時(shí)可將廣播流量轉(zhuǎn)化為組播流量,避免廣播數(shù)據(jù)泛濫。
因此,Overlay網(wǎng)絡(luò)實(shí)際上是目前最主流的容器跨節(jié)點(diǎn)數(shù)據(jù)傳輸和路由方案。
按照實(shí)現(xiàn)原理即可分為直接路由方式、橋接方式(例如pipework)、Overlay隧道方式(如flannel、ovs+gre)等。
(1) 直接路由
通過在Docker主機(jī)上添加靜態(tài)路由實(shí)現(xiàn)跨宿主機(jī)通信:
容器在兩個(gè)跨主機(jī)進(jìn)行通信的時(shí)候,是使用overlay network這個(gè)網(wǎng)絡(luò)模式進(jìn)行通信;如果使用host也可以實(shí)現(xiàn)跨主機(jī)進(jìn)行通信,直接使用這個(gè)物理的ip地址就可以進(jìn)行通信。overlay它會(huì)虛擬出一個(gè)網(wǎng)絡(luò)比如10.0.2.3這個(gè)ip地址。在這個(gè)overlay網(wǎng)絡(luò)模式里面,有一個(gè)類似于服務(wù)網(wǎng)關(guān)的地址,然后把這個(gè)包轉(zhuǎn)發(fā)到物理服務(wù)器這個(gè)地址,最終通過路由和交換,到達(dá)另一個(gè)服務(wù)器的ip地址。
?
實(shí)驗(yàn):
如下圖所示,我們有兩個(gè)物理主機(jī)1和主機(jī)2,我們?cè)谒拗鳈C(jī)上啟動(dòng)一個(gè)centos容器,啟動(dòng)成功之后,兩個(gè)容器分別運(yùn)行在兩個(gè)宿主機(jī)上,默認(rèn)的IP地址分配如圖所示。這也是docker自身的默認(rèn)網(wǎng)絡(luò)。
此時(shí)兩臺(tái)主機(jī)上的Docker容器可以通過各自主機(jī)中添加路由的方式來實(shí)現(xiàn)兩個(gè)centos容器之間的通信。由于使用容器的IP進(jìn)行路由,就需要便面不同主機(jī)上的容器使用相同的IP,為此我們應(yīng)該為不同的主機(jī)分配不同的子網(wǎng)來保證。于是我們構(gòu)造兩個(gè)容器之間通信的路由方案:
各項(xiàng)配置如下:
-
主機(jī)1的IP地址為:192.168.72.130
-
主機(jī)2的IP地址為:192.168.72.137
-
為主機(jī)1上的Docker容器分配的子網(wǎng):10.0.128.0/24
-
為主機(jī)2上的Docker容器分配的子網(wǎng):10.0.129.0/24
這樣配置之后,兩惡搞主機(jī)山過的Docker容器就肯定不會(huì)使用相同的IP地址從而避免了IP沖突。之后我們需要定義路由規(guī)則: -
所有目的地址為10.0.128.0/24的包都被轉(zhuǎn)發(fā)到主機(jī)1上
-
所有目的地址為10.0.129.0/24的包都被轉(zhuǎn)發(fā)到主機(jī)2上
綜上所述:數(shù)據(jù)包在兩個(gè)容器間的通信過程如下:
從主機(jī)1的容器發(fā)往主機(jī)2的容器的數(shù)據(jù)包,首先發(fā)往container1的網(wǎng)關(guān)docker0,然后通過查找主機(jī)1的路由得知需要將數(shù)據(jù)包發(fā)給主機(jī)2,數(shù)據(jù)包到達(dá)主機(jī)2后再轉(zhuǎn)發(fā)給主機(jī)2的docker0,最后將器數(shù)據(jù)包轉(zhuǎn)發(fā)到container1里,反向原理相同。
實(shí)驗(yàn)環(huán)境:
操作系統(tǒng) | 服務(wù)器地址 | container地址 |
---|---|---|
centos7 | 192.168.72.130 | 10.0.128.2 |
centos7 | 192.168.91.137 | 10.0.129.2 |
由于docker默認(rèn)的網(wǎng)關(guān)地址為172.17.0.0/24,我們需要配置兩臺(tái)主機(jī)的網(wǎng)段必須為10.0.128.2和10.0.129.2。有2種方式:
?1)?將兩臺(tái)主機(jī)的ip地址改為靜態(tài)ip地址
修改docker0的默認(rèn)網(wǎng)段
修改方式有兩種:
1、創(chuàng)建一個(gè)docker網(wǎng)橋
主機(jī)1:
[root@localhost ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33
BOOTPROTO=static
ONBOOT=yes
IPADDR=192.168.72.130
NETMASK=255.255.255.0
GATEWAY=192.168.72.2
DNS1=114.114.114.114
:wq
[root@localhost ~]# systemctl restart network
主機(jī)2:
[root@localhost ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33
BOOTPROTO=static
ONBOOT=yes
IPADDR=192.168.72.137
NETMASK=255.255.255.0
GATEWAY=192.168.72.2
DNS1=114.114.114.114
:wq
[root@localhost ~]# systemctl restart network
2) 修改docker0的默認(rèn)網(wǎng)段
修改方式有兩種:
1、創(chuàng)建一個(gè)docker網(wǎng)橋文章來源:http://www.zghlxwxcb.cn/news/detail-477431.html
主機(jī)1:
docker network create --driver bridge --subnet 10.0.128.0/24 --gateway=10.0.128.1 mynetwork
主機(jī)2:
docker network create --driver bridge --subnet 10.0.129.0/24 --gateway=10.0.129.1 mynetwork
2.修改docker0的網(wǎng)段(我們選用這種)文章來源地址http://www.zghlxwxcb.cn/news/detail-477431.html
1、編輯 /etc/docker/daemon.json
主機(jī)1:
{
"bip":"10.0.128.1/24"
}
:wq
主機(jī)2:
{
"bip":"10.0.129.1/24"
}
2、將我們?cè)O(shè)置的參數(shù)生效并重啟docker
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl start docker
3、查看兩個(gè)主機(jī)的IP地址是否改變。
主機(jī)1:
[root@localhost ~]# ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 10.0.128.1 netmask 255.255.255.0 broadcast 10.128.0.255
ether 02:42:3c:c9:45:0d txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
主機(jī)2:
[root@localhost ~]# ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 10.0.129.1 netmask 255.255.255.0 broadcast 10.129.0.255
ether 02:42:e2:09:e3:ec txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
?2)?添加路由規(guī)則
1.查看路由表
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.72.2 0.0.0.0 UG 100 0 0 ens33
10.128.0.0 0.0.0.0 255.255.255.0 U 0 0 0 docker0
192.168.72.0 0.0.0.0 255.255.255.0 U 100 0 0 ens33
默認(rèn)只有自己本身的路由,如果需要訪問10.0.129.0/24網(wǎng)段,需要添加路由。
2.添加路由規(guī)則
2.1.主機(jī)1添加路由規(guī)則
route add -net 10.0.129.0/24 gw 192.168.72.137
gw表示下一跳地址,這里的地址就是主機(jī)2的IP地址
2.2.主機(jī)2添加路由規(guī)則
route add -net 10.0.128.0/24 gw 192.168.72.130
2.3路由持久化(防止主機(jī)重啟路由丟失)
vi /etc/rc.local
主機(jī)1:route add -net 10.0.129.0/24 gw 192.168.72.137
主機(jī)2:route add -net 10.0.128.0/24 gw 192.168.72.130
3.進(jìn)行ping測試
主機(jī)1ping主機(jī)2
[root@localhost ~]# ping 10.0.129.1
PING 10.0.129.1 (10.0.129.1) 56(84) bytes of data.
64 bytes from 10.0.129.1: icmp_seq=1 ttl=64 time=0.852 ms
64 bytes from 10.0.129.1: icmp_seq=2 ttl=64 time=4.89 ms
64 bytes from 10.0.129.1: icmp_seq=3 ttl=64 time=1.28 ms
主機(jī)2ping主機(jī)1
[root@localhost ~]# ping 10.0.128.1
PING 10.0.128.1 (10.0.128.1) 56(84) bytes of data.
64 bytes from 10.0.128.1: icmp_seq=1 ttl=64 time=0.824 ms
到了這里,關(guān)于Docker跨主機(jī)網(wǎng)絡(luò)通信的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!