版本:19.03.5
网络知识主要学习如何访问容器中服务及各个容器之间互相通信。
Docker 网络类型主要分为:
单机:
birdge NetWork : 桥接模式,也是容器使用的默认模式
host NetWork : 容器共享宿主主机的网络命名空间(Network Namespace)
none NetWork : 有独立的Network Namespace,但默认不会有任何的网络配置
多机:
Overlay NetWork : vxlan模式
Bridge Network
安装好Docker以后,宿主主机默认会新创建一个docker0网络:
# ifconfig docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 inet6 fe80::42:d8ff:fec3:67ee prefixlen 64 scopeid 0x20<link> ether 02:42:d8:c3:67:ee txqueuelen 0 (Ethernet) RX packets 141 bytes 169350 (165.3 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 210 bytes 20900 (20.4 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
默认网络是bridge模式,网段在172.17.0网段。
查看docker网络列表
# docker network list NETWORK ID NAME DRIVER SCOPE 0eb80c8427a7 bridge bridge local b678a42c5faf host host local 96abb6575955 none null local
在创建容器时,默认都是使用网络bridge。创建容器tomcat_01和tomcat_02:
# docker run -d --name tomcat_01 -p 8080:8080 tomcat 7e20de6f90d192ad307a0b94c874cc529dec9b242f288caefe72ae94f41b1bac # docker run -d --name tomcat_02 -p 8081:8080 tomcat a4ca98091a01250a7b0cd8bb9b90a27771279ab5f1ce158dda5b3fbcf7b595b0 # docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a4ca98091a01 tomcat "catalina.sh run" 3 minutes ago Up 3 minutes 0.0.0.0:8081->8080/tcp tomcat_02 7e20de6f90d1 tomcat "catalina.sh run" 18 minutes ago Up 18 minutes 0.0.0.0:8080->8080/tcp tomcat_01可以通过 inspect 查看网络详细信息:
# docker network inspect bridge [ { "Name": "bridge", "Id": "0eb80c8427a7a4b60370f85ffe769b959d086eac2b905a01fa3632c9e2d67fa3", "Created": "2019-12-29T09:24:53.964816193-05:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "172.17.0.0/16", "Gateway": "172.17.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "7e20de6f90d192ad307a0b94c874cc529dec9b242f288caefe72ae94f41b1bac": { "Name": "tomcat_01", "EndpointID": "910f890b2f529046392d51da17d2efc7c4b945b5bf974e3e9d179ae2dcf7c51f", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" }, "a4ca98091a01250a7b0cd8bb9b90a27771279ab5f1ce158dda5b3fbcf7b595b0": { "Name": "tomcat_02", "EndpointID": "934e646244341a2cdff757bc6231993c83a57cc4cf0b86bc14352c6a77feea15", "MacAddress": "02:42:ac:11:00:03", "IPv4Address": "172.17.0.3/16", "IPv6Address": "" } }, "Options": { "com.docker.network.bridge.default_bridge": "true", "com.docker.network.bridge.enable_icc": "true", "com.docker.network.bridge.enable_ip_masquerade": "true", "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0", "com.docker.network.bridge.name": "docker0", "com.docker.network.driver.mtu": "1500" }, "Labels": {} } ]可以看到网络名称为bridge的网络容器信息里边包含IP为172.17.0.2的容器tomcat_01,和IP为172.17.0.3的容器tomcat_02。
我们进入容器tomcat_01中ping一下容器tomcat_02:
# docker exec -it tomcat_01 bash root@7e20de6f90d1:/usr/local/tomcat# ping 172.17.0.3 PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data. 64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.240 ms 64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.057 ms 64 bytes from 172.17.0.3: icmp_seq=3 ttl=64 time=0.060 ms ^C --- 172.17.0.3 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2000ms rtt min/avg/max/mdev = 0.057/0.119/0.240/0.085 ms root@7e20de6f90d1:/usr/local/tomcat# ping tomcat_02 ping: tomcat_02: Name or service not known
从上边操作中可以看出,在容器tomcat_01中可以通过IP ping通容器tomcat_02,但是通过容器名称不可以ping通。
如果想通过容器名称实现容器之间的通信需要自己创建自己的网络。
# docker network create -d bridge tomcat-net 11ca5edea6ef2fea3b756a9708abed66bf2cca9a8f9036ad05dbb05b766bf39a [root@localhost ~]# docker network list NETWORK ID NAME DRIVER SCOPE 0eb80c8427a7 bridge bridge local b678a42c5faf host host local 96abb6575955 none null local 11ca5edea6ef tomcat-net bridge local其中-d参数指明网络类型,查看自定义网络详情:
# docker network inspect tomcat-net [ { "Name": "tomcat-net", "Id": "11ca5edea6ef2fea3b756a9708abed66bf2cca9a8f9036ad05dbb05b766bf39a", "Created": "2019-12-29T09:54:29.35890642-05:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.18.0.0/16", "Gateway": "172.18.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": {}, "Options": {}, "Labels": {} } ]
我们可以看到新创建的网络网段在172.18.0.0/16。
在创建网络时,也可以指定网段等其他信息,删除网络tomcat-net,重新创建
# docker network rm tomcat-net tomcat-net # docker network ls NETWORK ID NAME DRIVER SCOPE 0eb80c8427a7 bridge bridge local b678a42c5faf host host local 96abb6575955 none null local # docker network create -d bridge --subnet=172.20.1.0/24 tomcat-net fcc4fd20cf617b68d9448cc18dd3a51e222475c2ec80f426d3856540038c85e6 # docker network ls NETWORK ID NAME DRIVER SCOPE 0eb80c8427a7 bridge bridge local b678a42c5faf host host local 96abb6575955 none null local fcc4fd20cf61 tomcat-net bridge local # docker network ls [ { "Name": "tomcat-net", "Id": "fcc4fd20cf617b68d9448cc18dd3a51e222475c2ec80f426d3856540038c85e6", "Created": "2019-12-29T10:06:08.790239082-05:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.20.1.0/24" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": {}, "Options": {}, "Labels": {} } ]
新创建容器tomcat_11和tomcat_12,并使用新创建的网络 tomcat-net:
# docker run -d --name tomcat_11 --network tomcat-net -p 9091:8080 tomcat fb8a31e42a5c5ebc22ef0e4cc3884a0e6f86c091e6a59c36a09dbbb588ea00ee # docker run -d --name tomcat_12 --network tomcat-net -p 9092:8080 tomcat cd06f4c4562f1a88f62adb24320730df148764f82b3284f595327eada3ce242c # docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cd06f4c4562f tomcat "catalina.sh run" 11 seconds ago Up 5 seconds 0.0.0.0:9092->8080/tcp tomcat_12 fb8a31e42a5c tomcat "catalina.sh run" 24 seconds ago Up 21 seconds 0.0.0.0:9091->8080/tcp tomcat_11 a4ca98091a01 tomcat "catalina.sh run" 29 minutes ago Up 29 minutes 0.0.0.0:8081->8080/tcp tomcat_02 7e20de6f90d1 tomcat "catalina.sh run" 44 minutes ago Up 44 minutes 0.0.0.0:8080->8080/tcp tomcat_01 # docker network inspect tomcat-net [ { "Name": "tomcat-net", "Id": "fcc4fd20cf617b68d9448cc18dd3a51e222475c2ec80f426d3856540038c85e6", "Created": "2019-12-29T10:06:08.790239082-05:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.20.1.0/24" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "cd06f4c4562f1a88f62adb24320730df148764f82b3284f595327eada3ce242c": { "Name": "tomcat_12", "EndpointID": "ed45a3d5dcbce479cab21a8788ad32c7c8e5a21dc92708c5ebd4edb9442c5570", "MacAddress": "02:42:ac:14:01:03", "IPv4Address": "172.20.1.3/24", "IPv6Address": "" }, "fb8a31e42a5c5ebc22ef0e4cc3884a0e6f86c091e6a59c36a09dbbb588ea00ee": { "Name": "tomcat_11", "EndpointID": "076aa51a454ca789c46ef83589d42b4bf16fa53ddfb0bf0b826979984fb53e39", "MacAddress": "02:42:ac:14:01:02", "IPv4Address": "172.20.1.2/24", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ]现在进入容器tomcat_11分别使用IP和容器名称 尝试 ping 容器tomcat_12:
# docker exec -it tomcat_11 bash root@fb8a31e42a5c:/usr/local/tomcat# ping 172.20.1.3 PING 172.20.1.3 (172.20.1.3) 56(84) bytes of data. 64 bytes from 172.20.1.3: icmp_seq=1 ttl=64 time=0.119 ms 64 bytes from 172.20.1.3: icmp_seq=2 ttl=64 time=0.056 ms 64 bytes from 172.20.1.3: icmp_seq=3 ttl=64 time=0.059 ms ^C --- 172.20.1.3 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2000ms rtt min/avg/max/mdev = 0.056/0.078/0.119/0.029 ms root@fb8a31e42a5c:/usr/local/tomcat# ping tomcat_12 PING tomcat_12 (172.20.1.3) 56(84) bytes of data. 64 bytes from tomcat_12.tomcat-net (172.20.1.3): icmp_seq=1 ttl=64 time=0.111 ms 64 bytes from tomcat_12.tomcat-net (172.20.1.3): icmp_seq=2 ttl=64 time=0.059 ms 64 bytes from tomcat_12.tomcat-net (172.20.1.3): icmp_seq=3 ttl=64 time=0.058 ms ^C --- tomcat_12 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2000ms rtt min/avg/max/mdev = 0.058/0.076/0.111/0.024 ms
发现通过IP 或 容器名称均可ping通。
我们查看容器 tomcat_11 的网络信息:
root@fb8a31e42a5c:/usr/local/tomcat# ip a 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 56: eth0@if57: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:14:01:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.20.1.2/24 brd 172.20.1.255 scope global eth0 valid_lft forever preferred_lft forever
发现除本地回环测试地址外,还有另外一块编号为56的网卡 eth0@if57,可以看出容器tomcat_11是通过网络桥接模式连接到编号为57的网卡,57网卡绑定在宿主主机Docker0。
另外也可以使用 --link 实现容器之间通信:
# docker run -d --name tomcat_03 --link tomcat_02 -p 8083:8080 tomcat 44660f561eefdc9baeb1a96efe8799d33ae8e9e6d6714c8f620dcad19bcebb48 # docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 44660f561eef tomcat "catalina.sh run" 35 minutes ago Up 3 seconds 0.0.0.0:8083->8080/tcp tomcat_03 a4ca98091a01 tomcat "catalina.sh run" 2 hours ago Up 4 seconds 0.0.0.0:8081->8080/tcp tomcat_02 7e20de6f90d1 tomcat "catalina.sh run" 2 hours ago Up 4 seconds 0.0.0.0:8080->8080/tcp tomcat_01 # docker exec -it tomcat_03 bash root@44660f561eef:/usr/local/tomcat# ip a 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 68: eth0@if69: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.4/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever root@44660f561eef:/usr/local/tomcat# ping 127.17.0.3 PING 127.17.0.3 (127.17.0.3) 56(84) bytes of data. 64 bytes from 127.17.0.3: icmp_seq=1 ttl=64 time=0.035 ms 64 bytes from 127.17.0.3: icmp_seq=2 ttl=64 time=0.048 ms ^C --- 127.17.0.3 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 0.035/0.041/0.048/0.009 ms root@44660f561eef:/usr/local/tomcat# ping tomcat_02 PING tomcat_02 (172.17.0.3) 56(84) bytes of data. 64 bytes from tomcat_02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.101 ms 64 bytes from tomcat_02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.056 ms ^C --- tomcat_02 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1000ms rtt min/avg/max/mdev = 0.056/0.078/0.101/0.024 ms
通过上述操作可以发现,容器tomcat_03也是用默认的网络bridge。
进入容器tomcat_03,和容器tomcat_02之间的通信既可以通过IP也可以通过容器的名称。
但是,tomcat_03和tomcat_01之间只能通过IP互相通信却不能使用容器名称通信。
但是使用自定义网络时,使用 --link 出错:
# docker run -d --name tomcat_21 --link tomcat_12 -p 9191:8080 tomcat f3eb6fb697bf7d77f9ec774eda88b35b708607af38280f716df83d0bcaaea478 docker: Error response from daemon: Cannot link to /tomcat_12, as it does not belong to the default network.
host Network
使用 host 网络,容器共享宿主主机的网络命名空间。
# docker run -d --name tomcat_102 --network host -p 9999:8080 tomcat WARNING: Published ports are discarded when using host network mode ecb3899d3340b27f06d367bead06f27b4736e5e200defd5840cfd8331e2ece4a # docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ecb3899d3340 tomcat "catalina.sh run" 2 seconds ago Up 2 seconds tomcat_102 # docker exec -it tomcat_102 /bin/bash root@localhost:/usr/local/tomcat# ip a 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: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:91:e9:ee brd ff:ff:ff:ff:ff:ff inet 192.168.31.200/24 brd 192.168.31.255 scope global noprefixroute ens33 valid_lft forever preferred_lft forever inet6 fe80::b9a1:1d26:25ac:447/64 scope link noprefixroute valid_lft forever preferred_lft forever 3: virbr0: <BROADCAST,MULTICAST> mtu 1500 qdisc noqueue state DOWN group default qlen 1000 link/ether 52:54:00:0f:e7:5a brd ff:ff:ff:ff:ff:ff 4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000 link/ether 52:54:00:0f:e7:5a brd ff:ff:ff:ff:ff:ff 5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:d8:c3:67:ee 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:d8ff:fec3:67ee/64 scope link valid_lft forever preferred_lft forever 55: br-fcc4fd20cf61: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:db:c9:69:27 brd ff:ff:ff:ff:ff:ff inet 172.20.1.1/24 brd 172.20.1.255 scope global br-fcc4fd20cf61 valid_lft forever preferred_lft forever inet6 fe80::42:dbff:fec9:6927/64 scope link valid_lft forever preferred_lft forever
我们可以看出容器内网卡信息和宿主主机相同。并且:
# curl 192.168.31.200:9999 curl: (7) Failed connect to 192.168.31.200:9999; Connection refused
我们发现即使有设置端口映射也不再起作用,因为共享网络命名空间,此容器已经占用了宿主主机的 8080 端口。
直接使用宿主主机的IP加8080端口(容器外露端口)访问即可。
none Network
在创建容器时使用 none 网络,默认不会有任何的网络配置:
# docker run -d --name tomcat_101 --network none -p 9901:8080 tomcat 06ad0476666f036727acff5897a362ed88aeb576a7a5d198f66d26c50b6a19d0 # docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 06ad0476666f tomcat "catalina.sh run" 11 seconds ago Up 10 seconds tomcat_101 # docker exec -it tomcat_101 /bin/bash root@06ad0476666f:/usr/local/tomcat# ip a 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我们发现即使有端口映射,但是查看容器时 PORTS 无任何显示,进入查看后也只有默认的本地回环测试地址,此容器独享自己的网络命名空间,可自行配置网卡。
overlay Network
overlay网络模式是实现多机之间docker容器信息通信的,创建此类型网络需要swarm manager节点。
注意点:多机之间运行的容器不可以在同一网段。