docker网络
理解docker网络
清空所有环境
清空所有容器 [root@iZmu0fa4hv0jwzZ ~]# docker rm $(docker ps -aq) 清空所有镜像 [root@iZmu0fa4hv0jwzZ ~]# docker rmi -f $(docker images -aq)
docker如何处理容器网络访问
创建并运行tomcat容器
[root@iZmu0fa4hv0jwzZ ~]# docker run -d -p 3355:8080 --name tomcat01 tomcat Unable to find image 'tomcat:latest' locally latest: Pulling from library/tomcat d960726af2be: Pull complete e8d62473a22d: Pull complete 8962bc0fad55: Pull complete 65d943ee54c1: Pull complete da20b77f10ac: Pull complete 8669a096f083: Pull complete e0c0a5e9ce88: Pull complete f7f46169d747: Pull complete 215575e3a745: Pull complete 6b282851d654: Pull complete Digest: sha256:9f502a5c7bafd4e1953dba4e77f9347c9211f987902ab8668a34997178f9bcd0 Status: Downloaded newer image for tomcat:latest 89d9db666e9ee45bf39eebbaa3ce2db42821cd78f0db40931104c2ef65ffad70
查看容器内的ip信息
[root@iZmu0fa4hv0jwzZ ~]# docker exec -it tomcat01 ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 86: eth0@if87: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever
在主机上ping容器内部
[root@iZmu0fa4hv0jwzZ ~]# ping 172.17.0.2 PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data. 64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.060 ms 64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.058 ms 64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.054 ms 64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.040 ms 64 bytes from 172.17.0.2: icmp_seq=5 ttl=64 time=0.065 ms
发现可以ping通docker容器内部
原理
每启动一个docker容器,docker就会给docker容器分配一个ip,只要安装了docker,就会有一个网卡docker0
桥接模式,使用的技术是evth-pair技术
测试ip addr
[root@iZmu0fa4hv0jwzZ ~]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 00:16:3e:10:1d:f7 brd ff:ff:ff:ff:ff:ff inet 172.24.53.41/18 brd 172.24.63.255 scope global dynamic noprefixroute eth0 valid_lft 314004835sec preferred_lft 314004835sec inet6 fe80::216:3eff:fe10:1df7/64 scope link valid_lft forever preferred_lft forever 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:f1:84:df:a8 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::42:f1ff:fe84:dfa8/64 scope link valid_lft forever preferred_lft forever 87: veth0383d1f@if86: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether ca:f4:29:b9:36:a4 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet6 fe80::c8f4:29ff:feb9:36a4/64 scope link valid_lft forever preferred_lft forever
再启动一个容器测试
[root@iZmu0fa4hv0jwzZ ~]# docker run -d -p 3344:8080 --name tomcat02 tomcat 78fb1077cf49dd3094801987c85514b592724eee75ffae4d6d429aa1f6fde887 [root@iZmu0fa4hv0jwzZ ~]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 00:16:3e:10:1d:f7 brd ff:ff:ff:ff:ff:ff inet 172.24.53.41/18 brd 172.24.63.255 scope global dynamic noprefixroute eth0 valid_lft 314004538sec preferred_lft 314004538sec inet6 fe80::216:3eff:fe10:1df7/64 scope link valid_lft forever preferred_lft forever 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:f1:84:df:a8 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::42:f1ff:fe84:dfa8/64 scope link valid_lft forever preferred_lft forever 87: veth0383d1f@if86: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether ca:f4:29:b9:36:a4 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet6 fe80::c8f4:29ff:feb9:36a4/64 scope link valid_lft forever preferred_lft forever 89: veth1e9226d@if88: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether c2:9b:92:b8:d3:43 brd ff:ff:ff:ff:ff:ff link-netnsid 1 inet6 fe80::c09b:92ff:feb8:d343/64 scope link valid_lft forever preferred_lft forever
发现多了一个89
查看tomcat02的ip信息
[root@iZmu0fa4hv0jwzZ ~]# docker exec -it tomcat02 ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 88: eth0@if89: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever
我们可以发现这个容器带来的网卡,都是一对一对的
evth-pair 就是一对的虚拟设备接口,它们都是成对出现的,一段连着协议,一段彼此相连
正因为有这个特性,evth-pair 充当一个桥梁,连接各种虚拟网络设备
OpenStac Docker容器之间的连接,OVS的连接,都是使用evth-pair技术
测试tomcat01和tomcat02是否可以ping通
[root@iZmu0fa4hv0jwzZ ~]# docker exec -it tomcat02 ping 172.17.0.2 PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data. 64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.094 ms 64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.076 ms 64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.072 ms
结论:容器和容器之间是可以互相ping通的
结论:tomcat01和tomcat02是共用的一个路由器,docker0
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用ip
小结
docker使用的是Linux的桥接,宿主机中是一个docker容器的网桥 docker0
docker中所有的网络接口都是虚拟的,虚拟的转发效率高
删掉一个容器
[root@iZmu0fa4hv0jwzZ ~]# docker rm -f tomcat01 tomcat01 [root@iZmu0fa4hv0jwzZ ~]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 00:16:3e:10:1d:f7 brd ff:ff:ff:ff:ff:ff inet 172.24.53.41/18 brd 172.24.63.255 scope global dynamic noprefixroute eth0 valid_lft 314002233sec preferred_lft 314002233sec inet6 fe80::216:3eff:fe10:1df7/64 scope link valid_lft forever preferred_lft forever 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:f1:84:df:a8 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::42:f1ff:fe84:dfa8/64 scope link valid_lft forever preferred_lft forever 89: veth1e9226d@if88: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether c2:9b:92:b8:d3:43 brd ff:ff:ff:ff:ff:ff link-netnsid 1 inet6 fe80::c09b:92ff:feb8:d343/64 scope link valid_lft forever preferred_lft forever
说明只要容器删除,对应网桥一对就没了
--link
启动tomcat01
[root@iZmu0fa4hv0jwzZ ~]# docker run -d -p 3355:8080 --name tomcat01 tomcat d9b38eef2e65eb27aede4860ed8bc3bed860b60ad350a86f1012045919b6aa03 [root@iZmu0fa4hv0jwzZ ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d9b38eef2e65 tomcat "catalina.sh run" 7 seconds ago Up 6 seconds 0.0.0.0:3355->8080/tcp, :::3355->8080/tcp tomcat01 78fb1077cf49 tomcat "catalina.sh run" 43 minutes ago Up 43 minutes 0.0.0.0:3344->8080/tcp, :::3344->8080/tcp tomcat02
如何用名字访问容器
[root@iZmu0fa4hv0jwzZ ~]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known
此问题可以通过--link解决
启动一个tomcat03并将其与tomcat02连接
[root@iZmu0fa4hv0jwzZ ~]# docker run -d -p 3356:8080 --name tomcat03 --link tomcat02 tomcat 3c96a7f2b7176e6a0d77f4c9c43a71b2e97ff46eed2dc570791b86c85a198fee
使用tomcat03 ping tomcat02
[root@iZmu0fa4hv0jwzZ ~]# 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.118 ms 64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.074 ms 64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.075 ms
可以发现能成功ping通
使用tomcat02 ping tomcat03
[root@iZmu0fa4hv0jwzZ ~]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known
发现反向无法ping通
查看tomcat03的配置信息
[root@iZmu0fa4hv0jwzZ ~]# docker inspect tomcat03
可以找到
"Links": [ "/tomcat02:/tomcat03/tomcat02" ],
本质探究
--link就是再host配置中增加了一个172.18.0.3
现在使用docker不建议使用 --link 了
自定义网络不适用docker0
docker0问题:不支持容器名连接访问
自定义网络
查看所有的docker网络
[root@iZmu0fa4hv0jwzZ ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 62fa14dd6435 bridge bridge local d3ea5a97c4be host host local d158b00a6ac1 none null local
网络模式
bridge | 桥接(默认,自己创建也是使用bridge模式) |
none | 不配置网络 |
host | 和宿主机共享网络 |
container | 容器网络联通(用的少) |
删除所有容器
[root@iZmu0fa4hv0jwzZ ~]# docker rm -f $(docker ps -aq)
查看ip配置
[root@iZmu0fa4hv0jwzZ ~]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 00:16:3e:10:1d:f7 brd ff:ff:ff:ff:ff:ff inet 172.24.53.41/18 brd 172.24.63.255 scope global dynamic noprefixroute eth0 valid_lft 313986764sec preferred_lft 313986764sec inet6 fe80::216:3eff:fe10:1df7/64 scope link valid_lft forever preferred_lft forever 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:f1:84:df:a8 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::42:f1ff:fe84:dfa8/64 scope link valid_lft forever preferred_lft forever
测试
#我们直接启动的命令 --net bridge ,而这个就是我们的docker0 docker run -d -P --name tomcat01 tomcat docker run -d -P --name tomcat01 --net bridge tomcat
docker0特点:默认,域名不能访问 --link可以打通链接
创建自己的docker网络
[root@iZmu0fa4hv0jwzZ ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet ec8a0e1d73cf71c457bf4f4f8c3a0f935ec8bd83a55e1f6e43806c4adbd08f61
查看
[root@iZmu0fa4hv0jwzZ ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 62fa14dd6435 bridge bridge local d3ea5a97c4be host host local ec8a0e1d73cf mynet bridge local d158b00a6ac1 none null local
查看自己的docker网络配置
[root@iZmu0fa4hv0jwzZ ~]# docker network inspect mynet [ { "Name": "mynet", "Id": "ec8a0e1d73cf71c457bf4f4f8c3a0f935ec8bd83a55e1f6e43806c4adbd08f61", "Created": "2021-06-23T15:46:32.703622875+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": {} } ]
创建两个tomcat容器并指定docker网络
[root@iZmu0fa4hv0jwzZ ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat 08cb0a04c8ab2a1ad9c7e4f6802bab96016a2f2ec34713dd90475861fe541978 [root@iZmu0fa4hv0jwzZ ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat 5e9a6e7d3aba5d0826cce9ee96f574273dbce8803b6ff1314c650fbd9a56dd1f [root@iZmu0fa4hv0jwzZ ~]# docker inspect mynet [ { "Name": "mynet", "Id": "ec8a0e1d73cf71c457bf4f4f8c3a0f935ec8bd83a55e1f6e43806c4adbd08f61", "Created": "2021-06-23T15:46:32.703622875+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": { "08cb0a04c8ab2a1ad9c7e4f6802bab96016a2f2ec34713dd90475861fe541978": { "Name": "tomcat-net-01", "EndpointID": "39f0c504d1e191e663756d3fd13c02ef17a1f5906ee736f106ee6f93040ad106", "MacAddress": "02:42:c0:a8:00:02", "IPv4Address": "192.168.0.2/16", "IPv6Address": "" }, "5e9a6e7d3aba5d0826cce9ee96f574273dbce8803b6ff1314c650fbd9a56dd1f": { "Name": "tomcat-net-02", "EndpointID": "f55a40458d3f41fb66296be1e470cc74a596cba27cb9b28d2e17365a2efe097a", "MacAddress": "02:42:c0:a8:00:03", "IPv4Address": "192.168.0.3/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ]
使用tomcat-net-01 ping tomcat-net-02
[root@iZmu0fa4hv0jwzZ ~]# docker exec -it tomcat-net-01 ping tomcat-net-02 PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data. 64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.054 ms 64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.074 ms 64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.075 ms 64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=4 ttl=64 time=0.071 ms
发现即使不使用 --link 也可以成功ping通
结论
我们自定义的docker网络都已经帮我们维护好了对应的关系,推荐我们平时这样使用网络
好处
redis-不同的集群使用不同的网络,保证集群是安全和健康的
mysql-不同的集群使用不同的网络,保证集群是安全和健康的
网络联通
创建两个tomcat并指定网络为docker01
[root@iZmu0fa4hv0jwzZ ~]# docker run -d -P --name tomcat01 tomcat 3131a1bf8a412ec222b8e5a43abff4ba32d5ef8fb9c36ee30b533a4a370d8d8d [root@iZmu0fa4hv0jwzZ ~]# docker run -d -P --name tomcat02 tomcat 0e771a982be75785ab5578eeb8783200e628c102228d87113f20a0cfdd127553 [root@iZmu0fa4hv0jwzZ ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0e771a982be7 tomcat "catalina.sh run" 7 seconds ago Up 7 seconds 0.0.0.0:49156->8080/tcp, :::49156->8080/tcp tomcat02 3131a1bf8a41 tomcat "catalina.sh run" 13 seconds ago Up 12 seconds 0.0.0.0:49155->8080/tcp, :::49155->8080/tcp tomcat01
使用tomcat01 ping tomcat-net-01
[root@iZmu0fa4hv0jwzZ ~]# docker exec -it tomcat01 ping tomcat-net-01 ping: tomcat-net-01: Name or service not known
发现无法ping通,解决方法 将容器与docker网络进行连接
docker network connect [OPTIONS] NETWORK CONTAINER
将tomcat01与mynet进行连接
[root@iZmu0fa4hv0jwzZ ~]# docker network connect mynet tomcat01 [root@iZmu0fa4hv0jwzZ ~]# docker inspect mynet [ { "Name": "mynet", "Id": "ec8a0e1d73cf71c457bf4f4f8c3a0f935ec8bd83a55e1f6e43806c4adbd08f61", "Created": "2021-06-23T15:46:32.703622875+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": { "08cb0a04c8ab2a1ad9c7e4f6802bab96016a2f2ec34713dd90475861fe541978": { "Name": "tomcat-net-01", "EndpointID": "39f0c504d1e191e663756d3fd13c02ef17a1f5906ee736f106ee6f93040ad106", "MacAddress": "02:42:c0:a8:00:02", "IPv4Address": "192.168.0.2/16", "IPv6Address": "" }, "3131a1bf8a412ec222b8e5a43abff4ba32d5ef8fb9c36ee30b533a4a370d8d8d": { "Name": "tomcat01", "EndpointID": "334cb9c46d8387598ec21b1acd392c54d5e79a5e70bd920ba921748f17a2cd60", "MacAddress": "02:42:c0:a8:00:04", "IPv4Address": "192.168.0.4/16", "IPv6Address": "" }, "5e9a6e7d3aba5d0826cce9ee96f574273dbce8803b6ff1314c650fbd9a56dd1f": { "Name": "tomcat-net-02", "EndpointID": "f55a40458d3f41fb66296be1e470cc74a596cba27cb9b28d2e17365a2efe097a", "MacAddress": "02:42:c0:a8:00:03", "IPv4Address": "192.168.0.3/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ]
可以发现mynet配置里面多了个tomcat01
再次用tomcat01 ping tomcat-net-01
[root@iZmu0fa4hv0jwzZ ~]# docker exec -it tomcat01 ping tomcat-net-01 PING 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.088 ms 64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.075 ms 64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.061 ms
发现可以ping通
结论
假设要跨网络操作别人,就需要使用docker network connect连通