四、Docker网络-容器间通信之Bridge模式 - 图1

创建两个容器

  1. $ docker container run -d --rm --name box1 busybox /bin/sh -c "while true; do sleep 3600; done"
  2. $ docker container run -d --rm --name box2 busybox /bin/sh -c "while true; do sleep 3600; done"
  3. $ docker container ls
  4. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  5. 4f3303c84e53 busybox "/bin/sh -c 'while t…" 49 minutes ago Up 49 minutes box2
  6. 03494b034694 busybox "/bin/sh -c 'while t…" 49 minutes ago Up 49 minutes box1

容器间通信

两个容器都连接到了一个叫 docker0Linux bridge

  1. $ docker network ls
  2. NETWORK ID NAME DRIVER SCOPE
  3. 1847e179a316 bridge bridge local
  4. a647a4ad0b4f host host local
  5. fbd81b56c009 none null local
  6. $ docker network inspect bridge
  7. [
  8. {
  9. "Name": "bridge",
  10. "Id": "1847e179a316ee5219c951c2c21cf2c787d431d1ffb3ef621b8f0d1edd197b24",
  11. "Created": "2021-07-01T15:28:09.265408946Z",
  12. "Scope": "local",
  13. "Driver": "bridge",
  14. "EnableIPv6": false,
  15. "IPAM": {
  16. "Driver": "default",
  17. "Options": null,
  18. "Config": [
  19. {
  20. "Subnet": "172.17.0.0/16",
  21. "Gateway": "172.17.0.1"
  22. }
  23. ]
  24. },
  25. "Internal": false,
  26. "Attachable": false,
  27. "Ingress": false,
  28. "ConfigFrom": {
  29. "Network": ""
  30. },
  31. "ConfigOnly": false,
  32. "Containers": {
  33. "03494b034694982fa085cc4052b6c7b8b9c046f9d5f85f30e3a9e716fad20741": {
  34. "Name": "box1",
  35. "EndpointID": "072160448becebb7c9c333dce9bbdf7601a92b1d3e7a5820b8b35976cf4fd6ff",
  36. "MacAddress": "02:42:ac:11:00:02",
  37. "IPv4Address": "172.17.0.2/16",
  38. "IPv6Address": ""
  39. },
  40. "4f3303c84e5391ea37db664fd08683b01decdadae636aaa1bfd7bb9669cbd8de": {
  41. "Name": "box2",
  42. "EndpointID": "4cf0f635d4273066acd3075ec775e6fa405034f94b88c1bcacdaae847612f2c5",
  43. "MacAddress": "02:42:ac:11:00:03",
  44. "IPv4Address": "172.17.0.3/16",
  45. "IPv6Address": ""
  46. }
  47. },
  48. "Options": {
  49. "com.docker.network.bridge.default_bridge": "true",
  50. "com.docker.network.bridge.enable_icc": "true",
  51. "com.docker.network.bridge.enable_ip_masquerade": "true",
  52. "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
  53. "com.docker.network.bridge.name": "docker0",
  54. "com.docker.network.driver.mtu": "1500"
  55. },
  56. "Labels": {}
  57. }
  58. ]

Note brctl 使用前需要安装, 对于CentOS, 可以通过 sudo yum install -y bridge-utils 安装;对于Ubuntu, 可以通过 sudo apt-get install -y bridge-utils

  1. $ brctl show
  2. bridge name bridge id STP enabled interfaces
  3. docker0 8000.0242759468cf no veth8c9bb82
  4. vethd8f9afb

容器对外通信

查看路由

  1. $ ip route
  2. default via 10.0.2.2 dev eth0 proto dhcp metric 100
  3. 10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15 metric 100
  4. 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
  5. 192.168.200.0/24 dev eth1 proto kernel scope link src 192.168.200.10 metric 101

iptable 转发规则

  1. $ sudo iptables --list -t nat
  2. Chain PREROUTING (policy ACCEPT)
  3. target prot opt source destination
  4. DOCKER all -- anywhere anywhere ADDRTYPE match dst-type LOCAL
  5. Chain INPUT (policy ACCEPT)
  6. target prot opt source destination
  7. Chain OUTPUT (policy ACCEPT)
  8. target prot opt source destination
  9. DOCKER all -- anywhere !loopback/8 ADDRTYPE match dst-type LOCAL
  10. Chain POSTROUTING (policy ACCEPT)
  11. target prot opt source destination
  12. MASQUERADE all -- 172.17.0.0/16 anywhere
  13. Chain DOCKER (2 references)
  14. target prot opt source destination
  15. RETURN all -- anywhere anywhere

端口转发

创建容器

  1. $ docker container run -d --rm --name web -p 8080:80 nginx
  2. $ docker container inspect --format '{{.NetworkSettings.IPAddress}}' web
  3. $ docker container run -d --rm --name client busybox /bin/sh -c "while true; do sleep 3600; done"
  4. $ docker container inspect --format '{{.NetworkSettings.IPAddress}}' client
  5. $ docker container exec -it client wget http://172.17.0.2

查看iptables的端口转发规则

  1. [vagrant@docker-host1 ~]$ sudo iptables -t nat -nvxL
  2. Chain PREROUTING (policy ACCEPT 10 packets, 1961 bytes)
  3. pkts bytes target prot opt in out source destination
  4. 1 52 DOCKER all -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
  5. Chain INPUT (policy ACCEPT 9 packets, 1901 bytes)
  6. pkts bytes target prot opt in out source destination
  7. Chain OUTPUT (policy ACCEPT 2 packets, 120 bytes)
  8. pkts bytes target prot opt in out source destination
  9. 0 0 DOCKER all -- * * 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
  10. Chain POSTROUTING (policy ACCEPT 4 packets, 232 bytes)
  11. pkts bytes target prot opt in out source destination
  12. 3 202 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0
  13. 0 0 MASQUERADE tcp -- * * 172.17.0.2 172.17.0.2 tcp dpt:80
  14. Chain DOCKER (2 references)
  15. pkts bytes target prot opt in out source destination
  16. 0 0 RETURN all -- docker0 * 0.0.0.0/0 0.0.0.0/0
  17. 1 52 DNAT tcp -- !docker0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 to:172.17.0.2:80

参考资料

https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/4/html/Security_Guide/s1-firewall-ipt-fwd.html