一、理解Docker0

  • 容器运行时如果没有指定网络模式,那么就默认是桥接模式的docker0

    1、测试

  • 三个网络:

image.png

2、问题

  • docker是如何处理容器网络访问的?

image.png

  1. 创建一个名为tomcat02的容器
  2. [root@VM-0-15-centos ~]# docker run -d -P --name tomcat02 tomcat
  3. a3be14a249d91c1103bb949f9db477f7332dbe3d5545e96c4106a17a10101bca
  4. #查看容器的内网IP,发现容器启动的时候会得到一个 eth0@if87 IP地址,这是docker分配的
  5. [root@VM-0-15-centos ~]# docker exec -it tomcat02 ip addr
  6. 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
  7. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  8. inet 127.0.0.1/8 scope host lo
  9. valid_lft forever preferred_lft forever
  10. 86: eth0@if87: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
  11. link/ether 02:42:ac:12:00:06 brd ff:ff:ff:ff:ff:ff link-netnsid 0
  12. inet 172.18.0.6/16 brd 172.18.255.255 scope global eth0
  13. valid_lft forever preferred_lft forever
  14. #思考。本机能否ping通docker容器内部。答案是能,因为在同一网段
  15. [root@VM-0-15-centos ~]# ping 172.18.0.6
  16. PING 172.18.0.6 (172.18.0.6) 56(84) bytes of data.
  17. 64 bytes from 172.18.0.6: icmp_seq=1 ttl=64 time=0.094 ms
  18. 64 bytes from 172.18.0.6: icmp_seq=2 ttl=64 time=0.055 ms
  19. 64 bytes from 172.18.0.6: icmp_seq=3 ttl=64 time=0.051 ms
  20. 64 bytes from 172.18.0.6: icmp_seq=4 ttl=64 time=0.053 ms
  21. ^C
  22. --- 172.18.0.6 ping statistics ---
  23. 4 packets transmitted, 4 received, 0% packet loss, time 2999ms
  24. rtt min/avg/max/mdev = 0.051/0.063/0.094/0.018 ms

3、原理

  • 我们每启动一个docker容器,docker就会给容器分配一个IP,我们只要安装了docker,就会有一个网卡docker0,使用的模式是桥接模式,使用的技术是veth-pair技术
  • 比如启动tomcat2容器后,再次查看IP,可以发现多了个网卡

image.png

  • 再启动tomcat03容器,查看容器IP和本机IP,发现又多了一对网卡

image.png
image.png

  • 我们发现这个容器的网卡都是一对一对的
  • evth-pair就是一对一的虚拟接口,它们都是成对出现的,一端连着协议,一端彼此相连。正因为有这个特性,evth-pair充当一座桥梁,连接各种虚拟网络设备。Openstack,Docker容器之间的连接,OVS的连接,都是使用evth-pair技术
  • 我们来测试一下tomcat02和tomcat03是否可以ping通

    1. # tomcat02 ping tomcat03,能够ping通
    2. [root@VM-0-15-centos ~]# docker exec -it tomcat02 ping 172.18.0.7
    3. PING 172.18.0.7 (172.18.0.7) 56(84) bytes of data.
    4. 64 bytes from 172.18.0.7: icmp_seq=1 ttl=64 time=0.115 ms
    5. 64 bytes from 172.18.0.7: icmp_seq=2 ttl=64 time=0.068 ms
    6. 64 bytes from 172.18.0.7: icmp_seq=3 ttl=64 time=0.058 ms
    7. 64 bytes from 172.18.0.7: icmp_seq=4 ttl=64 time=0.065 ms
    8. ^C
    9. --- 172.18.0.7 ping statistics ---
    10. 4 packets transmitted, 4 received, 0% packet loss, time 1002ms
    11. rtt min/avg/max/mdev = 0.058/0.076/0.115/0.024 ms
  • 绘制一张网络模型图

image.png

  • 结论:所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用IP

    4、小结

    image.png

  • Docker中所有的网络接口都是虚拟的。虚拟的转法效率高!

  • 只要容器stop或者删除,那对应网桥对就没了

    二、容器互联—link

  • 思考一个场景,我们编写了一个微服务,database url=ip:,项目不重启,数据库IP换掉了,我们希望可以处理这个问题,可以名字来访问容器,那该怎么做? ```shell

    尝试直接ping容器名,ping不通

    [root@VM-0-15-centos ~]# docker exec -it tomcat02 ping tomcat03 ping: tomcat03: Name or service not known

通过—link可以解决

启动tomcat4,并关联tomcat03,tomcat04可以通过直接ping容器名 tomcat03 ping通

[root@VM-0-15-centos ~]# docker run -d -P —name tomcat04 —link tomcat03 tomcat aa09aa2dbd2425f5e54fa89259069f82523c821ebec865ad452238d7ad8f9fd5 [root@VM-0-15-centos ~]# docker exec -it tomcat04 ping tomcat03 PING tomcat03 (172.18.0.7) 56(84) bytes of data. 64 bytes from tomcat03 (172.18.0.7): icmp_seq=1 ttl=64 time=0.114 ms 64 bytes from tomcat03 (172.18.0.7): icmp_seq=2 ttl=64 time=0.065 ms 64 bytes from tomcat03 (172.18.0.7): icmp_seq=3 ttl=64 time=0.065 ms 64 bytes from tomcat03 (172.18.0.7): icmp_seq=4 ttl=64 time=0.065 ms ^C —- tomcat03 ping statistics —- 4 packets transmitted, 4 received, 0% packet loss, time 1002ms rtt min/avg/max/mdev = 0.065/0.077/0.114/0.022 ms

但是反向ping,tomcat03无法直接通过ping容器名ping通

[root@VM-0-15-centos ~]# docker exec -it tomcat03 ping tomcat04 ping: tomcat04: Name or service not known

  1. - 查看tomcat04的/etc/hosts文件
  2. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/2893488/1630856398994-b8392a92-ac97-4b6a-a721-46fabf2804a9.png#clientId=u4047ceef-f67e-4&from=paste&height=180&id=u35b85acd&margin=%5Bobject%20Object%5D&name=image.png&originHeight=212&originWidth=666&originalType=binary&ratio=1&size=21135&status=done&style=none&taskId=u83bdf764-e361-41b1-8d6d-d967629b9d5&width=567)
  3. - 查看tomcat03的/etc/hosts文件
  4. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/2893488/1630856442394-15c8f656-8d37-4f97-bdf9-f6ef3eb5c515.png#clientId=u4047ceef-f67e-4&from=paste&height=153&id=u3232f28c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=196&originWidth=725&originalType=binary&ratio=1&size=21383&status=done&style=none&taskId=uaa1f2770-2c88-41bd-a1ab-06253730fce&width=564.5)
  5. - --link就是在hosts配置中增加了一条解析
  6. - 不推荐使用--linkdocker0问题:它不支持容器名直接访问
  7. <a name="tmWvy"></a>
  8. # 三、自定义网络
  9. - 自定义的网络完善了docker0不支持容器名访问的缺点和--link不能相互ping通的缺点,只要是在同一自定义网络下,都能直接通过容器名相互ping
  10. - 查看所有的docker网络:`**docker network ls**`
  11. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/2893488/1630860163028-808b75e5-4e7d-4d70-bcb7-ab7148683b02.png#clientId=u4047ceef-f67e-4&from=paste&height=154&id=udfe0f0fe&margin=%5Bobject%20Object%5D&name=image.png&originHeight=130&originWidth=460&originalType=binary&ratio=1&size=12433&status=done&style=none&taskId=u8d84cca3-6fc9-42d3-b8bd-1072effea9c&width=544)
  12. <a name="cGzHx"></a>
  13. ## 1、网络模式
  14. ```shell
  15. bridge:桥接(默认,自己创建也使用bridge模式)
  16. none:不配置网络
  17. host:和宿主机共享网络
  18. container:容器网络连通(用的少,局限性大)

2、测试

  1. # 我们直接启动的命令 --net bridge,而这个就是我们的docker0
  2. docker run -d -P --name tomcat02 tomcat
  3. 等价于
  4. docker run -d -P --name tomcat02 --net bridge tomcat
  5. # docker0特点:默认,容器名不能访问,--link可以打通连接
  6. #我们可以用create命令自定义一个网络
  7. # --driver bridge(默认)
  8. # --subnet 192.168.0.0/16(子网掩码)
  9. # --gateway 192.168.0.1(网关)
  10. [root@VM-0-15-centos ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
  11. b93f7bc668c46baa7657025e029f13022c8c529e33b2eec1a73d2e29cd4af340
  12. # ls命令查看网络,我们自己的网络创建好了
  13. [root@VM-0-15-centos ~]# docker network ls
  14. NETWORK ID NAME DRIVER SCOPE
  15. 115a2351052d bridge bridge local
  16. a8299a5d2f22 host host local
  17. b93f7bc668c4 mynet bridge local #(mynet网络创建成功)
  18. 431f88da42b1 none null local
  19. # inspect命令查看meynet网络信息
  20. [root@VM-0-15-centos ~]# docker network inspect mynet
  21. [
  22. {
  23. "Name": "mynet",
  24. "Id": "b93f7bc668c46baa7657025e029f13022c8c529e33b2eec1a73d2e29cd4af340",
  25. "Created": "2021-09-06T00:59:48.490085063+08:00",
  26. "Scope": "local",
  27. "Driver": "bridge",
  28. "EnableIPv6": false,
  29. "IPAM": {
  30. "Driver": "default",
  31. "Options": {},
  32. "Config": [
  33. {
  34. "Subnet": "192.168.0.0/16",
  35. "Gateway": "192.168.0.1"
  36. }
  37. ]
  38. },
  39. "Internal": false,
  40. "Attachable": false,
  41. "Ingress": false,
  42. "ConfigFrom": {
  43. "Network": ""
  44. },
  45. "ConfigOnly": false,
  46. "Containers": {},
  47. "Options": {},
  48. "Labels": {}
  49. }
  50. ]
  51. # 设置网络模式为自己创建的网络mynet,建立tomcat-net-01和tomcat-net-02
  52. [root@VM-0-15-centos ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
  53. e067a02080bb5ad3bf38496c5cb5f5a6274ac3e67d3ec378106485e3c98ad470
  54. [root@VM-0-15-centos ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
  55. 830a53b87c0758aa8c985195b83b63f4e2dbebdb5e99b5bba5a39ca349a12650
  56. # inspect命令查看meynet网络信息,可以看到多了两个对应的新加入的container(容器)
  57. [root@VM-0-15-centos ~]# docker network inspect mynet
  58. [root@VM-0-15-centos ~]# docker network inspect mynet
  59. [
  60. {
  61. "Name": "mynet",
  62. "Id": "b93f7bc668c46baa7657025e029f13022c8c529e33b2eec1a73d2e29cd4af340",
  63. "Created": "2021-09-06T00:59:48.490085063+08:00",
  64. "Scope": "local",
  65. "Driver": "bridge",
  66. "EnableIPv6": false,
  67. "IPAM": {
  68. "Driver": "default",
  69. "Options": {},
  70. "Config": [
  71. {
  72. "Subnet": "192.168.0.0/16",
  73. "Gateway": "192.168.0.1"
  74. }
  75. ]
  76. },
  77. "Internal": false,
  78. "Attachable": false,
  79. "Ingress": false,
  80. "ConfigFrom": {
  81. "Network": ""
  82. },
  83. "ConfigOnly": false,
  84. "Containers": {
  85. "830a53b87c0758aa8c985195b83b63f4e2dbebdb5e99b5bba5a39ca349a12650": {
  86. "Name": "tomcat-net-02",
  87. "EndpointID": "d86423260674d0300b6d1da749c5dad721683966b1d4bc59e714a317c60c7df9",
  88. "MacAddress": "02:42:c0:a8:00:03",
  89. "IPv4Address": "192.168.0.3/16",
  90. "IPv6Address": ""
  91. },
  92. "e067a02080bb5ad3bf38496c5cb5f5a6274ac3e67d3ec378106485e3c98ad470": {
  93. "Name": "tomcat-net-01",
  94. "EndpointID": "c182a6883d2c0f19137f5085dce4415a4eaf49d5e04cc1775a84f0e0f2482995",
  95. "MacAddress": "02:42:c0:a8:00:02",
  96. "IPv4Address": "192.168.0.2/16",
  97. "IPv6Address": ""
  98. }
  99. },
  100. "Options": {},
  101. "Labels": {}
  102. }
  103. ]
  104. # 自定义的网络完善了docker0不支持容器名访问的缺点和--link不能相互ping通的缺点,只要是在同一自定义网络下,都能直接通过容器名相互ping通
  105. [root@VM-0-15-centos ~]# docker exec -it tomcat-net-01 ping 192.168.0.3
  106. PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
  107. 64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.096 ms
  108. 64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.071 ms
  109. [root@VM-0-15-centos ~]# docker exec -it tomcat-net-02 ping 192.168.0.2
  110. PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
  111. 64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.084 ms
  112. 64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.064 ms

四、网络连通

image.png
image.png

测试

  1. # 尝试用tomcat01 ping tomcat-net-01,ping不通,因为网络没有连通
  2. [root@VM-0-15-centos ~]# docker exec -it tomcat01 ping tomcat-net-01
  3. ping: tomcat-net-01: Name or service not known
  4. # 将tomcat01加入到网络mynet中
  5. [root@VM-0-15-centos ~]# docker network connect mynet tomcat01
  6. # 查看mynet的信息,可以看到tomcat01加入了mynet,并有了个IPv4地址:192.168.0.4/16
  7. [root@VM-0-15-centos ~]# docker network inspect mynet

image.png

  1. # 相当于给tomcat01一块新的网卡,这块网卡选择加入mynet中
  2. [root@VM-0-15-centos ~]# docker exec -it tomcat01 ip addr

image.png

  1. # 本机IP信息
  2. [root@VM-0-15-centos ~]# ip addr

image.png

  1. # tomcat01可以ping通tomcat-net-01了
  2. [root@VM-0-15-centos ~]# docker exec -it tomcat01 ping tomcat-net-01
  3. PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
  4. 64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.081 ms
  5. 64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.065 ms
  6. 64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.066 ms
  • 网络模型

image.png

五、实战