Docker网络
1 - 理解Docker0
1、清空所有容器与镜像,净化环境
# 清空所有容器 docker rm -f $(docker ps -aq) # 清空所有镜像 docker rmi -f $(docker images -aq)
2、思考:Docker是如何处理容器网络访问的?
# 启动一个Tomcat [root@VM-0-17-centos /]# docker run -d -P --name tomcat01 tomcat # 查看容器内部网络地址。追加一个命令 ip addr 发现容器启动的时候会得到一个 eth0@if81 ip地址,docker分配的 [root@VM-0-17-centos /]# 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 80: eth0@if81: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0 # docker0地址 valid_lft forever preferred_lft forever # 思考,Linux能不能 ping 通容器内部? # 测试 [root@VM-0-17-centos /]# ping 172.18.0.2 PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data. 64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.072 ms 64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.048 ms # 说明:Linux 可以ping 通docker容器内部
3、docker0原理
1、我们每启动一个容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0
桥接模式,使用的技术是 evth-pair
# 我们发现这个容器带来的网卡,都是一对对的 # veth-pair 就是一对的虚拟设备接口,他们都是成对存在的,一段连接着协议,一段彼此相连 # 因为有这个特性,veth-pair 充当一个桥梁,连接各种虚拟网络设备的 # OpenStac,Docker容器之间的连接,OVS的连接,都是使用veth-pair技术
4、我们来测试下tomcat01和tomcat02是否可以ping通
[root@VM-0-17-centos /]# docker exec -it tomcat01 ip addr # 获取 tomcat01 的ip 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 80: eth0@if81: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0 valid_lft forever preferred_lft forever [root@VM-0-17-centos /]# docker exec -it tomcat02 ping 172.18.0.2 # 让tomcat02 ping tomcat01 PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data. 64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.122 ms 64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.059 ms # 测试结果发下,容器之间可以ping 通
5、docker0网络通信原理图(桥连接)
结论:tomcat01和tomcat02公用一个路由器,docker0。
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用ip。
小结: Docker使用的是Linux的桥接,宿主机是一个Docker容器的网桥 docker0。Docker中所有的网路接口都是虚拟的,虚拟的转发效率高(内网传递文件)
只要容器删除,对应的网桥对就没有了
2 - 容器互联之 --link
思考一个场景:我们编写了一个微服务,database url=ip: 项目不重启,数据ip换了,我们希望可以处理这个问题,可以通过名字来进行访问容器?
$ docker exec -it tomcat02 ping tomca01 # ping不通 ping: tomca01: Name or service not known # 运行一个tomcat03 --link tomcat02 $ docker run -d -P --name tomcat03 --link tomcat02 tomcat 5f9331566980a9e92bc54681caaac14e9fc993f14ad13d98534026c08c0a9aef # 用tomcat03 ping tomcat02 可以ping通 $ 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.115 ms 64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.080 ms # 用tomcat02 ping tomcat03 ping不通
探究: docker network inspect 网络id 网段相同
docker inspect tomcat03
查看tomcat03里面的/etc/hosts发现有tomcat02的配置
–link 本质就是在hosts配置中添加映射
现在使用Docker已经不建议使用–link了!
自定义网络,不适用docker0!
docker0问题:不支持容器名连接访问!
3 - 容器互联之自定义网络
1、查看所有的docker网络
[root@VM-0-17-centos /]# docker network ls NETWORK ID NAME DRIVER SCOPE c4119baf1ba2 bridge bridge local c42cab1b38db host host local b5c1e156330a none null local
网络模式
bridge # 桥连接 docker默认,自己创建也使用 bridge 模式 host # 不配置网络 none # 和宿主机共享网络 container # 容器内网络联通(用的少)
自定义网络
# 我们直接启动的命令 --net bridge 而这个就是我们的docker0 docker run -d -P --name tomcat01 tomcat docker run -d -P --name tomcat01 --net bridge tomcat # docker0的特点:默认,容器名不能访问。--link 可以打通容器间连接,但是也有一些弊端 # 我们可以自定义 # --driver bridge # --subnet 192.168.0.0/16 # --gateway 192.168.0.1 [root@VM-0-17-centos /]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet 051c657ae074e244437a7fc7a606187efd9a96ad8214e32ae375adc689c08103 [root@VM-0-17-centos /]# docker network ls NETWORK ID NAME DRIVER SCOPE c4119baf1ba2 bridge bridge local c42cab1b38db host host local 051c657ae074 mynet bridge local b5c1e156330a none null local # 启动两个tomcat [root@VM-0-17-centos /]# docker run -d -P --name tomcat-mynet01 --net mynet tomcat 6538cf23ba9ffbb40dbb61ce978fc796a6145035379056cfa7822370637e279f [root@VM-0-17-centos /]# docker run -d -P --name tomcat-mynet02 --net mynet tomcat c568b7da687c0ae3b19983444aa0c4b0268313a30c433a84ccd8b88ebe59784a # 此时可以查看以自定义的网络配置 docker network inspect mynet [root@VM-0-17-centos /]# docker network inspect mynet [ { "Name": "mynet", "Id": "051c657ae074e244437a7fc7a606187efd9a96ad8214e32ae375adc689c08103", "Created": "2020-10-05T19:53:44.245591371+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": { "6538cf23ba9ffbb40dbb61ce978fc796a6145035379056cfa7822370637e279f": { "Name": "tomcat-mynet01", "EndpointID": "1c394d71dfd9abcf88fefc981cf985d5b42cc368cbb9d03e07e297b3fa87b8c3", "MacAddress": "02:42:c0:a8:00:02", "IPv4Address": "192.168.0.2/16", "IPv6Address": "" }, "c568b7da687c0ae3b19983444aa0c4b0268313a30c433a84ccd8b88ebe59784a": { "Name": "tomcat-mynet02", "EndpointID": "4100b2e8c9c35460e41e8212b428d6c558055e6176b502a18a3f8e6e20038f8c", "MacAddress": "02:42:c0:a8:00:03", "IPv4Address": "192.168.0.3/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ]
测试两个 tomcat 通过ip地址或者容器名 能不能 ping 通
# 测试通过ip 地址能不能ping 通 [root@VM-0-17-centos /]# docker exec -it tomcat-mynet01 ip addr # 获取tomcat-mynet01 的ip地址 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 87: eth0@if88: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:c0:a8:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 192.168.0.2/16 brd 192.168.255.255 scope global eth0 valid_lft forever preferred_lft forever # 测试 [root@VM-0-17-centos /]# docker exec -it tomcat-mynet02 ping 192.168.0.2 PING 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.088 ms 64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.075 ms
# 通过容器名 ping 通 [root@VM-0-17-centos /]# docker exec -it tomcat-mynet02 ping tomcat-mynet02 PING tomcat-mynet02 (192.168.0.3) 56(84) bytes of data. 64 bytes from c568b7da687c (192.168.0.3): icmp_seq=1 ttl=64 time=0.030 ms 64 bytes from c568b7da687c (192.168.0.3): icmp_seq=2 ttl=64 time=0.047 ms
好处:
redis -不同的集群使用不同的网络,保证集群是安全和健康的
mysql-不同的集群使用不同的网络,保证集群是安全和健康的
4 - 网络连通
1、为什么需要网络连通?两个属于不同网卡的容器之间实现互联!
2、网络连通命令
3、测试
# 测试两个不同的网络连通 再启动两个tomcat 使用默认网络,即docker0 [root@VM-0-17-centos /]# docker run -d -P --name tomcat01 tomcat 9248bf34255630899658d334423c6a5b946e5b8dbd4807d96425ff8027263f32 [root@VM-0-17-centos /]# docker run -d -P --name tomcat02 tomcat b7daa6950ce761a92af859f8f4590a754bab633e4ce79811560beeed70bb8d78 [root@VM-0-17-centos /]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b7daa6950ce7 tomcat "catalina.sh run" 8 seconds ago Up 7 seconds 0.0.0.0:32778->8080/tcp tomcat02 9248bf342556 tomcat "catalina.sh run" 16 seconds ago Up 16 seconds 0.0.0.0:32777->8080/tcp tomcat01 # 此时ping不通 # 要将tomcat01 连通 tomcat—mynet01 ,连通就是将 tomcat01加到 mynet网络 [root@VM-0-17-centos /]# docker run -d -P --name tomcat-mynet01 --net mynet tomcat 347517e4ac2d18e252a2003af1d0cd5aeeec812466e7ad93621b74b46211e3eb # 连通命令:docker network connect 网络模式 容器名 [root@VM-0-17-centos /]# docker network connect mynet tomcat01 # 测试 [root@VM-0-17-centos /]# docker exec -it tomcat01 ping tomcat-mynet01 PING tomcat-mynet01 (192.168.0.2) 56(84) bytes of data. 64 bytes from tomcat-mynet01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.068 ms 64 bytes from tomcat-mynet01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.059 ms # 原因:使用连通命令时,将tomcat01 放到了 mynet下。可用 docker network inspect mynet 查看 # 总结:一个容器两个ip,网卡之间不能直接打通
结论:假设要跨网络操作别人的容器,就需要使用docker network connect 连通!