none 网络

none 网络即什么都没有的网络,挂在这个网络下的容器除了 io,没有其他任何网卡。容器创建时可以通过 —network=none 来指定使用 none 网络。

  1. root@Wangying:~# docker run -it --network=none ubuntu
  2. root@7b53475c58f8:/# ifconfig
  3. bash: ifconfig: command not found
  4. root@Wangying:~# docker run -it --network=none busybox
  5. Digest: sha256:caa382c432891547782ce7140fb3b7304613d3b0438834dce1cad68896ab110a
  6. / # ifconfig
  7. lo Link encap:Local Loopback
  8. inet addr:127.0.0.1 Mask:255.0.0.0
  9. UP LOOPBACK RUNNING MTU:65536 Metric:1
  10. RX packets:0 errors:0 dropped:0 overruns:0 frame:0
  11. TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
  12. collisions:0 txqueuelen:1000
  13. RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

封闭意味着隔离,一些对安全性要求较高并且不需要联网的应用就可以使用 none 网络。

host 网络

连接到 host 网络的容器共享 Docker host 的网格线,容器的网络配置与 host 完全一样,可以通过 —network=host 来指定使用 host 网络。

  1. root@Wangying:~# docker run -it --network=host busybox
  2. / # ip l
  3. 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
  4. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  5. 2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop qlen 1000
  6. link/ipip 0.0.0.0 brd 0.0.0.0
  7. 3: sit0@NONE: <NOARP> mtu 1480 qdisc noop qlen 1000
  8. link/sit 0.0.0.0 brd 0.0.0.0
  9. 4: services1@if5: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
  10. link/ether c6:31:69:cb:9d:e6 brd ff:ff:ff:ff:ff:ff
  11. 6: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel qlen 1000
  12. link/ether 02:50:00:00:00:01 brd ff:ff:ff:ff:ff:ff
  13. 7: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue
  14. link/ether 02:42:fb:8b:f4:82 brd ff:ff:ff:ff:ff:ff
  15. 15: veth36eebed@if14: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue master docker0
  16. link/ether 02:bb:66:77:a6:af brd ff:ff:ff:ff:ff:ff
  17. 17: veth4f04fad@if16: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue master docker0
  18. link/ether 26:66:d5:55:b1:75 brd ff:ff:ff:ff:ff:ff
  19. / # hostname
  20. docker-desktop
  1. 直接使用 Docker host 网络的最大好处是性能,如果容器对网络传输效率有较高要求,则可以选择 host 网络,不便之处就是牺牲一些灵活性,考虑端口问题,Docker host 上已经使用的端口就不能再用了。

另外一个用途是让容器可以直接配置 host 网络,比如某些跨 host 的网络解决方案,其本身也是以容器方式运行的,这些方案需要对网络进行配置,比如管理 ipables。

bridge 网络

Docker 安装时会安装一个命名为 docker0 的 Linux bridge。如果不指定 —network,创建的容器默认会挂到 docker0 上。

创建容器时,默认会为新容器创建虚拟网卡,容器内有对应的一个网卡,两个网卡形成一对 veth pair。veth pair 时一种成对出现的特殊网络设备,可以把它们想象成由一根虚拟网线连接起来的一对网卡,网卡的一头在容器中,另一头挂在网桥 docker0 上。

bridge 网络配置的 subnet 就是 172.17.0.0/16,并且网关是 172.17.0.1,这个网关就是 docker0 。创建容器时,docker 会自动从172.17.0.0/16 中分配一个 IP,这里16位的掩码保证有足够多个 IP 可以供容器使用。

容器之间通信

IP 通信

两个容器要能通信,必须有属于同一个网络的网卡。满足这个条件后,容器就可以通过IP交互了。具体做法是在容器创建时通过 —network 指定相应的网络,或者通过docker network connect 将现有容器加入到指定网络。

Docker DNS Server

通过 IP 访问容器虽然满足了通信的需求,但还是不够灵活。因为在部署应用之前可能无法确定 IP,部署之后再指定要访问的 IP 会比较麻烦。对于这个问题,可以通过 docker 自带的 DNS 服务解决。

  1. root@Wangying:~# docker run -it --network=my_net2 --name=bbox1 busybox
  2. root@Wangying:~# docker run -it --network=my_net2 --name=bbox2 busybox
  3. #进入 bbox2 就能够直接 ping 到 bbox1 了
  4. / # ping -c 3 bbox1
  5. PING bbox1 (172.22.16.2): 56 data bytes
  6. 64 bytes from 172.22.16.2: seq=0 ttl=64 time=0.563 ms
  7. 64 bytes from 172.22.16.2: seq=1 ttl=64 time=0.080 ms
  8. 64 bytes from 172.22.16.2: seq=2 ttl=64 time=0.052 ms
  9. --- bbox1 ping statistics ---
  10. 3 packets transmitted, 3 packets received, 0% packet loss
  11. round-trip min/avg/max = 0.052/0.231/0.563 ms

使用 docker DNS 有个限制,就是只能在 user-defined 网络中使用。也就是说,默认的 bridge 网络是无法使用 DNS 的。

  1. docker run -it --name bbox3
  2. docker run -it --name bbox4
  3. #进入到 bbox4,使用 IP 访问 bbox3
  4. / # ping -c 3 172.17.0.2
  5. PING 172.17.0.2 (172.17.0.2): 56 data bytes
  6. 64 bytes from 172.17.0.2: seq=0 ttl=64 time=6.015 ms
  7. 64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.055 ms
  8. 64 bytes from 172.17.0.2: seq=2 ttl=64 time=0.163 ms
  9. / # ping -c 3 bbox3
  10. ping: bad address 'bbox3'

joined 容器

joined 容器非常特别,它可以使两个或多个容器共享一个网络栈,共享网卡和配置信息,joined 容器之间可以通过127.0.0.1直接通信。

  1. #创建一个 httpd 容器,名字为 web1
  2. docker run -it --name=web1 httpd
  3. #创建 busybox 容器,通过 --network=container:web1 指定 joined 容器为 web1
  4. #分别查看两个容器的网络配置,可见两者 IP 地址一致。
  1. 该方式适用于一下场景:不同容器中的程序希望通过 lookback 高效快速通信,比如 Web Server App Server;希望监控其他容器的网络流量,比如运行在独立容器中的网络监控程序。