13.Docker的四种网络模式

 

1. 概述

docker run创建Docker容器时,可以用–net选项指定容器的网络模式,Docker有以下4种网络模式: 

  1. bridge模式:使–net =bridge指定,默认设置; 
  2. host模式:使–net =host指定; 
  3. none模式:使–net =none指定; 
  4. container模式:使–net =container:[NAME]/[ID]指定。 

可以使用docker network ls来查看

1
2
3
4
5
[root@localhost docker]# docker network ls
NETWORK ID NAME DRIVER SCOPE
664654d9d382 bridge bridge local
de8b3d3fc85c host host local
60c1b99865c2 none null local

Docker四种网络模式

1. bridge模式

bridge模式是Docker默认的网络设置,此模式会为每一个容器分配Network Namespace、设置IP等,并将并将一个主机上的Docker容器连接到一个虚拟网桥上。当Docker server启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。接下来就要为容器分配IP了,Docker会从RFC1918所定义的私有IP网段中,选择一个和宿主机不同的IP地址和子网分配给docker0,连接到docker0的容器就从这个子网中选择一个未占用的IP使用。如一般Docker会使用172.17.0.0/16这个网段,并将172.17.42.1/16分配给docker0网桥(在主机上使用ip addr命令是可以看到docker0的,可以认为它是网桥的管理端口,在宿主机上作为一块虚拟网卡使用)。 

具体操作: 

启动容器:(由于是默认设置,这里没指定网络–net =bridge) 

1
2
[root@localhost docker]# docker run -it -d -p 8085:8080 5a915ec43999
f4c4e551ac9e9b3b9307cb2ecdc3e6661834580cb67b4a7f48c2192352ac7e35
1
2
3
[root@localhost docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f4c4e551ac9e 5a915ec43999 "catalina.sh run" 4 seconds ago Up 2 seconds 0.0.0.0:8085->8080/tcp dazzling_yalow

可以看到容器内创建了eth0,ip地址为172.17.0.2/16

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@localhost docker]# docker exec -it f4c4e551ac9e /bin/bash
root@f4c4e551ac9e:/usr/local/tomcat#
root@f4c4e551ac9e:/usr/local/tomcat# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe11:2/64 scope link
valid_lft forever preferred_lft forever

使用ping命令连接Host网络发现,容器与宿主机Host网络(192.168.88.128)是连通的: 

1
2
3
4
5
6
7
8
9
10
root@f4c4e551ac9e:/usr/local/tomcat# ping -c 4 192.168.88.128
PING 192.168.88.128 (192.168.88.128) 56(84) bytes of data.
64 bytes from 192.168.88.128: icmp_seq=1 ttl=64 time=0.090 ms
64 bytes from 192.168.88.128: icmp_seq=2 ttl=64 time=0.100 ms
64 bytes from 192.168.88.128: icmp_seq=3 ttl=64 time=0.105 ms
64 bytes from 192.168.88.128: icmp_seq=4 ttl=64 time=0.107 ms

--- 192.168.88.128 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 0.090/0.100/0.107/0.012 ms

eth0实际上是veth pair的一端,另一端(veth3b414b0)连接在docker0网桥上: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
[root@localhost docker]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:39:24:e4 brd ff:ff:ff:ff:ff:ff
inet 192.168.88.128/24 brd 192.168.88.255 scope global noprefixroute dynamic ens33
valid_lft 1628sec preferred_lft 1628sec
inet6 fe80::aff0:e07e:612b:e7e3/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:ba:b7:68 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:feba:b768/64 scope link
valid_lft forever preferred_lft forever
7: veth3b414b0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 5e:75:c4:e9:b4:27 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::5c75:c4ff:fee9:b427/64 scope link
valid_lft forever preferred_lft forever

root@f4c4e551ac9e:/usr/local/tomcat# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe11:2/64 scope link
valid_lft forever preferred_lft forever

2. host模式

如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。 

使用host模式启动容器:

1
2
[root@localhost docker]# docker run -it -d -P --net=host 5a915ec43999
f503c52dadeac150483df1f15d0ade48a0d182d94db9ee10154ee12ebe273c53
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@localhost docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f503c52dadea 5a915ec43999 "catalina.sh run" 5 seconds ago Up 4 seconds musing_meitner
[root@localhost docker]# docker exec -it f503c52dadea /bin/bash
root@localhost:/usr/local/tomcat#
root@localhost:/usr/local/tomcat# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:39:24:e4 brd ff:ff:ff:ff:ff:ff
inet 192.168.88.128/24 brd 192.168.88.255 scope global dynamic noprefixroute ens33
valid_lft 1784sec preferred_lft 1784sec
inet6 fe80::aff0:e07e:612b:e7e3/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:ac:ba:b7:68 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:feba:b768/64 scope link
valid_lft forever preferred_lft forever

使用host模式启动容器后可以发现,使用ip addr查看网络环境时,看到的都是宿主机上的信息。这种方式创建出来的容器,可以看到host上的所有网络设备。 

容器中,对这些设备有全部的访问权限。因此docker提示我们,这种方式是不安全的。如果在隔离良好的环境中(比如租户的虚拟机中)使用这种方式,问题不大。

例:创建一个host模式的tomcat容器

1
2
[root@localhost local]# docker run -it -d -p 8085:8080 --net=host 9715fb4d02ba
118ff6ac73fb2a77a18fedbba45b641ffa6aaeef87c4822ea0f7f1b3e2eb3c13
1
2
3
[root@localhost local]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
118ff6ac73fb 9715fb4d02ba "/bin/sh -c 'bin/s..." 6 seconds ago Up 3 seconds blissful_meitner

此时在浏览器访问http://192.168.168.130:8080/,无法访问,原因是防火墙处于开启状态。直接在宿主机中运行tomcat,宿主机防火墙处于开启状态,外部不能正常访问tomcat。而host模式容器和宿主机共用一个网络,如果宿主机防火墙处于开启状态,外部无法正常访问tomcat容器。

  • firewall-cmd --state: 查看防火墙状态
  • systemctl stop firewalld.service: 关闭防火墙
1
2
3
4
5
[root@localhost local]# firewall-cmd --state
running
[root@localhost local]# systemctl stop firewalld.service
[root@localhost local]# firewall-cmd --state
not running

此时在浏览器访问http://192.168.168.130:8080/,可以正常访问

systemctl start firewalld.service: 开启防火墙

1
2
3
[root@localhost local]# systemctl start firewalld.service
[root@localhost local]# firewall-cmd --state
running

3. none模式

在none模式下,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。 

使用--net =none模式启动容器: 

1
2
[root@localhost docker]# docker run -it -d -P --net=none 5a915ec43999
49ca234a222b6064065e782bd9a5bc7c86d9dacab0bfc84d316067a2c9bebd44
1
2
3
4
5
6
7
8
9
10
11
12
[root@localhost docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
49ca234a222b 5a915ec43999 "catalina.sh run" 4 seconds ago Up 2 seconds epic_leavitt
[root@localhost docker]# docker exec -it 49ca234a222b /bin/bash
root@49ca234a222b:/usr/local/tomcat#
root@49ca234a222b:/usr/local/tomcat# ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever

4. container模式

这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。 

使用--net =container模式启动容器:

1
2
3
4
5
[root@localhost docker]# docker run -it -d --name=centos-1 0d120b6ccaa8 
a1b466b807b9564636c945040d86112bb5e9ebdc7a1b1a0ada96af9006347805
[root@localhost docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1b466b807b9 0d120b6ccaa8 "/bin/bash" 3 seconds ago Up 2 seconds centos-1
1
2
3
4
5
6
[root@localhost docker]# docker run -it -d --name=tomcat-2 --net=container:centos-1 5a915ec43999
3fcb512e4eeac8219ed03869a670f05ad76f9ce2434e283227e67e7826ac866b
[root@localhost docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3fcb512e4eea 5a915ec43999 "catalina.sh run" 3 seconds ago Up 2 seconds tomcat-2
a1b466b807b9 0d120b6ccaa8 "/bin/bash" 3 minutes ago Up 3 minutes centos-1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@localhost docker]# docker exec -it centos-1 /bin/bash
[root@a1b466b807b9 /]#
[root@a1b466b807b9 /]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe11:2/64 scope link
valid_lft forever preferred_lft forever
[root@a1b466b807b9 /]# exit
exit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@localhost docker]# docker exec -it tomcat-2 /bin/bash
root@a1b466b807b9:/usr/local/tomcat#
root@a1b466b807b9:/usr/local/tomcat# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe11:2/64 scope link
valid_lft forever preferred_lft forever

通过该例子可以看出来,两者的网络完全相同。