一、理解Docker0
2、问题
- docker是如何处理容器网络访问的?

创建一个名为tomcat02的容器[root@VM-0-15-centos ~]# docker run -d -P --name tomcat02 tomcata3be14a249d91c1103bb949f9db477f7332dbe3d5545e96c4106a17a10101bca#查看容器的内网IP,发现容器启动的时候会得到一个 eth0@if87 IP地址,这是docker分配的[root@VM-0-15-centos ~]# docker exec -it tomcat02 ip addr1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever86: eth0@if87: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group defaultlink/ether 02:42:ac:12:00:06 brd ff:ff:ff:ff:ff:ff link-netnsid 0inet 172.18.0.6/16 brd 172.18.255.255 scope global eth0valid_lft forever preferred_lft forever#思考。本机能否ping通docker容器内部。答案是能,因为在同一网段[root@VM-0-15-centos ~]# ping 172.18.0.6PING 172.18.0.6 (172.18.0.6) 56(84) bytes of data.64 bytes from 172.18.0.6: icmp_seq=1 ttl=64 time=0.094 ms64 bytes from 172.18.0.6: icmp_seq=2 ttl=64 time=0.055 ms64 bytes from 172.18.0.6: icmp_seq=3 ttl=64 time=0.051 ms64 bytes from 172.18.0.6: icmp_seq=4 ttl=64 time=0.053 ms^C--- 172.18.0.6 ping statistics ---4 packets transmitted, 4 received, 0% packet loss, time 2999msrtt min/avg/max/mdev = 0.051/0.063/0.094/0.018 ms
3、原理
- 我们每启动一个docker容器,docker就会给容器分配一个IP,我们只要安装了docker,就会有一个网卡docker0,使用的模式是桥接模式,使用的技术是veth-pair技术
- 比如启动tomcat2容器后,再次查看IP,可以发现多了个网卡

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


- 我们发现这个容器的网卡都是一对一对的
- evth-pair就是一对一的虚拟接口,它们都是成对出现的,一端连着协议,一端彼此相连。正因为有这个特性,evth-pair充当一座桥梁,连接各种虚拟网络设备。Openstack,Docker容器之间的连接,OVS的连接,都是使用evth-pair技术
我们来测试一下tomcat02和tomcat03是否可以ping通
# tomcat02 ping tomcat03,能够ping通[root@VM-0-15-centos ~]# docker exec -it tomcat02 ping 172.18.0.7PING 172.18.0.7 (172.18.0.7) 56(84) bytes of data.64 bytes from 172.18.0.7: icmp_seq=1 ttl=64 time=0.115 ms64 bytes from 172.18.0.7: icmp_seq=2 ttl=64 time=0.068 ms64 bytes from 172.18.0.7: icmp_seq=3 ttl=64 time=0.058 ms64 bytes from 172.18.0.7: icmp_seq=4 ttl=64 time=0.065 ms^C--- 172.18.0.7 ping statistics ---4 packets transmitted, 4 received, 0% packet loss, time 1002msrtt min/avg/max/mdev = 0.058/0.076/0.115/0.024 ms
绘制一张网络模型图

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

Docker中所有的网络接口都是虚拟的。虚拟的转法效率高!
-
二、容器互联—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
- 查看tomcat04的/etc/hosts文件- 查看tomcat03的/etc/hosts文件- --link就是在hosts配置中增加了一条解析- 不推荐使用--link。docker0问题:它不支持容器名直接访问<a name="tmWvy"></a># 三、自定义网络- 自定义的网络完善了docker0不支持容器名访问的缺点和--link不能相互ping通的缺点,只要是在同一自定义网络下,都能直接通过容器名相互ping通- 查看所有的docker网络:`**docker network ls**`<a name="cGzHx"></a>## 1、网络模式```shellbridge:桥接(默认,自己创建也使用bridge模式)none:不配置网络host:和宿主机共享网络container:容器网络连通(用的少,局限性大)
2、测试
# 我们直接启动的命令 --net bridge,而这个就是我们的docker0docker run -d -P --name tomcat02 tomcat等价于docker run -d -P --name tomcat02 --net bridge tomcat# docker0特点:默认,容器名不能访问,--link可以打通连接#我们可以用create命令自定义一个网络# --driver bridge(默认)# --subnet 192.168.0.0/16(子网掩码)# --gateway 192.168.0.1(网关)[root@VM-0-15-centos ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynetb93f7bc668c46baa7657025e029f13022c8c529e33b2eec1a73d2e29cd4af340# ls命令查看网络,我们自己的网络创建好了[root@VM-0-15-centos ~]# docker network lsNETWORK ID NAME DRIVER SCOPE115a2351052d bridge bridge locala8299a5d2f22 host host localb93f7bc668c4 mynet bridge local #(mynet网络创建成功)431f88da42b1 none null local# inspect命令查看meynet网络信息[root@VM-0-15-centos ~]# docker network inspect mynet[{"Name": "mynet","Id": "b93f7bc668c46baa7657025e029f13022c8c529e33b2eec1a73d2e29cd4af340","Created": "2021-09-06T00:59:48.490085063+08:00","Scope": "local","Driver": "bridge","EnableIPv6": false,"IPAM": {"Driver": "default","Options": {},"Config": [{"Subnet": "192.168.0.0/16","Gateway": "192.168.0.1"}]},"Internal": false,"Attachable": false,"Ingress": false,"ConfigFrom": {"Network": ""},"ConfigOnly": false,"Containers": {},"Options": {},"Labels": {}}]# 设置网络模式为自己创建的网络mynet,建立tomcat-net-01和tomcat-net-02[root@VM-0-15-centos ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcate067a02080bb5ad3bf38496c5cb5f5a6274ac3e67d3ec378106485e3c98ad470[root@VM-0-15-centos ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat830a53b87c0758aa8c985195b83b63f4e2dbebdb5e99b5bba5a39ca349a12650# inspect命令查看meynet网络信息,可以看到多了两个对应的新加入的container(容器)[root@VM-0-15-centos ~]# docker network inspect mynet[root@VM-0-15-centos ~]# docker network inspect mynet[{"Name": "mynet","Id": "b93f7bc668c46baa7657025e029f13022c8c529e33b2eec1a73d2e29cd4af340","Created": "2021-09-06T00:59:48.490085063+08:00","Scope": "local","Driver": "bridge","EnableIPv6": false,"IPAM": {"Driver": "default","Options": {},"Config": [{"Subnet": "192.168.0.0/16","Gateway": "192.168.0.1"}]},"Internal": false,"Attachable": false,"Ingress": false,"ConfigFrom": {"Network": ""},"ConfigOnly": false,"Containers": {"830a53b87c0758aa8c985195b83b63f4e2dbebdb5e99b5bba5a39ca349a12650": {"Name": "tomcat-net-02","EndpointID": "d86423260674d0300b6d1da749c5dad721683966b1d4bc59e714a317c60c7df9","MacAddress": "02:42:c0:a8:00:03","IPv4Address": "192.168.0.3/16","IPv6Address": ""},"e067a02080bb5ad3bf38496c5cb5f5a6274ac3e67d3ec378106485e3c98ad470": {"Name": "tomcat-net-01","EndpointID": "c182a6883d2c0f19137f5085dce4415a4eaf49d5e04cc1775a84f0e0f2482995","MacAddress": "02:42:c0:a8:00:02","IPv4Address": "192.168.0.2/16","IPv6Address": ""}},"Options": {},"Labels": {}}]# 自定义的网络完善了docker0不支持容器名访问的缺点和--link不能相互ping通的缺点,只要是在同一自定义网络下,都能直接通过容器名相互ping通[root@VM-0-15-centos ~]# docker exec -it tomcat-net-01 ping 192.168.0.3PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.096 ms64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.071 ms[root@VM-0-15-centos ~]# docker exec -it tomcat-net-02 ping 192.168.0.2PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.084 ms64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.064 ms
四、网络连通
测试
# 尝试用tomcat01 ping tomcat-net-01,ping不通,因为网络没有连通[root@VM-0-15-centos ~]# docker exec -it tomcat01 ping tomcat-net-01ping: tomcat-net-01: Name or service not known# 将tomcat01加入到网络mynet中[root@VM-0-15-centos ~]# docker network connect mynet tomcat01# 查看mynet的信息,可以看到tomcat01加入了mynet,并有了个IPv4地址:192.168.0.4/16[root@VM-0-15-centos ~]# docker network inspect mynet

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

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

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


