1. 概述 docker run创建Docker容器时,可以用–net选项指定容器的网络模式,Docker有以下4种网络模式:
bridge模式:使–net =bridge指定,默认设置;
host模式:使–net =host指定;
none模式:使–net =none指定;
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
通过该例子可以看出来,两者的网络完全相同。