Docker的四种网络模式:
一. bridge模式(桥接模式,默认网络模式)
ocker网络隔离基于网络命名空间,在物理机上创建docker容器时会为每一个docker容器分配网络命名空间,并且把容器IP桥接到物理机的虚拟网桥上。
二. none模式(没有网络,只有本地回环)
此模式下创建容器是不会为容器配置任何网络参数的,如:容器网卡、IP、通信路由等,全部需要自己去配置。
三. host模式(和物理机共享同一个网络)
此模式创建的容器没有自己独立的网络命名空间,是和物理机共享一个Network Namespace,并且共享物理机的所有端口与IP,并且这个模式认为是不安全的。
四. container模式(用户自定义)
此模式和host模式很类似,只是此模式创建容器共享的是其他容器的IP和端口而不是物理机,此模式容器自身是不会配置网络和端口,创建此模式容器进去后,你会发现里边的IP是你所指定的那个容器IP并且端口也是共享的,而且其它还是互相隔离的,如进程等。
1.可以给容器指定IP
2.容器之间可以使用DNS通信。即使用主机名通信
查看当前有哪些网络:
[root@localhost docker-image]# docker network ls
NETWORK ID NAME DRIVER SCOPE
84b1ed78b104 bridge bridge local
43d4a6e7bfa1 host host local
98639a70d982 none null local
一、none网络
none网络没有网络,只有lo即本地地址,没有任何的网卡。创建容器时可以使用–network=none来指定none网络:
[root@localhost docker-image]# docker run -it --network none httpd sh
# ip a
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
# exit
[root@localhost docker-image]#
none网络的应用场景主要是用于对于安全性要求比较高的场景。
二、host网络
连接到host的网络的容器共享主机的网络栈,容器的网络配置与宿主机完全一样,创建容器时可以通过–network=host指定使用host网络:
[root@localhost docker-image]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest 020584afccce 11 days ago 1.22MB
httpd latest fb2f3851a971 18 months ago 178MB
[root@localhost docker-image]# docker run -it --network host httpd sh
# ip a
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: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:ca:f2:60 brd ff:ff:ff:ff:ff:ff
inet 192.168.59.200/24 brd 192.168.59.255 scope global noprefixroute ens32
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:feca:f260/64 scope link
valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 52:54:00:1e:82:2b brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000
link/ether 52:54:00:1e:82:2b brd ff:ff:ff:ff:ff:ff
5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:bc:03:4f:5f brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
6: br-bda2328dcf83: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:71:21:33:ca brd ff:ff:ff:ff:ff:ff
inet 172.18.0.1/16 brd 172.18.255.255 scope global br-bda2328dcf83
valid_lft forever preferred_lft forever
# exit
[root@localhost docker-image]# ip a
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: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:ca:f2:60 brd ff:ff:ff:ff:ff:ff
inet 192.168.59.200/24 brd 192.168.59.255 scope global noprefixroute ens32
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:feca:f260/64 scope link
valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 52:54:00:1e:82:2b brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000
link/ether 52:54:00:1e:82:2b brd ff:ff:ff:ff:ff:ff
5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:bc:03:4f:5f brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
6: br-bda2328dcf83: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:71:21:33:ca brd ff:ff:ff:ff:ff:ff
inet 172.18.0.1/16 brd 172.18.255.255 scope global br-bda2328dcf83
valid_lft forever preferred_lft forever
[root@localhost docker-image]#
直接使用主机的网络最大的好处就是性能,如果容器对网络传输效率有较高的要求,则可以选择宿主机的网络。但是需要考虑端口冲突的问题,宿主机已经使用的端口就不能再用了。
三、bridge网络
查看bridge网络详细信息:
[root@ken1 ~]# docker network inspect bridge
...
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
beidge网络配置的subnet就是172.17.0.0/16,并且网关是172.17.0.1,其实这个网关就是docker0。容器创建时,docker会自动从172.17.0.0/16中分配一个IP。
[root@localhost docker-image]# docker run -it httpd sh
# ip a
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
7: eth0@if8: <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
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
# exit
bridge原理:
1、docker安装时会创建一个docker0的linux brdge。如果不指定–network,创建的容器more都会挂到docker0上:
[root@ken1 ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.024259833389 no
virbr0 8000.525400da7083 yes virbr0-nic
2、当我们启动了一个容器,就会产生了一个新的网络接口vethd50e73c被挂到了docker0上,vethd50e73c就是新创建容器的虚拟网卡。
下面看一下容器的网络配置:
[root@localhost docker-image]# docker run -it httpd sh
# ip a
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
7: eth0@if8: <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
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
# exit
[root@localhost docker-image]# ip a
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: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:ca:f2:60 brd ff:ff:ff:ff:ff:ff
inet 192.168.59.200/24 brd 192.168.59.255 scope global noprefixroute ens32
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:feca:f260/64 scope link
valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 52:54:00:1e:82:2b brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000
link/ether 52:54:00:1e:82:2b brd ff:ff:ff:ff:ff:ff
5: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:bc:03:4f:5f brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:bcff:fe03:4f5f/64 scope link
valid_lft forever preferred_lft forever
6: br-bda2328dcf83: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:71:21:33:ca brd ff:ff:ff:ff:ff:ff
inet 172.18.0.1/16 brd 172.18.255.255 scope global br-bda2328dcf83
valid_lft forever preferred_lft forever
12: vethd50e73c@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 9a:4b:09:b4:78:28 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::984b:9ff:feb4:7828/64 scope link
valid_lft forever preferred_lft forever
3、使用ip a可以发现我们每启动一个容器相关的网卡信息也都会显示出来。容器有一个网卡eth0@if8,实际上eth0@if8和vethd50e73c是一对veth pair。veth pair是一种成对出现的椰树网络设备,可以把它想象成一根虚拟网线连接起来的一对网卡,网卡的一头(eth0@if8)在容器中,另一头(vethd50e73c)挂在docker0上,其效果就是将eth0@if8也挂在了docker0上。
4、当们创建一个容器后,docker0上interfaces处加入vethd50e73c:
[root@localhost docker-image]# brctl show
bridge name bridge id STP enabled interfaces
br-bda2328dcf83 8000.0242712133ca no
docker0 8000.0242bc034f5f no vethd50e73c
virbr0 8000.5254001e822b yes virbr0-nic
四: 自定义网络
除了none,host,bridge这三个自动创建的网络,用户也可以根据业务需要创建 user-defined 网络。
Docker 提供三种 user-defined 网络驱动:bridge, overlay 和 macvlan。overlay 和 macvlan 用于创建跨主机的网络
我们可通过 bridge 驱动创建类似前面默认的 bridge 网络,例如:
创建网络:
[root@localhost docker-image]# docker network create --subnet 192.59.56.0/24 --gateway 192.59.56.1 define
a688152e0ea8eee741673ab124d66a28b11ee09f7170d5cc9026341cb5f24db7
[root@localhost docker-image]# docker network ls
NETWORK ID NAME DRIVER SCOPE
84b1ed78b104 bridge bridge local
a688152e0ea8 define bridge local
bda2328dcf83 harbor_harbor bridge local
43d4a6e7bfa1 host host local
98639a70d982 none null local
创建容器时指定IP:
[root@localhost docker-image]# docker run -it --network define --ip 192.59.56.6 httpd sh
# ip a
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
17: eth0@if18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:c0:3b:38:06 brd ff:ff:ff:ff:ff:ff
inet 192.59.56.6/24 brd 192.59.56.255 scope global eth0
valid_lft forever preferred_lft forever
用户自定义网络使用主机名通信:
[root@localhost docker-image]# docker run -d -it --network define --name test2 --ip 192.59.56.7 httpd
[root@localhost docker-image]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dd0d2b588ca2 httpd "sh" 2 minutes ago Up About a minute 80/tcp test2
cefea823c404 httpd "sh" 7 minutes ago Up About a minute 80/tcp trusting_hawking
[root@localhost docker-image]# docker exec -it cefea823c404 sh
# ping test2
PING test2 (192.59.56.7) 56(84) bytes of data.
64 bytes from test2.define (192.59.56.7): icmp_seq=1 ttl=64 time=0.121 ms
64 bytes from test2.define (192.59.56.7): icmp_seq=2 ttl=64 time=0.125 ms
64 bytes from test2.define (192.59.56.7): icmp_seq=3 ttl=64 time=0.125 ms
...
注意:使用默认的网络模式是不能使用主机名进行通信的!
Docker DNS Server:
通过 IP 访问容器虽然满足了通信的需求,但还是不够灵活。因为我们在部署应用之前可能无法确定 IP,部署之后再指定要访问的 IP 会比较麻烦。对于这个问题,可以通过 docker 自带的 DNS 服务解决。docker daemon 实现了一个内嵌的 DNS server,使容器可以直接通过“容器名”通信。方法很简单,只要在启动时用 --name 为容器命名就可以了。
使用 docker DNS 有个限制:只能在 user-defined 网络中使用。也就是说,默认的 bridge 网络是无法使用 DNS 的。