背景说明

容器网络实质上也是由Docker为应用程序所创造的虚拟环境的一部分,它能让应用从宿主机操作系统的网络环境中独立出来,形成容器自有的网络设备、IP协议栈、端口套接字、IP路由表、防火墙等等与网络相关的模块,Docker默认提供了多种网络模式。

  1. [root@vm2 ~]# docker info -f {{.Plugins.Network}}
  2. [bridge host ipvlan macvlan null overlay]
  3. [root@vm2 ~]#

解决方案

官方文档

https://docs.docker.com/network/

模式查看

Docker安装的时候默认会创建三个不同的网络。

  1. [root@vm2 ~]# docker network ls
  2. NETWORK ID NAME DRIVER SCOPE
  3. 801380e310dd bridge bridge local
  4. 4a5006c650f6 host host local
  5. a027c870d158 none null local
  6. [root@vm2 ~]#

无网模式

通过参数—network=none指定

  1. [root@vm2 ~]# docker run --network=none -it centos
  2. [root@bc43c569cfa7 /]# ip addr
  3. 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
  4. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  5. inet 127.0.0.1/8 scope host lo
  6. valid_lft forever preferred_lft forever
  7. [root@bc43c569cfa7 /]#
  8. [root@bc43c569cfa7 /]# ping 192.168.184.142
  9. connect: Network is unreachable

采用此种模式,容器内部只能使用loopback网络设备,无法和其他设备进行网络通信,此时容器是一个封闭容器,不参与网络通信可以有效保证容器的安全性。

后期可以通过相关命令将容器添加到已有的自定义网络中

主机模式

通过参数—network=host指定,使用主机网络模式时,容器网络将直接绑定到主机网络上,没有网络隔离,但是其他文件系统、进程列表等均进行了隔离,外界可以直接访问容器。
image.png

容器复用主机的网络命名空间,其他独立与主机的。

  1. [root@vm2 ~]# ip addr
  2. 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
  3. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  4. inet 127.0.0.1/8 scope host lo
  5. valid_lft forever preferred_lft forever
  6. inet6 ::1/128 scope host
  7. valid_lft forever preferred_lft forever
  8. 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
  9. link/ether 00:0c:29:43:2c:2d brd ff:ff:ff:ff:ff:ff
  10. inet 192.168.184.142/24 brd 192.168.184.255 scope global noprefixroute dynamic ens33
  11. valid_lft 1616sec preferred_lft 1616sec
  12. inet6 fe80::1d72:8c06:652b:cc91/64 scope link tentative noprefixroute dadfailed
  13. valid_lft forever preferred_lft forever
  14. inet6 fe80::2452:200d:395f:968a/64 scope link noprefixroute
  15. valid_lft forever preferred_lft forever
  16. 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
  17. link/ether 02:42:e2:2f:29:69 brd ff:ff:ff:ff:ff:ff
  18. inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
  19. valid_lft forever preferred_lft forever
  20. [root@vm2 ~]# ip route
  21. default via 192.168.184.2 dev ens33 proto dhcp metric 100
  22. 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
  23. 192.168.184.0/24 dev ens33 proto kernel scope link src 192.168.184.142 metric 100
  24. [root@vm2 ~]# docker run -it --network=host centos /bin/bash
  25. [root@vm2 /]# ip addr
  26. 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
  27. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  28. inet 127.0.0.1/8 scope host lo
  29. valid_lft forever preferred_lft forever
  30. inet6 ::1/128 scope host
  31. valid_lft forever preferred_lft forever
  32. 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
  33. link/ether 00:0c:29:43:2c:2d brd ff:ff:ff:ff:ff:ff
  34. inet 192.168.184.142/24 brd 192.168.184.255 scope global dynamic noprefixroute ens33
  35. valid_lft 1583sec preferred_lft 1583sec
  36. inet6 fe80::1d72:8c06:652b:cc91/64 scope link dadfailed tentative noprefixroute
  37. valid_lft forever preferred_lft forever
  38. inet6 fe80::2452:200d:395f:968a/64 scope link noprefixroute
  39. valid_lft forever preferred_lft forever
  40. 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
  41. link/ether 02:42:e2:2f:29:69 brd ff:ff:ff:ff:ff:ff
  42. inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
  43. valid_lft forever preferred_lft forever
  44. [root@vm2 /]# ip route
  45. default via 192.168.184.2 dev ens33 proto dhcp metric 100
  46. 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
  47. 192.168.184.0/24 dev ens33 proto kernel scope link src 192.168.184.142 metric 100
  48. [root@vm2 /]#

分析如上命令主机网络地址:192.168.184.142/24,容器网络地址:192.168.184.142/24 注意进入容器后的命令前缀为: [root@vm2 /]# 主机和容器共享网络设备和路由表

尝试启动一个Nginx容器服务

  1. [root@vm2 ~]# docker run -d nginx
  2. 54a8cfcde386d48f61e3ba7bed0cd61e3371c3e24d7ebf6fec11c6c51ff0388a
  3. [root@vm2 ~]#
  4. [root@vm2 ~]# curl http://localhost:80
  5. curl: (7) Failed connect to localhost:80; Connection refused
  6. [root@vm2 ~]# docker ps
  7. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  8. 54a8cfcde386 nginx "/docker-entrypoint.…" 9 minutes ago Up 9 minutes 80/tcp awesome_brattain
  9. [root@vm2 ~]# docker exec 54a8 /bin/bash
  10. [root@vm2 ~]# docker exec -it 54a8 /bin/bash
  11. root@54a8cfcde386:/# curl http://localhost:80
  12. <!DOCTYPE html>
  13. <html>
  14. <head>
  15. <title>Welcome to nginx!</title>
  16. <style>
  17. html { color-scheme: light dark; }
  18. body { width: 35em; margin: 0 auto;
  19. font-family: Tahoma, Verdana, Arial, sans-serif; }
  20. </style>
  21. </head>
  22. <body>
  23. <h1>Welcome to nginx!</h1>
  24. <p>If you see this page, the nginx web server is successfully installed and
  25. working. Further configuration is required.</p>
  26. <p>For online documentation and support please refer to
  27. <a href="http://nginx.org/">nginx.org</a>.<br/>
  28. Commercial support is available at
  29. <a href="http://nginx.com/">nginx.com</a>.</p>
  30. <p><em>Thank you for using nginx.</em></p>
  31. </body>
  32. </html>
  33. root@54a8cfcde386:/#

端口没有进行映射时,无法通过主机IP进行访问,容器内部可以访问其端口

指定端口映射启动Nginx容器服务

  1. [root@vm2 ~]# docker run -d -p 8080:80 nginx
  2. ca4c47c41f4015f9150400a60d4460db3ed65d032197e3a72b5d903580ec8e46
  3. [root@vm2 ~]#
  4. [root@vm2 ~]# curl http://localhost:8080
  5. <!DOCTYPE html>
  6. <html>
  7. <head>
  8. <title>Welcome to nginx!</title>
  9. <style>
  10. html { color-scheme: light dark; }
  11. body { width: 35em; margin: 0 auto;
  12. font-family: Tahoma, Verdana, Arial, sans-serif; }
  13. </style>
  14. </head>
  15. <body>
  16. <h1>Welcome to nginx!</h1>
  17. <p>If you see this page, the nginx web server is successfully installed and
  18. working. Further configuration is required.</p>
  19. <p>For online documentation and support please refer to
  20. <a href="http://nginx.org/">nginx.org</a>.<br/>
  21. Commercial support is available at
  22. <a href="http://nginx.com/">nginx.com</a>.</p>
  23. <p><em>Thank you for using nginx.</em></p>
  24. </body>
  25. </html>
  26. [root@vm2 ~]#

指定端口映射可以正常访问容器服务

容器模式

容器模式并不是一个标准的容器网络类型,相当于多个容器共用一个网络命名空间,提供给一个网卡和docker0网桥进行通信。
image.png
创建docker1容器并查看网络地址

  1. [root@vm2 ~]# docker run -it -d --name docker1 centos
  2. 96af1b7a75efab993b224d02a82de610eac0aa511ef06b146da16f9d4a13fc1a
  3. [root@vm2 ~]# docker exec -it docker1 /bin/bash
  4. [root@96af1b7a75ef /]# ip addr
  5. 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
  6. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  7. inet 127.0.0.1/8 scope host lo
  8. valid_lft forever preferred_lft forever
  9. 8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
  10. link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0
  11. inet 172.17.0.4/16 brd 172.17.255.255 scope global eth0
  12. valid_lft forever preferred_lft forever
  13. [root@96af1b7a75ef /]#
  14. [root@96af1b7a75ef /]# ip route
  15. default via 172.17.0.1 dev eth0
  16. 172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.4
  17. [root@96af1b7a75ef /]#

创建docker2容器

[root@vm2 ~]# docker run -it --network=container:docker1 centos
[root@96af1b7a75ef /]# 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
8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.4/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
[root@96af1b7a75ef /]# 
[root@96af1b7a75ef /]# ip route
default via 172.17.0.1 dev eth0 
172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.4 
[root@96af1b7a75ef /]#

可以看到docker1和docker2使用的是同一个网络地址。docker2创建时不会创建新的网卡和命名空间复用docker1,并且共享端口范围,两个容器之间的网络交互使用lo回环设备进行交互。

网桥模式

通过参数—network=bridge指定,这里Docker的默认模式,在此模式下各容器拥有独立的网络空间,可以互相通过网络地址访问。
image.png

macvlan

MacVLAN使得容器网络和主机网络在同一个广播域,容器等同于真实的物理主机,是一种跨主机的网络通讯方案。

overlay

也叫覆盖网络或扁平化网络,容器之间可以直接通过容器网络地址进行访问。