溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Docker之網(wǎng)絡(luò)管理(容器間通信的配置)

發(fā)布時間:2020-05-07 08:33:10 來源:網(wǎng)絡(luò) 閱讀:1266 作者:warrent 欄目:云計(jì)算

博文大綱:

  • 一、Bridge模式(同一臺Docker服務(wù)器上容器間的通信)
  • 二、部署consul服務(wù)實(shí)現(xiàn)Docker容器跨主機(jī)通信

前言:

當(dāng)你開始大規(guī)模使用Docker時,你會發(fā)現(xiàn)需要了解很多關(guān)于網(wǎng)絡(luò)的知識。Docker作為目前最火的輕量級容器技術(shù),有很多令人稱道的功能,如Docker的鏡像管理。然而,Docker同樣有著很多不完善的地方,網(wǎng)絡(luò)方面就是Docker比較薄弱的部分。因此,我們有必要深入了解Docker的網(wǎng)絡(luò)知識,以滿足更高的網(wǎng)絡(luò)需求。本文首先介紹了Docker自身的4種網(wǎng)絡(luò)工作方式,然后介紹一些自定義網(wǎng)絡(luò)模式。


我們安裝Docker時,它會自動創(chuàng)建三個網(wǎng)絡(luò),bridge(創(chuàng)建容器默認(rèn)連接到此網(wǎng)絡(luò))、 none 、host。

  • host:容器將不會虛擬出自己的網(wǎng)卡,配置自己的IP等,而是使用宿主機(jī)的IP和端口。
  • None:該模式關(guān)閉了容器的網(wǎng)絡(luò)功能,相當(dāng)于一個回環(huán)網(wǎng)絡(luò)。
  • Bridge:此模式會為每一個容器分配、設(shè)置IP等,并將容器連接到一個叫docker0的虛擬網(wǎng)橋,通過docker0網(wǎng)橋以及Iptables nat表配置與宿主機(jī)通信。
[root@docker ~]# docker network ls    #執(zhí)行該命令查看docker創(chuàng)建的網(wǎng)絡(luò)

關(guān)于上述提到的三個網(wǎng)絡(luò)解釋如下:

  • Host:相當(dāng)于Vmware中的橋接模式,與宿主機(jī)在同一個網(wǎng)絡(luò)中,但沒有獨(dú)立的IP地址。眾所周知,Docker使用了Linux的Namespaces技術(shù)來進(jìn)行資源隔離,如PID Namespace隔離進(jìn)程,Mount Namespace隔離文件系統(tǒng),Network Namespace隔離網(wǎng)絡(luò)等。一個Network Namespace提供了一份獨(dú)立的網(wǎng)絡(luò)環(huán)境,包括網(wǎng)卡、路由、Iptable規(guī)則等都與其他的Network Namespace隔離。一個Docker容器一般會分配一個獨(dú)立的Network Namespace。但如果啟動容器的時候使用host模式,那么這個容器將不會獲得一個獨(dú)立的Network Namespace,而是和宿主機(jī)共用一個Network Namespace。容器將不會虛擬出自己的網(wǎng)卡,配置自己的IP等,而是使用宿主機(jī)的IP和端口。基于Host模式啟動的容器,在容器內(nèi)執(zhí)行ifconfig時,看到的都是宿主機(jī)上的信息。該模式不夠靈活,容易出現(xiàn)端口沖突問題。
  • None:該模式將容器放置在它自己的網(wǎng)絡(luò)棧中,但是并不進(jìn)行任何配置。實(shí)際上,該模式關(guān)閉了容器的網(wǎng)絡(luò)功能,類似于會換地址,在以下兩種情況下是有用的:容器并不需要網(wǎng)絡(luò)(例如只需要寫磁盤卷的批處理任務(wù))。
  • overlay:顧名思義:覆蓋,但它又不是覆蓋,它的作用就是在容器原有的網(wǎng)絡(luò)基礎(chǔ)之上,再添加一塊網(wǎng)卡,并為其分配一個IP地址,可以將所有的docker容器關(guān)聯(lián)到同一個局域網(wǎng)中,適用于容器與容器是跨主機(jī)進(jìn)行通信的場景。
  • Bridge:相當(dāng)于Vmware中的NAT模式,容器使用獨(dú)立的network Namespace,并且連接到docker0虛擬網(wǎng)卡(默認(rèn)模式)。通過docker網(wǎng)橋以及IPtables nat表配置與宿主機(jī)通信;Bridge模式是Docker默認(rèn)的網(wǎng)絡(luò)設(shè)置,此模式會為每一個容器分配一個Network nameSpace、設(shè)置IP等,并將一個主機(jī)上的Docker容器連接到一個虛擬網(wǎng)橋docker0上。

在生產(chǎn)環(huán)境中,應(yīng)用的最多的就是Bridge模式和overlay模式了。這篇博文將圍繞著這兩個模式進(jìn)行介紹。

一、Bridge模式

當(dāng)Docker server啟動時,會在主機(jī)上創(chuàng)建一個名為docker0的虛擬網(wǎng)橋,此主機(jī)上啟動的Docker容器就會連接到這個虛擬網(wǎng)橋上。虛擬網(wǎng)橋的工作方式和物理交換機(jī)類似,這樣主機(jī)上的所有容器就通過交換機(jī)連在了一個二層網(wǎng)絡(luò)中,一般Docker會使用172.17.0.0/16這個網(wǎng)段,并將這個網(wǎng)段分配給docker0網(wǎng)橋使用(在主機(jī)上使用ifconfig命令可以看到docker0),然后為容器分配一個同網(wǎng)段的IP地址。

單機(jī)環(huán)境下的網(wǎng)絡(luò)拓?fù)淙缦拢ㄖ鳈C(jī)地址是10.10.0.186/24):

Docker之網(wǎng)絡(luò)管理(容器間通信的配置)

Docker 完成以上網(wǎng)絡(luò)配置的過程大致是這樣的:

  • 在主機(jī)上創(chuàng)建一對虛擬網(wǎng)卡veth pair設(shè)備。veth設(shè)備總是成對出現(xiàn)的,它們組成了一個數(shù)據(jù)的通道,數(shù)據(jù)從一個設(shè)備進(jìn)入,就會從另一個設(shè)備出來。因此,veth設(shè)備常用來連接兩個網(wǎng)絡(luò)設(shè)備。
  • Docker將veth pair設(shè)備的一端放在新創(chuàng)建的容器中,并命名為eth0。另一端放在主機(jī)中,以veth75f9這樣類似的名字命名,并將這個網(wǎng)絡(luò)設(shè)備加入到docker0網(wǎng)橋中,可以通過brctl show命令查看。
  • 從docker0子網(wǎng)中分配一個IP給容器使用,并設(shè)置docker0的IP地址為容器的默認(rèn)網(wǎng)關(guān)。

當(dāng)所有的容器都是基于默認(rèn)的docker0進(jìn)行創(chuàng)建的,那么拋開防火墻、IPtables等相關(guān)的設(shè)置外,理論上,各個容器是可以相互通信的,但是docker0這個網(wǎng)絡(luò)是系統(tǒng)自帶的,有些功能不能夠?qū)崿F(xiàn),并且不夠靈活。

其實(shí)我們也是可以自定義創(chuàng)建網(wǎng)絡(luò)的,并且可以指定其具體屬于哪個網(wǎng)段等。這是docker 0無法實(shí)現(xiàn)的,那么,如果各個容器,不是基于同一個網(wǎng)絡(luò)(如Docker0)創(chuàng)建的話,那么?如何使它們互通呢?

下面來一段配置,來看一下Bridge的工作模式。

實(shí)現(xiàn)的效果如下:

  • 基于docker0(docker的驅(qū)動名稱使bridge)網(wǎng)絡(luò)創(chuàng)建2個容器,分別是box1、box2。
  • 創(chuàng)建自定義網(wǎng)絡(luò),網(wǎng)絡(luò)類型為bridge,名稱為my_net1.基于此網(wǎng)絡(luò)創(chuàng)建兩個容器box3,box4(若不指定網(wǎng)段,會使用172.18.0.0/16這個網(wǎng)段,基于docker0增加一個網(wǎng)絡(luò)位)
  • 創(chuàng)建自定義網(wǎng)絡(luò),網(wǎng)絡(luò)類型為bridge,名稱為my_net2,指定網(wǎng)段為172.20.18.0/24,基于此網(wǎng)絡(luò)創(chuàng)建兩個容器box5(ip為172.20.18.6),box6(IP為172.20.18.8)。
  • 配置實(shí)現(xiàn)box2能夠和box3相互通信,box4和box5可以相互通信。
[root@docker ~]# docker run -itd --name box1 --network bridge busybox    
#創(chuàng)建一個容器box1,--network選項(xiàng)可以省略,默認(rèn)就是bridge,這里只是為了展示命令
[root@docker ~]# docker run -itd --name box2 --network bridge busybox   #同上,這里創(chuàng)建一個容器box2
[root@docker ~]# docker network create -d bridge my_net1    #創(chuàng)建一個橋接網(wǎng)絡(luò),名稱為my_net1
[root@docker ~]# docker run -tid --name box3 --network my_net1 busybox    #基于my_net1創(chuàng)建容器box3
[root@docker ~]# docker run -tid --name box4 --network my_net1 busybox   #同上,創(chuàng)建box4
[root@docker ~]# docker network create -d bridge --subnet 172.20.18.0/24 my_net2   #創(chuàng)建一個橋接網(wǎng)絡(luò)my_net2,并指定其網(wǎng)段
[root@docker ~]# docker run -tid --name box5 --network my_net2 --ip 172.20.18.6 busybox   
#基于my_net2網(wǎng)絡(luò),創(chuàng)建一個容器box5,并且指定其IP地址
[root@docker ~]# docker run -tid --name box6 --network my_net2 --ip 172.20.18.8 busybox    #同上
[root@docker ~]# docker network connect my_net1 box2      #將box2連接到my_net1這個網(wǎng)絡(luò)
[root@docker ~]# docker exec box2 ping box3   #進(jìn)行ping測試,可以發(fā)現(xiàn)box2可以ping通box3了。
#而如果沒有將box2連接到網(wǎng)絡(luò)my_net1,是絕對不會ping通的。
PING box3 (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.069 ms
64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.076 ms
[root@docker ~]# docker network connect my_net2 box4   #將box4連接到my_net2網(wǎng)絡(luò)
#同box2和box3的ping測試,若沒有將box4連接到box5所在的網(wǎng)絡(luò),是不可能ping通的。
[root@docker ~]# docker exec box5 ip a    #查看box5的IP地址
         .......................#省略部分內(nèi)容
16: eth0@if17: <BROADCAST,MULTICAST,UP,LO500 qdisc noqueue 
    link/ether 02:42:ac:14:12:06 brd ff:ff:ff:ff:ff:ff
    inet 172.20.18.6/24 brd 172.20.18.255 scope global eth0     #確認(rèn)其IP
       valid_lft forever preferred_lft forever
[root@docker ~]# docker exec box4 ping 172.20.18.6   #在box4容器上對box5的IP進(jìn)行ping測試,可以ping通
PING box5 (172.20.18.6): 56 data bytes
64 bytes from 172.20.18.6: seq=0 ttl=64 time=0.090 ms
64 bytes from 172.20.18.6: seq=1 ttl=64 time=0.130 ms

經(jīng)過以上配置,已經(jīng)實(shí)現(xiàn)了最終的效果,需要注意的是,我們完全可以將創(chuàng)建的my_net1、my_net2網(wǎng)絡(luò)驅(qū)動理解為一個交換機(jī),而執(zhí)行命令docker network connect my_net1 box2,則相當(dāng)于將box2這個容器添加了一塊網(wǎng)卡,然后連接到了my_net1這個交換機(jī),然后這個容器就多了一塊網(wǎng)卡,并且擁有my_net1這個交換機(jī)中IP地址。在上述的配置中,box2不但可以和box3進(jìn)行通信,也是可以和box4進(jìn)行通信的,因?yàn)樗鼈兌际沁B接在了my_net1這個“交換機(jī)”上。

注意:

  • 容器之間可以使用容器名進(jìn)行通信,但前提使用的是自定義的網(wǎng)絡(luò),如上面的my_net1、my_net2;
  • 如果在創(chuàng)建自定義網(wǎng)絡(luò)的同時,指定了該網(wǎng)絡(luò)的網(wǎng)段,那么,使用此網(wǎng)絡(luò)的容器也可以指定容器的IP地址,若沒有指定該網(wǎng)絡(luò)的網(wǎng)段,則不可以指定容器的IP地址。

二、部署consul服務(wù)實(shí)現(xiàn)Docker容器跨主機(jī)通信

consul:數(shù)據(jù)中心的含義,可以將其當(dāng)做數(shù)據(jù)庫來理解,類似于Redis等非關(guān)系型數(shù)據(jù)庫,采用的是鍵-值對的方式,存放著各個容器的IP及端口信息。

我對consul服務(wù)的了解也不是太多,若想要詳細(xì)了解此服務(wù),還是參考其他文檔吧,若以后有機(jī)會,我會詳細(xì)寫下來consul這個服務(wù)。

consul的功能很強(qiáng)大,可以以群集的方式運(yùn)行,并且具備健康監(jiān)測等功能。

下面開始配置consul服務(wù)。

1、環(huán)境準(zhǔn)備如下:

  • Docker服務(wù)器三臺,我這里的docker版本為18.09.0;
  • 第一臺Docker服務(wù)器的IP是192.168.20.7,其運(yùn)行consul服務(wù);
  • 后兩臺為測試端,只需要有docker環(huán)境即可。

若需要安裝部署Docker服務(wù)器,可以參考博文:Docker的安裝詳細(xì)配置 。

2、第一臺Docker服務(wù)器配置如下:

[root@docker ~]# docker pull progrium/consul          #下載consul鏡像
[root@docker ~]# docker run -d -p 8500:8500 -h consul --name consul --restart=always progrium/consul -server -bootstrap
#運(yùn)行consul容器,該服務(wù)的默認(rèn)端口是8500,“-p”:表示將容器的8500端口映射到宿主機(jī)的8500端口
#“-h”:表示consul的主機(jī)名;“--name consul”表示為該容器名;“--restart=always”表示可以隨著docker服務(wù)的啟動而啟動;
#“-serve -bootstarp”:表示當(dāng)在群集中,加上這兩個選項(xiàng)可以使其以master的身份出現(xiàn)
[root@docker ~]# netstat -anput | grep 8500   #確定8500端口在監(jiān)聽
tcp6       0      0 :::8500                 :::* 

OK,至此,單節(jié)點(diǎn)的consul服務(wù)就完成了,現(xiàn)在切換至第二臺Docker服務(wù)器。

3、第二臺Docker服務(wù)器配置如下:

[root@docker02 ~]# vim /usr/lib/systemd/system/docker.service  #編輯docker主配置文件
         ..............#省略部分內(nèi)容,搜索“Start”定位到下面配置行,修改如下:
ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376 --cluster-store=consul://192.168.20.7:8500 --cluster-advertise=ens33:2376
#各項(xiàng)解釋如下:
#/var/run/docker.sock:Docker的一個編程接口
# “ -H tcp://0.0.0.0:2376 ” :使用本機(jī)的tcp2376端口;
# “ --cluster-store=consul://192.168.20.7:8500”:指定運(yùn)行著consul服務(wù)的第一臺docker服務(wù)器IP及端口;
# “ --cluster-advertise=ens33:2376”:從本機(jī)的ens33網(wǎng)卡通過2376端口搜集網(wǎng)絡(luò)信息,存儲在consul上
#修改完成后,保存退出即可。
[root@docker02 ~]# systemctl daemon-reload    #重新加載配置文件
[root@docker02 ~]# systemctl restart docker    #重啟docker服務(wù)

4、然后在第三臺docker服務(wù)器上,進(jìn)行與第二臺Docker服務(wù)器一樣的配置操作,主要是為了指定consul服務(wù)的監(jiān)聽端口。(自行配置,這里就不寫了,記得更改完成后,重啟docker服務(wù))

5、現(xiàn)在使用瀏覽器訪問consul服務(wù)的web頁面(訪問:192.168.20.7:8500),如下:

Docker之網(wǎng)絡(luò)管理(容器間通信的配置)

Docker之網(wǎng)絡(luò)管理(容器間通信的配置)

即可看到用來測試的那兩臺docker服務(wù)器IP等相關(guān)信息,如下:
Docker之網(wǎng)絡(luò)管理(容器間通信的配置)

6、回到第二臺Docker服務(wù)器上,創(chuàng)建一個overlay網(wǎng)絡(luò):

[root@docker02 ~]# docker network create -d overlay my_olay         #創(chuàng)建一個名字為my_olay的voerlay網(wǎng)絡(luò) 

7、切換至第三臺Docker服務(wù)器上,發(fā)現(xiàn)可以看到剛剛在第二臺Docker服務(wù)器上創(chuàng)建的overlay網(wǎng)絡(luò):

[root@docker03 ~]# docker network ls     #查看docker03的網(wǎng)絡(luò),發(fā)現(xiàn)其不但有overlay網(wǎng)絡(luò),
#而且其SCOPE(范圍)是global(全局的)
NETWORK ID          NAME                DRIVER              SCOPE
8d5b00cf07ab        bridge              bridge              local
17c053a80f5a        host                host                local
c428fc28bb11        my_olay             overlay             global
323935eaa5c3        none                null                local

其實(shí),現(xiàn)在在第二臺Docker服務(wù)器上基于剛剛創(chuàng)建的overlay網(wǎng)絡(luò)運(yùn)行一個容器,在第三臺Docker服務(wù)器上也基于這個overlay網(wǎng)絡(luò)運(yùn)行一個容器,這兩個在不同主機(jī)上的容器是可以互通的,如下:

##################第二臺Docker服務(wù)器上配置如下:###########################
[root@docker02 ~]# docker run -tid --name web01 --network my_olay busybox    #基于網(wǎng)絡(luò)my_olay運(yùn)行一個容器web01
[root@docker02 ~]# docker exec web01 ip a         #查看其IP信息,發(fā)現(xiàn)其除了回環(huán)地址,還有兩個IP
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue 
    link/ether 02:42:0a:00:00:02 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.2/24 brd 10.0.0.255 scope global eth0     #這個地址就是my_olay給的
       valid_lft forever preferred_lft forever
11: eth2@if12: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.2/16 brd 172.18.255.255 scope global eth2  
       valid_lft forever preferred_lft forever
##################第三臺Docker服務(wù)器上配置如下:###########################
[root@docker03 ~]# docker run -tid --name web02 --network my_olay busybox     #基于網(wǎng)絡(luò)my_olay運(yùn)行一個容器web02
[root@docker03 ~]# docker exec web02 ip a     #查看web02的IP
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue 
    link/ether 02:42:0a:00:00:03 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.3/24 brd 10.0.0.255 scope global eth0            #這個地址就是my_olay給的
       valid_lft forever preferred_lft forever
11: eth2@if12: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.2/16 brd 172.18.255.255 scope global eth2
       valid_lft forever preferred_lft forever
#########在第二臺Docker服務(wù)器上對第三臺Docker服務(wù)器上的容器進(jìn)行ping測試##########
[root@docker02 ~]# docker exec web01 ping web02      #確定可以ping通
PING web02 (10.0.0.3): 56 data bytes
64 bytes from 10.0.0.3: seq=0 ttl=64 time=1.091 ms
64 bytes from 10.0.0.3: seq=1 ttl=64 time=1.007 ms

———————— 本文至此結(jié)束,感謝閱讀 ————————

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI