Docker 自 1.12 版本之后提供了 docker network 来替代原来的 link 方式建立两个容器的连接。首先回顾下 link 使用方法:

  1. # 创建容器 test1
  2. $ docker run -d --name test1 nginx
  3. # 创建容器 test2并 link 到 test1。
  4. $ docker run -d --name test2 --link test1 nginx
  5. # 进入test2,并 ping test1,发现是可以 ping 通的。
  6. $ docker exec -it test2 /bin/sh
  7. # ping test1

作为对比,我们通过一些命令体会 network 的用法。

首先创建一个叫做 my-bridge 的网桥,使用的连接方式是 bridge

  1. $ docker network create -d bridge my-bridge

显示所有 networks,可以看到我们刚刚创建的 my-bridge 网络:

  1. $ docker network ls
  2. NETWORK ID NAME DRIVER SCOPE
  3. f769b043d559 bridge bridge local
  4. 99a1cc29b666 host host local
  5. 0b33d91b8999 my-bridge bridge local
  6. f29aea175ca8 none null local

然后创建和运行容器 nginx1 并添加到 my-bridge 网络中,然后使用 inspect 命令查看容器 nginx1 相关信息。

  1. $ docker run --name nginx1 --network my-bridge -p 8080:80 -d nginx:alpine
  2. $ docker inspect nginx1
  3. ... ...
  4. "Networks": {
  5. "my-bridge": {
  6. "Links": null,
  7. "Aliases": [
  8. "fab28aa9c54d"
  9. ],
  10. "Gateway": "172.19.0.1",
  11. "IPAddress": "172.19.0.2",
  12. ... ...
  13. }
  14. }
  15. ... ...

同理,你也可以通过 docker inspect my-bridge 会发现自建的 my-bridge 的 containers里面有 nginx1

  1. # 查看 my-bridge 网络里面的容器
  2. $ docker inspect my-bridge
  3. [
  4. {
  5. "Name": "my-bridge",
  6. "Id": "0b33d91b8999b18d221c80446c9f47bca1997bccab578d9bca0948f54f5afdac",
  7. ... ...
  8. "Containers": {
  9. "fab28aa9c54d4e931c155d3d8675c5741046dab69aa641b00bd36718bd06a060": {
  10. "Name": "nginx1",
  11. "EndpointID": "691339f0d007d73495bfda5d191a73008d2e5342686c823f2965d1fda71bab55",
  12. "MacAddress": "02:42:ac:13:00:02",
  13. "IPv4Address": "172.19.0.2/16",
  14. "IPv6Address": ""
  15. }
  16. },
  17. ... ...
  18. }
  19. ]

然后手动将某个容器加入网桥:

  1. $ docker run -d --name nginx2 nginx:alpine
  2. $ docker network connect my-bridge nginx2
  3. $ docker inspect my-bridge
  4. [
  5. {
  6. "Name": "my-bridge",
  7. ... ...
  8. "Containers": {
  9. "a0d25f38238388cb136a6db0501696056b39f95c6187ecc075df762e94502c26": {
  10. "Name": "nginx2",
  11. "EndpointID": "b0517695e75aae2cd6a6ca798e8e6907676a9e9504f7cafab8f5b67800f3412e",
  12. "MacAddress": "02:42:ac:13:00:03",
  13. "IPv4Address": "172.19.0.3/16",
  14. "IPv6Address": ""
  15. },
  16. "fab28aa9c54d4e931c155d3d8675c5741046dab69aa641b00bd36718bd06a060": {
  17. "Name": "nginx1",
  18. "EndpointID": "691339f0d007d73495bfda5d191a73008d2e5342686c823f2965d1fda71bab55",
  19. "MacAddress": "02:42:ac:13:00:02",
  20. "IPv4Address": "172.19.0.2/16",
  21. "IPv6Address": ""
  22. }
  23. },
  24. ... ...
  25. }
  26. ]

然后进入 nginx2 的 Shell 环境,在 Shell 中 ping nginx1 容器,可以看到端口是通的,IP 为 nginx1 的 IPv4Address - 172.19.0.2

  1. $ docker exec -it nginx2 sh
  2. # ping nginx1
  3. PING nginx1 (172.19.0.2): 56 data bytes
  4. 64 bytes from 172.19.0.2: seq=0 ttl=64 time=0.395 ms
  5. 64 bytes from 172.19.0.2: seq=1 ttl=64 time=0.109 ms
  6. ... ...

然后我们断开 nginx2my-bridge 连接,再尝试 ping 容器主机:

  1. $ docker network disconnect my-bridge nginx2
  2. $ docker exec -it nginx2 sh
  3. # ping nginx1
  4. ping: bad address 'nginx1'
  1. $ docker exec -it nginx1 cat /etc/hosts
  2. 127.0.0.1 localhost
  3. ... ...
  4. 172.19.0.2 fab28aa9c54d
  5. $ docker exec -it nginx2 cat /etc/hosts
  6. 127.0.0.1 localhost
  7. ... ...
  8. 172.19.0.3 a0d25f382383
  9. $ docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Names}}"
  10. CONTAINER ID IMAGE PORTS NAMES
  11. a0d25f382383 nginx:alpine 80/tcp nginx2
  12. fab28aa9c54d nginx:alpine 0.0.0.0:8080->80/tcp nginx1

参考