翻译自docker官方文档,原文:https://docs.docker.com/engine/userguide/networking/work-with-networks/

这篇文章提供了几个你可以用来和docker网络及其中的容器进行交互的网络子命令的例子。这些命令可以通过docker引擎的命令行接口(CLI)使用,命令如下:

  • docker network create
  • docker network connect
  • docker network ls
  • docker network rm
  • docker network disconnect
  • docker network inspect

虽然不是必须的,但在尝试本章中介绍的例子之前读一下docker网络简介的文章(已翻译,就是这篇:http://blog.csdn.net/zlw01234/article/details/79237651)是有好处的。
下面的例子用的是默认的bridge网络,所以你可以直接开始实验。要用overlay式网络尝试这些例子,请查看另一篇文章(未翻译,原文章地址:https://docs.docker.com/engine/userguide/networking/get-started-overlay/)。

创建网络

当你安装docker的时候,docker引擎会自动创建一个bridge网络。这个网络会和叫做docker0的网桥(在宿主机上,可以通过ifconfig查看)通信,而且docker引擎已经连到docker0上了。除了这个网络,你也可以创建你自己的桥接式(bridge)或overlay式网络。
bridge式网络只能用于安装有docker引擎的单主机上。而overlay式网络可以连通多台有docker引擎的主机。当你运行docker network create命令并且只提供了一个网络名时,它会给你创建一个bridge式网络。

$ docker network create simple-network69568e6336d8c96bbf57869030919f7c69524f71183b44d80948bd3927c87f6a$ 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"}]},"Containers": {},"Options": {},"Labels": {}}
]

和bridge式网络不同的是,overlay式网络在创建前需要一些先决条件,这些条件是:

  • 能访问一个键值对式的存储空间,docker引擎支持Consul, Etcd, 和 ZooKeeper (分布式存储) 。
  • 一个能连到键值对存储空间的集群。
  • 集群中主机上的docker守护进程都正确配置了。

支持overlay式网络的dockerd选项有:

  • --cluster-store
  • --cluster-store-opt
  • --cluster-advertise

当你创建网络时,引擎会自动给这个网络创建一个不重叠的子网(译者注:指在docker管理的所有网络中不重叠)。你可以用--subnet选项来直接指定子网并覆盖默认值。在bridge式网络中,你只能指定一个子网,在overlay式网络中你可以指定多个子网。

注意:强烈建议在创建网络时使用--subnet参数。如果没指定,docker守护进程会自动从网络中选择并分配一个子网,而这个子网可能覆盖你硬件中不由docker管理的另一个子网。这种覆盖现象可能导致容器连到这个网络时出问题或失败。

除了--subnet参数,你还可以指定--getway--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

要确保你的子网没有重叠,否则创建网络会失败,docker会返回一个错误。
当创建自定义网络时,可以传递一些额外的参数。bridge式网络接受的参数有:

参数 等价于 描述
com.docker.network.bridge.name - 创建Linux网桥设备时的网桥名称
com.docker.network.bridge.enable_ip_masquerade --ip-masq 是否允许IP伪装
com.docker.network.bridge.enable_icc --icc 是否允许网络内的容器连通
com.docker.network.bridge.host_binding_ipv4 --ip 绑定容器端口时默认的IP
com.docker.network.driver.mtu --mtu 设置容器网络的MTU

com.docker.network.driver.mtu参数也适用于overlay式的网络。
下面的参数可以在创建任何形式的网络时传给docker network create

参数 等价于 描述
--internal - 限制外部访问到网络
--ipv6 --ipv6 允许IPv6的网络

下面的例子使用-o参数指定了特定的当绑定端口时可用的IP地址,然后用docker network inspect检查网络,最后把一个新的容器添加到这个网络。记得把例子中的172.23.0.1替换成你宿主机所在网络中可用的IP地址。

$ docker network create -o "com.docker.network.bridge.host_binding_ipv4"="172.23.0.1" my-networkb1a086897963e6a2e7fc6868962e55e746bee8ad0c97b54a5831054b5f62672a$ 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"}]},"Containers": {},"Options": {"com.docker.network.bridge.host_binding_ipv4": "172.23.0.1"},"Labels": {}}
]$ docker run -d -P --name redis --network my-network redisbafb0c808c53104b2c90346f284bda33a69beadcab4fc83ab8f2c5a4410cd129$ docker psCONTAINER 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式网络或支持多主机互联的自定义插件来说,不同主机上的连到同一个多主机网络的容器也能以相同的方式进行通信。
下面的例子使用了6个容器,当你需要他们的时候会指导你创建的。

基础容器网络示例

1.首先,创建并运行两个容器container1container2

$ docker run -itd --name=container1 busybox18c062ef45ac0c026ee48a83afa39d25635ee5f02b58de4abc8f467bcaa28731$ docker run -itd --name=container2 busybox498eaaaf328e1018042c04b2de04036fc04719a6e39a097a4f4866043a2c2152

2.创建一个用于测试的隔离的bridge式网络:

$ docker network create -d bridge --subnet 172.25.0.0/16 isolated_nw06a62f1c73c4e3107c0f555b7a5f163309827bfbbf999840166065a8f35455a8

3.把container2连到网络,并检查(inspect)网络来检查连通性:

$ 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 busybox467a7863c3f0277ef8e661b38427737f28099b61fa55622d6c30fb288d88c551

只要一个IP地址是子网的一部分,你就可以把这个IP指定给一个要连到该子网的容器,通过--ip--ip6选项。当你使用一个用户定义的网络时,用这种方式指定IP地址的话,这个配置会作为容器的配置的一部分被保护起来,并且在容器重新启动时会生效。用非用户定义的网络(docker自带的)时,分配的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所用的网络资源,如果你安装了python,你可以美化输出:

$ 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网络,然后你在第三步的时候又把它连到了isolated_nw.

7.用docker attach命令连到正在运行的container2,并检查它的网络:

$ docker attach container2

ifconfig命令检查容器的网络。你应该会看到两个以太网接口,一个是默认的bridge网络,另一个是isolated_nw网络。

# 原文确实有sudo,但我试的时候提示sudo:not found,把sudo去掉就行
$ sudo ifconfig -aeth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:03inet addr:172.17.0.3  Bcast:0.0.0.0  Mask:255.255.0.0inet6 addr: fe80::42:acff:fe11:3/64 Scope:LinkUP BROADCAST RUNNING MULTICAST  MTU:9001  Metric:1RX packets:8 errors:0 dropped:0 overruns:0 frame:0TX packets:8 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0RX bytes:648 (648.0 B)  TX bytes:648 (648.0 B)eth1      Link encap:Ethernet  HWaddr 02:42:AC:15:00:02inet addr:172.25.0.2  Bcast:0.0.0.0  Mask:255.255.0.0inet6 addr: fe80::42:acff:fe19:2/64 Scope:LinkUP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1RX packets:8 errors:0 dropped:0 overruns:0 frame:0TX packets:8 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0RX bytes:648 (648.0 B)  TX bytes:648 (648.0 B)lo        Link encap:Local Loopbackinet addr:127.0.0.1  Mask:255.0.0.0inet6 addr: ::1/128 Scope:HostUP LOOPBACK RUNNING  MTU:65536  Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0RX 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网络中不可用。container1container2都连到了bridge网络,但你不能在container2中用容器名ping通container1:

/ # ping -w 4 container1
ping: bad address 'container1'

你还是可以直接用IPping通container1:

/ # 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

CTRL-p CTRL-q来离开container2并让它保持运行。

9.现在,container2同时连到了bridgeisolated_nw,所以它能和container1container3通信。但是container1container3没有公共的网络,所以他们不能通信。要验证这个,可以attachcontainer3然后尝试用IP来pingcontainer1.

$ 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

CTRL-p CTRL-q来离开container3并让它保持运行。

你甚至可以把一个没在运行的容器连到一个网络。但是,docker network inspect只会显示正在运行的容器的信息。

不使用用户定义的网络来连接容器

在你完成基础容器网络示例后,container2可以自动解析container3的容器名,因为他们都连到了isloated_nw网络。但是,连到默认的bridge网络的容器不能解析彼此的容器名。如果你需要bridge网络中的容器能够互联,你需要使用遗留的link特性。这是--link参数唯一推荐的使用场景。强烈建议你使用用户定义的网络。
使用遗留的link特性会在默认的bridge网络间通信中增加以下特性:

  • 把容器名解析为IP地址的能力
  • 给被连接的容器指定一个网络别名,通过使用--link=CONTAINER-NAME:ALIAS
  • 安全的容器间连接(要隔离可以使用 --icc=false
  • 注入环境变量

要重申一下,当你使用用户定义的网络时,所有这些特性都是默认提供的,完全不用额外的配置。另外,你还能得到动态连接或断开多个网络的能力

  • 用DNS自动解析容器名
  • 支持用--link参数给被连接的容器指定别名
  • 自动给网络内的容器提供安全隔离环境
  • 注入环境变量

下面的例子简要介绍了任何使用--link
1.接着上面的例子,创建一个新容器container4,把它连到isolated_nw网络上。另外,用--link参数把它连到container5(还不存在!)。

$ docker run --network=isolated_nw -itd --name=container4 --link container5:c5 busybox01b5df970834b77a9eadbaff39051f237957bd35c4c56f11193e0594cfd5117c

这有点奇怪,因为container5还不存在。当container5被创建的时候,container4可以用c5这个名字解析出container5的IP地址。
注意:任何用遗留的link特性创建的容器间的连接天生都是静态的,而且是把别名硬关联到容器的。它不能处理被连接的容器重启的情况。而在用户定义的网络中能用的新的link特性支持动态链接,而且能处理被连接的容器重启和IP变化的情况。

由于你还没有创建容器container5,尝试ping它会报错。连到container4并尝试pingcontainer5c5

$ docker attach container4$ ping container5ping: bad address 'container5'$ ping c5ping: bad address 'c5'

CTRL-p CTRL-q来离开container4并让它保持运行。

2.创建另一个容器container5,用别名c4连到container4

$ docker run --network=isolated_nw -itd --name=container5 --link container4:c4 busybox72eccf2208336f31e9e33ba327734125af00d1e1d2657878e2ee8154fbb23c7a

现在连到container4,尝试pingcontaienr5c5

$ 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

CTRL-p CTRL-q来离开container4并让它保持运行。
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

CTRL-p CTRL-q来离开container5并让它保持运行。

网络别名有效范围的例子

当你连接容器时,不管是用遗留的link方法还是自定义的网络,你指定的别名都只对所指定的容器有意义,而且在默认的bridge网络中对其他容器都没用。
另外,如果一个容器属于多个网络,给定的一个连接时的别名只能限定在一个网络。因此,一个容器能在不同网络中指定不同的别名,而且别名对不在同一网络内的容器不可见。
下面的例子说明了这些情况:
1.创建一个叫local_alias的网络:

$ docker network create -d bridge --subnet 172.26.0.0/24 local_alias
76b7dc932e037589e6553f59f76008e5b76fa069638cd39776b890607f567aaa

2.接下来,把容器container4container5连到网络local_alias,并指定别名:foobar:

$ docker network connect --link container5:foo local_alias container4
$ docker network connect --link container4:bar local_alias container5

3.进入container4并尝试用别名foo来pingcontainer4 (没错,就是它自己)(译者注:这里很奇怪,foo应该是container5的别名,而且我试的时候确实解析到的是container5的IP),然后尝试用别名c5来pingcontainer5:

 $ docker attach container4/ # ping -w 4 fooPING foo (172.26.0.3): 56 data bytes64 bytes from 172.26.0.3: seq=0 ttl=64 time=0.070 ms64 bytes from 172.26.0.3: seq=1 ttl=64 time=0.080 ms64 bytes from 172.26.0.3: seq=2 ttl=64 time=0.080 ms64 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 lossround-trip min/avg/max = 0.070/0.081/0.097 ms/ # ping -w 4 c5PING c5 (172.25.0.5): 56 data bytes64 bytes from 172.25.0.5: seq=0 ttl=64 time=0.070 ms64 bytes from 172.25.0.5: seq=1 ttl=64 time=0.080 ms64 bytes from 172.25.0.5: seq=2 ttl=64 time=0.080 ms64 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 lossround-trip min/avg/max = 0.070/0.081/0.097 ms

两次都ping通了,但经过但子网不同,证明走了不同的网络。
CTRL-p CTRL-q来离开container4并让它保持运行。

4.把container5isolated_nw中断开,再连到container4并尝试pingc5foo

$ 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了。但你还可以通过别名foo到达container4(从container4)(译者注:跟上面一样,我觉得foo是container5的别名,所以这两处都应该是到达container5)。
CTRL-p CTRL-q来离开container4并让它保持运行。

docker network的限制

虽然docker network是控制容器网络的推荐方式,但它确实有些限制。

环境变量注入

环境变量注入是静态的,而且容器启动后就不能修改。遗留的--link参数会和被连接的容器共享所有环境变量,但docker network命令不同。当你用docker network把一个容器连到一个网络时,环境变量不能在容器间进行动态共享。

使用网络限定的别名

遗留的link可以给单独的配置了别名的容器提供名字解析。网络限定的别名不能提供这样的隔离,而是把这个别名提供给网络内的所有容器。
下面的例子说明了这种限制。
(译者注:个人觉得下面的例子跟上面的观点没啥关联,要证明上面的观点,可以新建一个容器c7,加到isolated_nw,用–link指定container4的别名c4,然后实验c7能连到c4,但其他容器不能解析c4这个别名)
1.创建另一个容器container6,连到isolated_nw,并给它一个别名app

$ docker run --network=isolated_nw -itd --name=container6 --network-alias app busybox8ebe6767c1e0361f27433090060b33200aac054a68476c3be87ef4005eb1df17

2.进入container4。尝试用容器名container6和网络别名app来ping容器。注意解析到的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 container6 (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

CTRL-p CTRL-q来离开container4并让它保持运行。

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)中连接这两个别名。

$ 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

CTRL-p CTRL-q来离开container4并让它保持运行。

$ docker attach container5/ # ping -w 4 scoped-app
ping: bad address 'scoped-app'

CTRL-p CTRL-q来离开container5并让它保持运行。
这表明别名被限定在它所定义的网络内,只有网络内的容器能访问到这个别名。

把多个容器解析到一个别名

在一个网络内的多个容器能共享一个网络限定的别名。这提供了一种DNS轮询调度形式的高可用。当使用可能缓存IP地址的软件,如nginx时,这个特性可能不稳定。
下面的例子展示了如何设置并使用网络别名。

注意:使用网络别名来做DNS轮询高可用的场景应该考虑使用集群服务(swarm services)代替。集群服务提供了开箱即用的负载均衡特性。当你连到任一节点,即使是不提供服务的节点时,docker都会把请求发给随机的一个提供服务的节点并管理所有的通信。

1.在网络isolated_nw中启动container7并指定和container6相同的别名app

$ docker run --network=isolated_nw -itd --name=container7 --network-alias app busybox3138c678c123b8799f4c7cc6a0cecc595acbdfa8bf81f621834103cd4f504554

当多个容器共享一个别名时,其中的一个会解析到该别名,如果这个容器挂了,别名会解析到另一个容器,这提供了一种集群内的高可用。

注意:当IP地址被解析到后,被选到的容器是不可预测的。因此,在下面的例子中,在某些步中你可能会得到不同的结果。如果某步的结果返回了container6而你的结果是container7,这就是原因。

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
...

返回的IP是container6的。
3.在另一个终端,关掉container6

$ docker stop container6

再进入container4的终端,观察结果输出。当container6停掉后,ping会卡住,因为它是在第一次启动的时候查找IP的,而最初找到的哪个IP已经不可用了。但是ping命令默认有很长的超时时间,所以没有错误输出。
4.用CTRL+c停掉ping,再次运行ping。

$ ping appPING 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
...

这次解析到了container7的IP。
5.最后一个测试,重启container6

$ docker start container6

在进入container4的终端,再次运行ping命令。他应该再次解析到container6。如果你多个重试ping命令,两个容器的IP你应该都能看到。

$ 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
...

CTRL+C停掉ping。用CTRL-p CTRL-q来离开container4并让它保持运行。

断开容器

你在任何时间可以把容器从一个网络中断开,通过docker network disconnect命令。
1.把container2isolated_nw中断开,然后检查container2isolated_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.当一个容器从一个网络中断开时,它就不能再和网络中的其他容器通信了,除非他们有其他的公共网络。验证container2不能在连到isolated_nw中的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.0inet6 addr: fe80::42:acff:fe11:3/64 Scope:LinkUP BROADCAST RUNNING MULTICAST  MTU:9001  Metric:1RX packets:8 errors:0 dropped:0 overruns:0 frame:0TX packets:8 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0RX 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.0inet6 addr: ::1/128 Scope:HostUP LOOPBACK RUNNING  MTU:65536  Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0RX 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
/ #

4.删掉 container4, container5, container6, 和 container7.

$ docker stop container4 container5 container6 container7$ docker rm container4 container5 container6 container7

处理失效的网络终端

在某些情况下,比如在多主机网络中不平滑地重启docker守护进程,守护进程不能清除失效的连接终端。这种失效的终端可能导致错误,当一个新容器用和失效的终端一样的名字加入网络时:

ERROR: Cannot start container bc0b19c089978f7845633027aa3435624ca3d12dd4f4f764b61eac4c0610f32e: container already connected to network multihost

要清除这些失效的终端,删掉容器并强制把他们从网络中断开(docker network disconnect -f)。这样你就能把这些容器连到网络了。

$ docker run -d --name redis_db --network multihost redisERROR: 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 redis7d986da974aeea5e9f7aca7e510bdb216d58682faa83a9040c2f2adc0544795a

删除网络

当网络内的所有容器都停止或断开后,你就能把网络删除了,如果网络还有连接的终端,删除会报错。
1.把container3断开isolated_nw.

$ 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 lsNETWORK 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网络相关命令相关推荐

  1. linux中级篇--网络相关命令

    网络相关命令 Linux中常见的网络相关命令如下表所示,本书将选取其中使用较频繁的命令进行讲解. 命令 说明 格式 ifconfig 显示或设置网络设备 ifconfig [网络设备][选项]- pi ...

  2. nova 命令汇总三 ——网络相关命令

    nova 命令汇总三 --网络相关命令 和网络相关的操作主要包括:add-fixed-ip.add-floating-ip.add-secgroup.fixed-ip-get .fixed-ip-re ...

  3. linux下常见的网络相关命令

    linux中环境部署.网络排查要用到非常多的命令,掌握一些核心的相关命令非常有必要.下面介绍几个工作和面试中高频提及的网络相关命令. ifconfig ifconfig 是一个用来查看.配置.启用或禁 ...

  4. DOS下常用网络相关命令解释(华为培训资料)

    DOS下常用网络相关命令解释 深圳市华为技术有限公司 华为技术 第一章引言 1. 概述 在我们的工作之中经常要和网络打交道而win95/98或是NT又是较常用的操 作系统在使用这些操作系统过程中使用频 ...

  5. [运维笔记] - (命令).Windows server常用网络相关命令

    [运维] - Windows server网络相关命令 注:内容通过Microsoft文档整体和翻译,仅用于便于维护工作时查询. 资料翻译者:jcLee95 邮箱:291148484@163.com ...

  6. 第十五天 11-常见的网络相关命令

    linux常见的网络相关命令 1.ping命令 简介: 在网络中ping是一个十分强大的TCP/IP工具.它的作用主要为: (1)用来检测网络的连通情况和分析网络速度: (2)根据域名得到服务器IP: ...

  7. Linux网络相关命令

    Linux网络相关命令 1 ping 2 netstat 3 tranceroute 4 ARP 5 tcpdump 1 ping 作用:检测当前主机与目标主机之间的连通性(不是100%准确,有的服务 ...

  8. 端口扫描分析(一)常用的网络相关命令

    发信人: Heway (陶陶), 信区: Internet_program 标  题: 端口扫描分析(一)常用的网络相关命令 发信站: 飘渺水云间 (Sun Mar 19 14:47:35 2000) ...

  9. Docker网络相关

    Docker中网络功能相关Docker是允许通过外部访问容器或者容器互联的方式来提供网络服务.外部访问容器:通过-P或者-p参数指定端口映射,-P是随机:-p是指定.-P : Docker会随机映射一 ...

最新文章

  1. Redis分布式锁实现
  2. 恒位油杯故障原因_厂家详解干式真空泵故障分析与保养办法
  3. CSDN博客图片居中问题解决方案
  4. asyn4j -- java 异步方法调用框架
  5. 偷用计算机作文,偷玩电脑作文500字
  6. 【无码专区6】球与盒子(数学线性筛)
  7. 漫谈C++:良好的编程习惯与编程要点
  8. 开源cms 和 开源博客_BackBee CMS如何以及为何开源
  9. 10款开源网上教学课程管理系统
  10. opencv学习笔记(三)分离颜色通道多通道颜色混合
  11. IP138 IP地址查询 php实例
  12. 小博老师浅谈Context(一)
  13. 绝地求生显示lsukn服务器,电脑中玩绝地求生出现Failed to initialize BattlEye Service:Generic Error怎么办...
  14. MapReduce之多MapReduce执行
  15. 人大金仓 过期 更换license
  16. JSON.parse 转换字符串样式的数组
  17. 百万富翁问题--安全多方计算
  18. 事件营销此起彼伏,效果决定未来
  19. extmail mysql数据库 重启_extmail数据库dspam表修复
  20. 百度关键词排名查询工具

热门文章

  1. python通信工程书籍_年末,等来了这几本重磅新书:深度学习、Python、机器学习......
  2. redis统计用户日活量_Redis精确去重计数方法(咆哮位图)
  3. 抛开Spring来说,如何自己实现Spring AOP?
  4. UG NX 12 过滤选取
  5. [东拼西凑]STM32单片机启动流程及RAM和Flash的配置关系和堆栈溢出现象
  6. 程序员的短板及其克服之道
  7. bootstrap的icheck插件使用
  8. linux 的i18n 文件夹,linux i18n文件分析
  9. 我记:交2中,突破boll线上轨,是否继续买入?
  10. 和你生活最近的淘宝天猫背后,阿里还有一个你不知道的神秘组织