Docker網絡通信

1. Docker網絡模式

Docker在創建容器時有四種網絡模式,bridge爲默認不需要用--net=bridge去指定,其他三種模式需要在創建容器時使用--net去指定。

Docker安裝後,會自動創建三個網絡,分別爲bridge、host、none。可以使用以下命令查看:

ycy@ubuntu18:~$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
349d6173c6e8        bridge              bridge              local
738ff1fb9923        host                host                local
1abb3c2c9846        none                null                local

1.1 bridge模式

默認情況下,創建一個新的容器都會自動連接到bridge網絡,相當於Vmware中的Nat模式。

新建容器有獨立的網絡命名空間,並通過以下步驟將容器接入docker0中。

(1)創建veth pari虛擬網絡對(類似於網線的兩頭);

(2)將veth pair的一端置於主機的root network namespace中,並將其關聯docker0;

(3)將veth pair的另一端置於新建容器的網絡命名空間中;

(4)從docker0所在的子網中選一個可用的IP地址賦予veth pair在容器的一端。

ycy@ubuntu18:~$ docker run -d --name s1 nginx
f5e8a999d00b06d9d95ecf732c81fbf1ff6b29b5707ed0868304d7c40567cd80

ycy@ubuntu18:~$ docker inspect -f "{{ .NetworkSettings.IPAddress }}" s1
172.17.0.2

ycy@ubuntu18:~$ brctl show
bridge name	bridge id		STP enabled	interfaces
docker0		8000.02422bc4b451	no		veth392e4b4

1.2 host模式

相當於Vmware中的橋接模式。新建容器與宿主機共享網絡命名空間,該容器不會連接到docker0中,直接使用網絡的網絡資源進行通信。

ycy@ubuntu18:~$ docker run -it --name v1 --network host nginx /bin/bash
root@ubuntu18:/# ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:2bff:fec4:b451  prefixlen 64  scopeid 0x20<link>
        ether 02:42:2b:c4:b4:51  txqueuelen 0  (Ethernet)
        RX packets 25018  bytes 1093724 (1.0 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 30033  bytes 185103642 (176.5 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.146.100  netmask 255.255.255.0  broadcast 192.168.146.255
        inet6 fe80::badd:42b1:f38b:bf0f  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:9e:08:65  txqueuelen 1000  (Ethernet)
        RX packets 231221  bytes 282634477 (269.5 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 72539  bytes 6474630 (6.1 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 6118  bytes 534681 (522.1 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 6118  bytes 534681 (522.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

1.3 none模式

新建容器有獨立的網絡namespace,但是不會配置任何網絡參數,也不會接入docker0中,用戶可對其進行任意的手動配置。

ycy@ubuntu18:~$ docker run -it --name net-none --network none mynginx /bin/bash
root@65fed235fdcb:/# ifconfig
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        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

1.4 container模式

新建容器與一個已有的容器共享network namespace,該容器不會連接到docker0中,直接使用已有容器的網絡資源進行通信。

joined容器是一種較爲特別的網絡模式

在容器創建時使用--network=container:name(name是運行的容器名)

處在這個模式下的Docker容器會共享一個網絡棧,這樣兩個容器可以使用localhost高效快速通信。

ycy@ubuntu18:~$ docker run -it --name s1 mynginx /bin/bash
root@da6f3ecc0391:/# ifconfig     
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 21  bytes 2682 (2.6 KiB)
        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

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        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

root@da6f3ecc0391:/# ycy@ubuntu18:~$ 
ycy@ubuntu18:~$ docker run -it --name s2 --network container:s1 mynginx /bin/bash
root@da6f3ecc0391:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 25  bytes 3036 (2.9 KiB)
        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

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        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

1.5 用戶自定義網絡模式

Docker提供了三種自定義網絡驅動:bridge、overlay、macvlan。

bridge驅動類似於默認的bridge網絡模式,但增加了一些新的功能(帶DNS解析功能),overllay和macvlan適用於創建跨主機網絡。

創建橋接網絡

ycy@ubuntu18:~$ docker network create -d bridge --subnet 172.20.0.0/24 --gateway 172.20.0.1 br0
a765c3af4c5220534638e542d8dfa10e45e0e89c6d6f83820d0232339b35e3c7

創建bridge網絡後,可以看到新增了一個網橋(172.20.0.1)。

ycy@ubuntu18:~$ ip a | grep br-
19: br-a765c3af4c52: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    inet 172.20.0.1/24 brd 172.20.0.255 scope global br-a765c3af4c52

2. Docker網絡通信

 

2.1 同一宿主機不同網橋間的容器間的通信

創建兩個自定義網絡

ycy@ubuntu18:~$ docker network create -d bridge --subnet 172.20.0.0/24 --gateway 172.20.0.1 br0
f8eb445161aa2291a1f89ee7879c2825e7c9a556b1f400f78181b62f8f9ff570

ycy@ubuntu18:~$ docker network create -d bridge --subnet 172.21.0.0/24 --gateway 172.21.0.1 br1
65c9dd48d5b57d70c845fd4ce1a287cd7d4c864a6b641560efb71049ffbf4a05

創建兩個測試容器,分別加入創建的網絡

ycy@ubuntu18:~$ docker run -it -d --name s0 --network br0 --ip 172.20.0.100 nginx /bin/bash
e28178cb59210b488efdf00519d135609664957fd2ee32cbd28a9119ea4f566b

ycy@ubuntu18:~$ docker run -it -d --name s1 --network br1 --ip 172.21.0.100 nginx /bin/bash
1afbf57debaa8a7150243cabcebaf9628d10c328cec1c8992379f01713f80d91

將當前容器加入到需要與之通信的網絡

ycy@ubuntu18:~$ docker network connect br1 s0
ycy@ubuntu18:~$ docker container attach s0

測試網絡連接

root@e28178cb5921:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.20.0.100  netmask 255.255.255.0  broadcast 172.20.0.255
        ether 02:42:ac:14:00:64  txqueuelen 0  (Ethernet)
        RX packets 26  bytes 3106 (3.0 KiB)
        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

eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.21.0.2  netmask 255.255.255.0  broadcast 172.21.0.255
        ether 02:42:ac:15:00:02  txqueuelen 0  (Ethernet)
        RX packets 19  bytes 2462 (2.4 KiB)
        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

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        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.2 跨主機容器間的通信

2.2.1 macvlan

  • macvlan網絡容器接口直接與主機網卡連接,無需NAT或端口映射。
  • macvlan會獨佔主機網卡,但可以使用vlan子接口實現多macvlan網絡。
  • macvlan網絡在二層上是隔離的,所以不同macvlan網絡的容器是不能通信的。
  • 可以在三層上通過網關將macvlan網絡聯通起來。
  • docker本身不做任何限制,像傳統vlan網絡那樣管理即可。

網卡開啓混雜模式

[root@CentOS7 ~]# ip link set ens37 promisc on    

創建macvlan網絡
使用-d macvlan創建macvlan網絡,使用-o parent指定流量在docker主機上實際通過的物理接口  

[root@CentOS7 ~]# docker network create -d macvlan --subnet 172.20.0.0/24 --gateway 172.20.0.1 -o parent=ens37 macvlan1
8a36aca364caeff25642c843fc0d3064bd74a60985545954b59e0b8bc3218d3f

開啓一個橋接macvlan的容器

[root@CentOS7 ~]# docker run -it --name s0 --network macvlan1 --ip 172.20.0.100 docker.io/centos
[root@e5519dccc6f2 /]#

另一個虛擬機也做類似配置

ycy@ubuntu18:~$ sudo ip link set ens38 promisc on

ycy@ubuntu18:~$ docker network create -d macvlan --subnet 172.20.0.0/24 --gateway 172.20.0.1 -o parent=ens38 macvlan1
9042e03b3242184498fc6ca2afae7953f776ec299ba8d05f21b1bbf240b32e71

ycy@ubuntu18:~$ docker run -it --name s1 --network macvlan1 --ip 172.20.0.200 nginx
root@8f8c30548017:/#

測試網絡連通性

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章