Docker用户指南(11) – Docker网络命令
本文介绍与docker网络和在其中的容器的交互的网络子命令示例。这些命令是:
docker network create docker network connect docker network ls docker network rm docker network disconnect docker network inspect创建网络
当你安装Docker Engine时,它自动创建一个bridge网络。此网络是docker engine依赖的docker0 bridge。除了这个网络,你可以创建自己的bridge或overlay网络。
一个bridge网络存在于运行着docker engine实例的单个主机上。一个overlay网络能跨越运行着它们自己engine的多个主机。如果你执行docker network create并只提供一个网络名称,它将为你创建一个bridge网络。
$ docker network create simple-network 69568e6336d8c96bbf57869030919f7c69524f71183b44d80948bd3927c87f6a $ docker network inspect simple-network [ { "Name": "simple-network", "Id": "69568e6336d8c96bbf57869030919f7c69524f71183b44d80948bd3927c87f6a", "Scope": "local", "Driver": "bridge", "IPAM": { "Driver": "default", "Config": [ { "Subnet": "172.22.0.0/16", "Gateway": "172.22.0.1/16" } ] }, "Containers": {}, "Options": {} } ]
不像bridge网络,在创建overlay网络之前需要一些提前存在的条件。这些条件是:
有一个能访问的键值存储。Engine支持Consul, Etcd和ZooKeeper(分布式存储)键值存储。 集群的主机能够访问键值存储。 在集群的每一个主机正确配置Engine daemon。支持overlay网络的dockerd选项是:
–cluster-store –cluster-store-opt –cluster-advertise当你创建网络时,Engine默认会为你的网络创建一个不重叠的子网。你可以直接使用–subnet选项来指定一个子网覆盖默认的行为。在一个bridge网络中你只能指定一个子网,而overlay网络支持多个子网。
创建网络时强烈推荐使用–subnet选项。如果–subnet选项没有指定,docker daemon会自动为你的网络选择和分配一个子网,它有可能与另一个不是docker控制的子网重叠。当容器连接到这样的网络时会导致引引连接问题。
除了–subnet选项,你也可以指定–gateway,–ip-range和–aux-address选项。
$ docker network create -d overlay --subnet=192.168.0.0/16 --subnet=192.170.0.0/16 --gateway=192.168.0.100 --gateway=192.170.0.100 --ip-range=192.168.1.0/24 --aux-address="my-router=192.168.1.5" --aux-address="my-switch=192.168.1.6" --aux-address="my-printer=192.170.1.5" --aux-address="my-nas=192.170.1.6" my-multihost-network
确保你的子网不会重叠,如果重叠了,网络创建会失败,Engine返回一个错误。
当你创建一个自定义网络时,你可以传递额外的选项到驱动。bridge驱动接受如下选项:
com.docker.network.driver.mtu选项同样被overlay驱动支持。
下面的参数可以传递到docker network create创建任何网络驱动时。
下面的示例使用-o绑定一个特定ip地址用来绑定端口,然后使用docker network inspect来查看网络,最后附加一个新容器到这个新网络。
$ docker network create -o "com.docker.network.bridge.host_binding_ipv4"="172.23.0.1" my-network b1a086897963e6a2e7fc6868962e55e746bee8ad0c97b54a5831054b5f62672a $ docker network inspect my-network [ { "Name": "my-network", "Id": "b1a086897963e6a2e7fc6868962e55e746bee8ad0c97b54a5831054b5f62672a", "Scope": "local", "Driver": "bridge", "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.23.0.0/16", "Gateway": "172.23.0.1/16" } ] }, "Containers": {}, "Options": { "com.docker.network.bridge.host_binding_ipv4": "172.23.0.1" } } ] $ docker run -d -P --name redis --network my-network redis bafb0c808c53104b2c90346f284bda33a69beadcab4fc83ab8f2c5a4410cd129 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES bafb0c808c53 redis "/entrypoint.sh redis" 4 seconds ago Up 3 seconds 172.23.0.1:32770->6379/tcp redis
连接容器
你可以连接一个存在的容器到一个或多个网络。一个容器能连接到使用不同网络驱动的网络。一旦连接,容器就能够使用另一个容器IP地址或名称为通信。
对于支持多主机连接的overlay网络或自定义插件,从不同主机启动的容器连接到相同的多主机网络也能够也这种方式通信。
基本的容器网络示例
1.首先创建和运行两个容器,container1和container2:
$ docker run -itd --name=container1 busybox 18c062ef45ac0c026ee48a83afa39d25635ee5f02b58de4abc8f467bcaa28731 $ docker run -itd --name=container2 busybox 498eaaaf328e1018042c04b2de04036fc04719a6e39a097a4f4866043a2c2152
2.创建一个隔离的bridge网络来测试。
$ docker network create -d bridge --subnet 172.25.0.0/16 isolated_nw 06a62f1c73c4e3107c0f555b7a5f163309827bfbbf999840166065a8f35455a8
3.连接container2到上步创建的网络,然后查看这个网络:
$ docker network connect isolated_nw container2 $ docker network inspect isolated_nw [ { "Name": "isolated_nw", "Id": "06a62f1c73c4e3107c0f555b7a5f163309827bfbbf999840166065a8f35455a8", "Scope": "local", "Driver": "bridge", "IPAM": { "Driver": "default", "Config": [ { "Subnet": "172.25.0.0/16", "Gateway": "172.25.0.1/16" } ] }, "Containers": { "90e1f3ec71caf82ae776a827e0712a68a110a3f175954e5bd4222fd142ac9428": { "Name": "container2", "EndpointID": "11cedac1810e864d6b1589d92da12af66203879ab89f4ccd8c8fdaa9b1c48b1d", "MacAddress": "02:42:ac:19:00:02", "IPv4Address": "172.25.0.2/16", "IPv6Address": "" } }, "Options": {} } ]
注意到container2自动分配了一个IP地址。因为你创建网络时指定了–subnet,IP地址从这个子网选择。
提醒一下,目前container1只连接到了默认的bridge网络。
4.启动第三个容器,不过这次使用–ip参数来指定一个IP地址和使用docker run命令的–network参数来连接到isolated_nw网络:
$ docker run --network=isolated_nw --ip=172.25.3.3 -itd --name=container3 busybox 467a7863c3f0277ef8e661b38427737f28099b61fa55622d6c30fb288d88c551
只要你为容器指定的Ip地址是网络子网的一部分,你就可以当连接到一个网络时使用–ip或–ip6参数来分配一个IPv4或IPv6地址给容器。当你以这样的方式在一个使用自定义网络容器中指定一个IP地址时,配置将作为容器配置的一部分保留,并在重新加载容器时应用。当使用非用户定义的网络时,保留分配的IP地址,因为除非你使用用户定义的网络,否则当Docker守护程序重新启动时,不能保证容器的子网不会更改。
5.查看container3使用的网络资源。
$ docker inspect --format='' container3 {"isolated_nw": {"IPAMConfig": { "IPv4Address":"172.25.3.3"}, "NetworkID":"1196a4c5af43a21ae38ef34515b6af19236a3fc48122cf585e3f3054d509679b", "EndpointID":"dffc7ec2915af58cc827d995e6ebdc897342be0420123277103c40ae35579103", "Gateway":"172.25.0.1", "IPAddress":"172.25.3.3", "IPPrefixLen":16, "IPv6Gateway":"", "GlobalIPv6Address":"", "GlobalIPv6PrefixLen":0, "MacAddress":"02:42:ac:19:03:03"} } } }
因为你启动container3容器时指定了isolated_nw网络,它不再连接到默认的bridge网络。
6.查看container2使用的网络资源。
$ docker inspect --format='' container2 | python -m json.tool { "bridge": { "NetworkID":"7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812", "EndpointID": "0099f9efb5a3727f6a554f176b1e96fca34cae773da68b3b6a26d046c12cb365", "Gateway": "172.17.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAMConfig": null, "IPAddress": "172.17.0.3", "IPPrefixLen": 16, "IPv6Gateway": "", "MacAddress": "02:42:ac:11:00:03" }, "isolated_nw": { "NetworkID":"1196a4c5af43a21ae38ef34515b6af19236a3fc48122cf585e3f3054d509679b", "EndpointID": "11cedac1810e864d6b1589d92da12af66203879ab89f4ccd8c8fdaa9b1c48b1d", "Gateway": "172.25.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAMConfig": null, "IPAddress": "172.25.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "MacAddress": "02:42:ac:19:00:02" } }
注意看container2属于两个网络。当你启动它时加入到了默认的bridge网络和在第3步连接到了isolated_nw网络。
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:03
eth1 Link encap:Ethernet HWaddr 02:42:AC:15:00:02
7.使用docker attach命令连接到运行中的container2并查看它的网络配置。
$ sudo ifconfig -a eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:03 inet addr:172.17.0.3 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::42:acff:fe11:3/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:9001 Metric:1 RX packets:8 errors:0 dropped:0 overruns:0 frame:0 TX packets:8 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:648 (648.0 B) TX bytes:648 (648.0 B) eth1 Link encap:Ethernet HWaddr 02:42:AC:15:00:02 inet addr:172.25.0.2 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::42:acff:fe19:2/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:8 errors:0 dropped:0 overruns:0 frame:0 TX packets:8 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:648 (648.0 B) TX bytes:648 (648.0 B) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
8.Docker内置的DNS服务器为连接到给定网络的容器启用名称解析。这意味着任意连接的容器能通过容器的名称ping在同一网络另一个容器。从container2内,你能通过container3的名称ping它。
/ # ping -w 4 container3 PING container3 (172.25.3.3): 56 data bytes 64 bytes from 172.25.3.3: seq=0 ttl=64 time=0.070 ms 64 bytes from 172.25.3.3: seq=1 ttl=64 time=0.080 ms 64 bytes from 172.25.3.3: seq=2 ttl=64 time=0.080 ms 64 bytes from 172.25.3.3: seq=3 ttl=64 time=0.097 ms --- container3 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.070/0.081/0.097 ms
这个功能对于默认的bridge网络不可用。container1和container2都是连接到bridge网络,你不能使用容器名称来从container2 ping container1。
/ # ping -w 4 container1 ping: bad address 'container1'
不过你仍然可以直接ping ip地址:
/ # ping -w 4 172.17.0.2 PING 172.17.0.2 (172.17.0.2): 56 data bytes 64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.095 ms 64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.075 ms 64 bytes from 172.17.0.2: seq=2 ttl=64 time=0.072 ms 64 bytes from 172.17.0.2: seq=3 ttl=64 time=0.101 ms --- 172.17.0.2 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.072/0.085/0.101 ms
9.目前container2附加到了bridge和isolated_nw这两个网络,所以你能与container1和container3两个通信。不过container3和container1没有在任何一个共同的网络,所以它们无法通信。要验证这个,可以attach到container3并尝试ping container1的ip地址。
$ docker attach container3 $ ping 172.17.0.2 PING 172.17.0.2 (172.17.0.2): 56 data bytes ^C --- 172.17.0.2 ping statistics --- 10 packets transmitted, 0 packets received, 100% packet loss
链接(linking)不使用自定义网络的容器
当你完成了上面的步骤后,container2能自动地解析container3的名称,是因为两个容器都连接到了isolated_nw网络。不过连接到默认bridge网络的容器无法解析彼此的容器名称。如果你需要在默认的bridge网络能够解析彼此的容器名称,你需要使用旧的链接(legacy link)功能。这是使用–link唯一推荐的一个用例。你应该考虑使用自定义网络替代。
使用旧的link参数对在默认bridge网络的通信增加了如下功能:
重申一下,当你使用一个自定义的网络时,下面的所有功能不需要额外的配置默认提供。此外,你能够动态地附加到多个网络和从多个网络脱离。
使用DNS自动名称解析 支持使用–link选项为链接的容器提供网络名称别名 为网络中的容器自动提供安全的隔离环境 环境变量注入下面的示例简单的介绍如何使用–link。
1.继续上面的示例,创建一个container4容器并连接它到isolated_nw网络。此外,使用–link参数链接它到容器container5(目前还不存在)。
$ docker run --network=isolated_nw -itd --name=container4 --link container5:c5 busybox 01b5df970834b77a9eadbaff39051f237957bd35c4c56f11193e0594cfd5117c
这有点棘手,因为container5还不存在。当创建container5后,container4就能够解析c5为container5的ip地址。
注意:使用旧的链接创建的容器之间的任意链接是静态并且硬绑定容器的别名。它不允许链接的容器重启。在自定义网络的链接功能支持容器之间动态链接并允许重启和链接的容器ip地址更改。
因为你没有创建容器container5,所以尝试ping它的话会返回错误。附加到container4并尝试ping container5或c5:
$ docker attach container4 $ ping container5 ping: bad address 'container5' $ ping c5 ping: bad address 'c5'
2.创建另一个容器container5,并链接它到使用c4别名的container4.
$ docker run --network=isolated_nw -itd --name=container5 --link container4:c4 busybox 72eccf2208336f31e9e33ba327734125af00d1e1d2657878e2ee8154fbb23c7a
现在附着到container4并尝试ping c5和container5。
$ docker attach container4 / # ping -w 4 c5 PING c5 (172.25.0.5): 56 data bytes 64 bytes from 172.25.0.5: seq=0 ttl=64 time=0.070 ms 64 bytes from 172.25.0.5: seq=1 ttl=64 time=0.080 ms 64 bytes from 172.25.0.5: seq=2 ttl=64 time=0.080 ms 64 bytes from 172.25.0.5: seq=3 ttl=64 time=0.097 ms --- c5 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.070/0.081/0.097 ms / # ping -w 4 container5 PING container5 (172.25.0.5): 56 data bytes 64 bytes from 172.25.0.5: seq=0 ttl=64 time=0.070 ms 64 bytes from 172.25.0.5: seq=1 ttl=64 time=0.080 ms 64 bytes from 172.25.0.5: seq=2 ttl=64 time=0.080 ms 64 bytes from 172.25.0.5: seq=3 ttl=64 time=0.097 ms --- container5 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.070/0.081/0.097 ms
3.最后,附着到container5并验证你能ping container4.
$ docker attach container5 / # ping -w 4 c4 PING c4 (172.25.0.4): 56 data bytes 64 bytes from 172.25.0.4: seq=0 ttl=64 time=0.065 ms 64 bytes from 172.25.0.4: seq=1 ttl=64 time=0.070 ms 64 bytes from 172.25.0.4: seq=2 ttl=64 time=0.067 ms 64 bytes from 172.25.0.4: seq=3 ttl=64 time=0.082 ms --- c4 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.065/0.070/0.082 ms / # ping -w 4 container4 PING container4 (172.25.0.4): 56 data bytes 64 bytes from 172.25.0.4: seq=0 ttl=64 time=0.065 ms 64 bytes from 172.25.0.4: seq=1 ttl=64 time=0.070 ms 64 bytes from 172.25.0.4: seq=2 ttl=64 time=0.067 ms 64 bytes from 172.25.0.4: seq=3 ttl=64 time=0.082 ms --- container4 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.065/0.070/0.082 ms
网络别名作用域示例
当你链接容器,不论使用的是旧的link方式或者使用自定义网络,你指定的任何别名只对链接的容器有效,不会对在默认bridge网络的其它容器有用。
此外,如果一个容器属于多个网络,一个给定的链接别名的作用域是一个给定的网络。因此一个容器在不同的网络能被链接到不同的别名,且不在同一个网络的容器别名不会有效。
下面的示例说明了这些点。
1.创建另一个网络local_alias
$ docker network create -d bridge --subnet 172.26.0.0/24 local_alias 76b7dc932e037589e6553f59f76008e5b76fa069638cd39776b890607f567aaa
2.下一步连接container4和container5到一个新的带有别名foo和bar的网络local_alias:
$ docker network connect --link container5:foo local_alias container4 $ docker network connect --link container4:bar local_alias container5
3.附着container4并尝试ping container4的别名foo,然后尝试ping container5的别名c5:
$ docker attach container4 / # ping -w 4 foo PING foo (172.26.0.3): 56 data bytes 64 bytes from 172.26.0.3: seq=0 ttl=64 time=0.070 ms 64 bytes from 172.26.0.3: seq=1 ttl=64 time=0.080 ms 64 bytes from 172.26.0.3: seq=2 ttl=64 time=0.080 ms 64 bytes from 172.26.0.3: seq=3 ttl=64 time=0.097 ms — foo ping statistics — 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.070/0.081/0.097 ms / # ping -w 4 c5 PING c5 (172.25.0.5): 56 data bytes 64 bytes from 172.25.0.5: seq=0 ttl=64 time=0.070 ms 64 bytes from 172.25.0.5: seq=1 ttl=64 time=0.080 ms 64 bytes from 172.25.0.5: seq=2 ttl=64 time=0.080 ms 64 bytes from 172.25.0.5: seq=3 ttl=64 time=0.097 ms — c5 ping statistics — 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.070/0.081/0.097 ms
两个ping都成功了,不过子网不同,意味着网络不一样。
4.从isolated_nw网络断开container5的连接。附着container4并尝试ping c5和foo。
$ docker network disconnect isolated_nw container5 $ docker attach container4 / # ping -w 4 c5 ping: bad address 'c5' / # ping -w 4 foo PING foo (172.26.0.3): 56 data bytes 64 bytes from 172.26.0.3: seq=0 ttl=64 time=0.070 ms 64 bytes from 172.26.0.3: seq=1 ttl=64 time=0.080 ms 64 bytes from 172.26.0.3: seq=2 ttl=64 time=0.080 ms 64 bytes from 172.26.0.3: seq=3 ttl=64 time=0.097 ms --- foo ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.070/0.081/0.097 ms
你不再能通过属于isolated_nw网络的container5的别名c5到达此容器,不过你仍然能够使用别名foo到达container4。
docker网络的限制
虽然docker network命令是控制你的容器使用的网络的推荐方法,不过它有一些限制。
环境变量注入
环境变量本质上是静态的并且容器启动之后不再能更改环境变量。旧的–link参数共享所有的环境变量给链接的容器,不过docker network命令没有等同的设置。当你使用docker network连接到一个网络,容器之间的环境变量无法动态的存在。
理解网络范围的别名
旧的link提供了在配置别名的容器隔离的名称解析。网络范围的别名不允许这种方式的隔离,但是此别名在网络中的所有成员可用。
下面的示例说明了这些限制。
1.创建另一个容器container6,指定网络为isolated_nw,网络别名为app。
$ docker run --network=isolated_nw -itd --name=container6 --network-alias app busybox 8ebe6767c1e0361f27433090060b33200aac054a68476c3be87ef4005eb1df17
2.附着到container4。尝试ping container6和网络别名app。注意这两个ip是相同的。
$ docker attach container4 / # ping -w 4 app PING app (172.25.0.6): 56 data bytes 64 bytes from 172.25.0.6: seq=0 ttl=64 time=0.070 ms 64 bytes from 172.25.0.6: seq=1 ttl=64 time=0.080 ms 64 bytes from 172.25.0.6: seq=2 ttl=64 time=0.080 ms 64 bytes from 172.25.0.6: seq=3 ttl=64 time=0.097 ms --- app ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.070/0.081/0.097 ms / # ping -w 4 container6 PING container5 (172.25.0.6): 56 data bytes 64 bytes from 172.25.0.6: seq=0 ttl=64 time=0.070 ms 64 bytes from 172.25.0.6: seq=1 ttl=64 time=0.080 ms 64 bytes from 172.25.0.6: seq=2 ttl=64 time=0.080 ms 64 bytes from 172.25.0.6: seq=3 ttl=64 time=0.097 ms --- container6 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.070/0.081/0.097 ms
3.连接container6到local_alias,设置别名scoped-app。
$ docker network connect --alias scoped-app local_alias container6
现在container6在网络isolated_nw的别名为app,在local_alias网络的别名为scoped-app。
4.尝试从container4(都连接到了上面的两个网络)和container5(只连接到isolated_nw网络)ping这些别名。
$ docker attach container4 / # ping -w 4 scoped-app PING foo (172.26.0.5): 56 data bytes 64 bytes from 172.26.0.5: seq=0 ttl=64 time=0.070 ms 64 bytes from 172.26.0.5: seq=1 ttl=64 time=0.080 ms 64 bytes from 172.26.0.5: seq=2 ttl=64 time=0.080 ms 64 bytes from 172.26.0.5: seq=3 ttl=64 time=0.097 ms --- foo ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.070/0.081/0.097 ms
再附着到container5。
$ docker attach container5 / # ping -w 4 scoped-app ping: bad address 'scoped-app'
这说明了别名的作用域是在它指定的网络并且只有连接到这个网络的容器才能够访问这些别名。
将多个容器解析到同一个别名
在同一个网络中多个容器可以共享同一个网络范围别名(network-scoped alias)。下面的示例解释是如何工作的。
1.启动container7,在isolated_nw网络中设置一个与container6同样的别名app。
$ docker run --network=isolated_nw -itd --name=container7 --network-alias app busybox 3138c678c123b8799f4c7cc6a0cecc595acbdfa8bf81f621834103cd4f504554
当多个容器共享同一个别名时,这个别名将解析到这些容器的其中一个。如果那个容器不可用,别名将解析到另一个可用的。这在集群中提供了一种高可用的方法。
当别名解析出多个ip时,容器将随机的选择一个。由于这个原因,下面的示例的结果可能与你的不一样。
2.在container4持续地ping多几个app。
$ docker attach container4 $ ping app PING app (172.25.0.6): 56 data bytes 64 bytes from 172.25.0.6: seq=0 ttl=64 time=0.070 ms 64 bytes from 172.25.0.6: seq=1 ttl=64 time=0.080 ms 64 bytes from 172.25.0.6: seq=2 ttl=64 time=0.080 ms 64 bytes from 172.25.0.6: seq=3 ttl=64 time=0.097 ms ...
目前解析到了container6。
3.在另一个终端,停止container6。
$ docker stop container6
然后附着到container4观察ping的输出,当container4停机时ping会停止。
4.退出ping命令,再执行一次。
$ ping app PING app (172.25.0.7): 56 data bytes 64 bytes from 172.25.0.7: seq=0 ttl=64 time=0.095 ms 64 bytes from 172.25.0.7: seq=1 ttl=64 time=0.075 ms 64 bytes from 172.25.0.7: seq=2 ttl=64 time=0.072 ms 64 bytes from 172.25.0.7: seq=3 ttl=64 time=0.101 ms ...
现在app别名解析到了container7的ip地址。
5.最后一次测试,重启container6。
$ docker start container6
在终端中附着container4,再次执行ping命令。它可能会再次解析到container6。如果你多次启动和停止ping命令,你会发现有时解析到container6,有时是container7。
$ docker attach container4 $ ping app PING app (172.25.0.6): 56 data bytes 64 bytes from 172.25.0.6: seq=0 ttl=64 time=0.070 ms 64 bytes from 172.25.0.6: seq=1 ttl=64 time=0.080 ms 64 bytes from 172.25.0.6: seq=2 ttl=64 time=0.080 ms 64 bytes from 172.25.0.6: seq=3 ttl=64 time=0.097 ms ...
断开容器网络
你可以在任何时候使用docker network disconnect命令从一个网络断开容器。
1.从isolated_nw网络断开container2,然后查看container2和isolated_nw网络。
$ docker network disconnect isolated_nw container2 $ docker inspect --format='' container2 | python -m json.tool { "bridge": { "NetworkID":"7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812", "EndpointID": "9e4575f7f61c0f9d69317b7a4b92eefc133347836dd83ef65deffa16b9985dc0", "Gateway": "172.17.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "172.17.0.3", "IPPrefixLen": 16, "IPv6Gateway": "", "MacAddress": "02:42:ac:11:00:03" } } $ docker network inspect isolated_nw [ { "Name": "isolated_nw", "Id": "06a62f1c73c4e3107c0f555b7a5f163309827bfbbf999840166065a8f35455a8", "Scope": "local", "Driver": "bridge", "IPAM": { "Driver": "default", "Config": [ { "Subnet": "172.21.0.0/16", "Gateway": "172.21.0.1/16" } ] }, "Containers": { "467a7863c3f0277ef8e661b38427737f28099b61fa55622d6c30fb288d88c551": { "Name": "container3", "EndpointID": "dffc7ec2915af58cc827d995e6ebdc897342be0420123277103c40ae35579103", "MacAddress": "02:42:ac:19:03:03", "IPv4Address": "172.25.3.3/16", "IPv6Address": "" } }, "Options": {} } ]
2.当一个容器从一个网络断开,它就不再能够与其它连接到这个网络的容器通信,除非它还有与这些容器相同的网络。验证一下在isolated_nw网络中,container2不再能够达到container3。
$ docker attach container2 / # ifconfig eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:03 inet addr:172.17.0.3 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::42:acff:fe11:3/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:9001 Metric:1 RX packets:8 errors:0 dropped:0 overruns:0 frame:0 TX packets:8 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:648 (648.0 B) TX bytes:648 (648.0 B) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) / # ping container3 PING container3 (172.25.3.3): 56 data bytes ^C --- container3 ping statistics --- 2 packets transmitted, 0 packets received, 100% packet loss
3.验证container2仍然能够访问默认的bridge网络。
/ # ping container1 PING container1 (172.17.0.2): 56 data bytes 64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.119 ms 64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.174 ms ^C --- container1 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.119/0.146/0.174 ms / #
处理过时的网络endpoints
在一些场景中,如docker daemon在多主机网络意外的重启,daemon无法清理过时的连接endpoint。当一个新的容器连接到与过时endpoint有相同名称的网络时会导致错误。
ERROR: Cannot start container bc0b19c089978f7845633027aa3435624ca3d12dd4f4f764b61eac4c0610f32e: container already connected to network multihost
要清理这些过时的endpoints,先删除容器再强制地从网络断开它。
$ docker run -d --name redis_db --network multihost redis ERROR: Cannot start container bc0b19c089978f7845633027aa3435624ca3d12dd4f4f764b61eac4c0610f32e: container already connected to network multihost $ docker rm -f redis_db $ docker network disconnect -f multihost redis_db $ docker run -d --name redis_db --network multihost redis 7d986da974aeea5e9f7aca7e510bdb216d58682faa83a9040c2f2adc0544795a
删除网络
当在一个网络的容器都停止或断开了,你可以删除这个网络。
1.从isolated_nw断开container3。
$ docker network disconnect isolated_nw container3
2.查看isolated_nw网络验证已经没有容器连接它了。
$ docker network inspect isolated_nw [ { "Name": "isolated_nw", "Id": "06a62f1c73c4e3107c0f555b7a5f163309827bfbbf999840166065a8f35455a8", "Scope": "local", "Driver": "bridge", "IPAM": { "Driver": "default", "Config": [ { "Subnet": "172.21.0.0/16", "Gateway": "172.21.0.1/16" } ] }, "Containers": {}, "Options": {} } ]
3.删除isolated_nw网络。
$ docker network rm isolated_nw
4.列出所有网络并验证isolated_nw已经不存在。
docker network ls NETWORK ID NAME DRIVER SCOPE 4bb8c9bf4292 bridge bridge local 43575911a2bd host host local 76b7dc932e03 local_alias bridge local b1a086897963 my-network bridge local 3eb020e70bfd none null local 69568e6336d8 simple-network bridge local
版权声明:Docker用户指南(11) – Docker网络命令是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。