文章目录
1.初始docker网络
-
对于docker的网络是这样子的,我们只要安装了docker,就会有个自带的网卡docker0,是使用桥接模式,使用的技术是evth-pair技术。
-
evth-pair技术:就是一对的虚拟设备接口,都是成对出现的,一段连着协议,一段彼此连接,evth-pair 就像一个桥梁,连接各种虚拟网络设备。
我们可以先使用ip add 查看当前本机网络情况,有三个: lo:本地回环地址 ens33:本机地址 docker0:docker的地址(默认安装了docker就会有的) 或者使用 ip ifconfig查看本机网络情况,这个是中文的,应该比较好接受
-
现在我们启动一个容器并查看容器内的网络地址,以及本机的网络地址。
我们发现除了回环地址,出现了另一个地址,即容器启动的时候会得到一个eth0@if7 ip地址。这个eth0就是docker为我们分配的。
当我们启动好一个容器后,查看本机的网络情况的时候,惊奇的发现,本机再刚刚三个地址的基础上,多增加了一个地址。# 现在我们来研究一下 在新创建的容器中,出现的ip为 6:eth0@if7 在本地主机中,出现的ip为: 7:xxxxx@if6 这个就是evth-pair技术:就是一对的虚拟设备接口,都是成对出现的。注意:是成对出现的
-
我们尝试用linux主机去ping容器内部,看能否ping通?或者容器内部去ping linux主机,是否能ping通?
答案是可以相互ping通,毕竟都是在同一个网络段中。 -
我们再启动一个容器tomcat,在本机中还是会出现一个新的网络地址。现在我们思考一下,这个时候,两个容器tomcat是否可以ping的通,答案是可以的,因为在创建容器tomcat02的时候,分的ip 肯定也是在172.17.0.0这个网络段的。
-
下面是之前画的原理图:
tomcat01 和tomcat02 是公用的一个路由器 docker0,相当于本机充当一个桥一样,让两个容器之间可以ping通。
7. 总结:- 我们只要安装了docker,就会有一个网卡(docker0),网络模式为桥接模式,使用的是 evth-pair技术。
- 所有的容器不指定网络的情况下,都是docker0路由的,只要我们创建一个容器,docker会给我们的容器分配一个默认的可用ip,当然本机上也会多出一个ip,因为是成对出现的。
- 容器和linux主机可以ping通,而且每个容器之间也可以通过ip地址ping通。
2.容器互联 --link
-
这里提出一个问题,我们每次去访问的时候,都要记住ip:端口号很麻烦,加上一个应用如果重启之后,端口号可能会出现变化。比如说,你有个应用连接mysql容器,使用172.168.0.2:3306, 突然mysql宕机,换了一台电脑或者重启,有可能ip地址或者端口号出现变化,那么又要改这个ip地址去连接,实在太麻烦了。
-
所以,我们思考能否,我们去连接的时候,直接是以名字连接,什么意思,比如A—连接(ping)—B即 输入命令A ping B成功连接上,之后B换了地址,但是我 始终是输入命令A ping B也可以成功连接上。可能说不清,看下面例子。
-
容器互联 --link:使得容器之间不用ip地址 而是通过容器名字来访问。
# 创建一个新的容器tomcat03,并使用--link root@ubuntu:/home/mylinux# docker run -it -d -P --name=tomcat03 --link tomcat02 tomcat 633afbdfec2c25dd28e976be693798c210637eaa7b01175c4582eff17e785600 # 使用tomcat03 ping tomcat02 发现可以ping的通 root@ubuntu:/home/mylinux# docker exec -it tomcat03 ping tomcat02 PING tomcat02 (172.17.0.3) 56(84) bytes of data. 64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.985 ms 64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.204 ms 64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.137 ms ^C --- tomcat02 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 34ms rtt min/avg/max/mdev = 0.137/0.442/0.985/0.384 ms # 然后反向无法ping通,这是为什么呢,我们需要去了解link的原理 root@ubuntu:/home/mylinux# docker exec -it tomcat02 ping tomcat03 ping: tomcat03: Temporary failure in name resolution
-
我们需要去查看网络信息,使用
命令docker network ls
,可以查看当前有哪些网络。 -
docker network inspect 容器id
,则是查看一个容器内,网络的详细信息。
-
小知识:linux中对于网络映射关系的配置,是在/etc/hosts目录下的。接下来 分析link的本质。
root@ubuntu:/home/mylinux# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 633afbdfec2c tomcat "catalina.sh run" 8 minutes ago Up 8 minutes 0.0.0.0:32770->8080/tcp tomcat03 1117187a2ce0 tomcat "catalina.sh run" 22 minutes ago Up 22 minutes 0.0.0.0:32769->8080/tcp tomcat02 dceb805366a2 tomcat "catalina.sh run" 28 minutes ago Up 28 minutes 0.0.0.0:32768->8080/tcp tomcat01 # 查看tomcat3 中的hosts root@ubuntu:/home/mylinux# docker exec -it 633afbdfec2c cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.17.0.3 tomcat02 1117187a2ce0 #我们发现他把tomcat02 的容器id 容器名 都设置好映射了 #即 当我们ping tomcat02 相当于ping 172.17.0.3 172.17.0.4 633afbdfec2c #这是查看tomcat02的hosts 发现并没有 看见tomcat03的信息 root@ubuntu:/home/mylinux# docker exec -it 1117187a2ce0 cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.17.0.3 1117187a2ce0
7. 总结:
- –link本质就是在hosts配置中添加了一个 ip 容器名跟id 的映射关系。
- 而且是 单方向的配置。
3.自定义网络
-
从上面的link我们知道,现在是基本上可以通过ping容器名字就可以成功了,但是只是单方向的,主要是因为默认的docker0网络就是这样子设置的,没办法,这样子就很烦,因此,我们需要自己定义网络,这样子就可以相互通过名字ping的通了。
-
网络模式,有三种,一般使用bridge桥接模式
bridge:桥接模式
none:不配置网络
host:和宿主机共享网络
# 创建自定义网络 # docker network create --driver ‘模式' --subnet ip --gateway 网关 docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 my_test_net root@ubuntu:/home/mylinux# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 my_test_net ea1fbd0198e998cb0e13de42295e94dccbe38d4cee2d58fd2da6674913430d1c root@ubuntu:/home/mylinux# docker network ls NETWORK ID NAME DRIVER SCOPE 9fb218842ee2 bridge bridge local 9bd13e836b8f host host local # 自己创建的网络 ea1fbd0198e9 my_test_net bridge local a02cf1880d21 none null local # 查看刚刚创建网络的信息 root@ubuntu:/home/mylinux# docker network inspect ea1fbd0198e9 [ { "Name": "my_test_net", "Id": "ea1fbd0198e998cb0e13de42295e94dccbe38d4cee2d58fd2da6674913430d1c", "Created": "2020-12-01T07:04:25.179655834-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": {} } ]
测试
# 创建新的容器,并指定网络,如果不指定,则默认使用docker0的 root@ubuntu:/home/mylinux# docker run -it -d -P --name tomcat-01 --net my_test_net tomcat d708db4928986820ea85f473f4569ab6352894be6a86e8871a58d95ebc7381a2 root@ubuntu:/home/mylinux# docker run -it -d -P --name tomcat-02 --net my_test_net tomcat a7b31c4a2995f8617c19d57231f7eca7cfa4c4fbcc724e6853c56f0ec8536ee4 d^Hroot@ubuntu:/home/mylinux# root@ubuntu:/home/mylinux# docker ps 下面输出简化了,为了方便查看 CONTAINER ID IMAGE COMMAND NAMES a7b31c4a2995 tomcat "catalina.sh run" tomcat-02 d708db492898 tomcat "catalina.sh run" tomcat-01 #下面是相互ping的测试 root@ubuntu:/home/mylinux# docker exec -it a7b31c4a2995 ping tomcat-01 PING tomcat-01 (192.168.0.2) 56(84) bytes of data. 64 bytes from tomcat-01.my_test_net (192.168.0.2): icmp_seq=1 ttl=64 time=0.109 ms 64 bytes from tomcat-01.my_test_net (192.168.0.2): icmp_seq=2 ttl=64 time=0.271 ms ^C --- tomcat-01 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 3ms rtt min/avg/max/mdev = 0.109/0.190/0.271/0.081 ms root@ubuntu:/home/mylinux# docker exec -it d708db492898 ping tomcat-02 PING tomcat-02 (192.168.0.3) 56(84) bytes of data. 64 bytes from tomcat-02.my_test_net (192.168.0.3): icmp_seq=1 ttl=64 time=0.056 ms 64 bytes from tomcat-02.my_test_net (192.168.0.3): icmp_seq=2 ttl=64 time=0.213 ms 64 bytes from tomcat-02.my_test_net (192.168.0.3): icmp_seq=3 ttl=64 time=0.138 ms ^C --- tomcat-02 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 29ms rtt min/avg/max/mdev = 0.056/0.135/0.213/0.065 ms
下面我们再来查看新创建的网络。
我们发现新的内容,将刚刚创建的2个容器信息保存入内。
有兴趣的还可以进入两个新创建的容器中 查看 hosts。
3. 总结:
我们自定义的网络,docker都已经帮我们维护好了对应的关系,可以相互ping名字呢,推荐使用自定义。
4.不同网络段之间的交流
假设要跨网络操作别人,就需要使用docker network connect 网络 容器名
docker network connect my_test_net tomcat01
连通式直接将tomcat01的网络信息放在 my_test_net,
但是我们发现tomcat01的ip不应该是下面的样子,应该是172.17.0.2才对
其实就是让一个容器拥有两个ip地址。
# 测试
# 先建立关系,后执行下面
root@ubuntu:/home/mylinux# docker network connect my_test_net tomcat01
root@ubuntu:/home/mylinux# docker exec -it tomcat-02 ping tomcat01
PING tomcat01 (192.168.0.4) 56(84) bytes of data.
64 bytes from tomcat01.my_test_net (192.168.0.4): icmp_seq=1 ttl=64 time=0.136 ms
64 bytes from tomcat01.my_test_net (192.168.0.4): icmp_seq=2 ttl=64 time=0.215 ms
^C
--- tomcat01 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 5ms
rtt min/avg/max/mdev = 0.136/0.175/0.215/0.041 ms
root@ubuntu:/home/mylinux# docker exec -it tomcat01 ping tomcat-02
PING tomcat-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-02.my_test_net (192.168.0.3): icmp_seq=1 ttl=64 time=0.056 ms
64 bytes from tomcat-02.my_test_net (192.168.0.3): icmp_seq=2 ttl=64 time=0.126 ms
64 bytes from tomcat-02.my_test_net (192.168.0.3): icmp_seq=3 ttl=64 time=0.173 ms
^C
--- tomcat-02 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 7ms
rtt min/avg/max/mdev = 0.056/0.118/0.173/0.048 ms