Docker 17
引擎 | Engine

使用网络命令(引擎) | Work with network commands (Engine)

使用网络命令

本文提供了可用于与Docker网络及其中的容器进行交互的网络子命令的示例。这些命令通过Docker Engine CLI可用。这些命令是:

  • docker network create

虽然不是必需的,但在尝试本节中的示例之前阅读Understanding Docker网络是一个好主意。这些示例使用默认bridge网络,以便您可以立即尝试。要尝试使用overlay网络,请查看“多主机网络入门指南”。

创建网络

Docker Engine bridge在安装Engine时会自动创建一个网络。该网络对应于docker0引擎传统依赖的桥梁。除了这个网络之外,你可以创建你自己的bridge或者overlay网络。

一个bridge网络驻留在运行泊坞窗引擎实例一台主机上。一个overlay网络可以跨越运行自己的引擎的多个主机。如果您docker network create只运行并提供网络名称,则会为您创建桥接网络。

$ 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" } ] }, "Containers": {}, "Options": {}, "Labels": {} } ]

bridge网络不同,overlay网络在创建之前需要一些预先存在的条件。这些条件是:

  • 访问键值存储。引擎支持Consul,Etcd和ZooKeeper(分布式存储)键值存储。

dockerd支持overlay网络的选项是:

  • --cluster-store

在创建网络时,Engine默认会为网络创建一个不重叠的子网。您可以覆盖此默认值并直接使用--subnet选项指定子网。在bridge网络上,您只能指定一个子网。一个overlay网络支持多个子网。

注意:强烈建议--subnet在创建网络时使用该选项。如果--subnet未指定,则docker守护进程会自动选择并为网络分配一个子网,并且可能会与您的基础架构中未由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

确保你的子网不重叠。如果他们这样做,网络创建失败,引擎返回错误。

创建自定义网络时,可以将其他选项传递给驱动程序。bridge驱动程序接受以下选项:

选项当量描述
com.docker.network.bridge.name-在创建Linux桥时要使用的桥名称
com.docker.network.bridge.enable_ip_masquerade--ip-伪装启用IP伪装
com.docker.network.bridge.enable_icc--icc启用或禁用容器连接
com.docker.network.bridge.host_binding_ipv4--ip绑定容器端口时的默认IP
com.docker.network.driver.mtu- 是的设置容器网络MTU

com.docker.network.driver.mtu选项也受overlay驱动程序支持。

以下参数可以传递给docker network create任何网络驱动程序。

属性当量描述
- 内部-限制对网络的外部访问
--ipv6--ipv6启用IPv6网络

以下示例-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" } ] }, "Containers": {}, "Options": { "com.docker.network.bridge.host_binding_ipv4": "172.23.0.1" }, "Labels": {} } ] $ 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支持多主机连接的网络或自定义插件,连接到相同多主机网络但从不同主机启动的容器也可以以这种方式进行通信。

此示例使用六个容器,并指导您在需要时创建它们。

基本容器网络示例

  • 首先,创建并运行两个容器,container1并且container2:$ docker run -itd --name = container1 busybox 18c062ef45ac0c026ee48a83afa39d25635ee5f02b58de4abc8f467bcaa28731 $ docker run -itd --name = container2 busybox 498eaaaf328e1018042c04b2de04036fc04719a6e39a097a4f4866043a2c2152

eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:03

eth1 Link encap:Ethernet HWaddr 02:42:AC:15:00:02

  • 使用该docker attach命令连接到运行container2并检查其网络堆栈:$ docker attach container2使用该ifconfig命令检查容器的网络堆栈。您应该看到两个以太网接口,一个用于默认bridge网络,另一个用于默认网络isolated_nw网络。$ 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范围:连接广播运行多播MTU:9001度量标准:1个RX包:8个错误:0个丢弃:0个超限:0个帧:0个TX包:8个错误:0个丢弃:0个超限:0个载波:0个冲突: 0 txqueuelen:0 RX字节:648(648.0 B)TX字节:648(648.0 B)eth1链路封装:以太网HWaddr 02:42:AC:15:00:02 inet addr:172.25.0.2 Bcast:0.0.0.0掩码: 255.255.0.0 inet6 addr:fe80 :: 42:acff:fe19:2/64适用范围:链路UP BROADCAST运行多播MTU:1500度量标准:1 RX包:8个错误:0丢弃:0超限:0帧:0 TX包: 8个错误:0丢弃:0超限:0载波:

即使容器未运行,您也可以将容器连接到网络。但是,docker network inspect只显示运行容器的信息。

链接容器而不使用用户定义的网络

完成基本容器网络示例中的步骤后,container2可以container3自动解析名称,因为两个容器都连接到isolated_nw网络。但是,连接到默认bridge网络的容器无法解析彼此的容器名称。如果您需要容器能够通过bridge网络相互通信,则需要使用旧式链接功能。这--link是推荐使用的唯一用例。您应该强烈考虑使用用户定义的网络。

使用遗留link标志为默认bridge网络上的通信之间的通信添加以下功能:

  • 将容器名称解析为IP地址的功能

重申一下,当您使用用户定义的网络时,所有这些功能都是默认提供的,无需其他配置。此外,您还可以动态连接到多个网络并从多个网络分离。

  • 使用DNS的自动名称解析

以下示例简要介绍如何使用--link

  • 继续上面的例子,创建一个新的容器,container4并将其连接到网络isolated_nw。另外,container5使用该--link标志将其链接到容器(尚不存在!)。$ docker run --network = isolated_nw -itd --name = container4 --link container5c5 busybox 01b5df970834b77a9eadbaff39051f237957bd35c4c56f11193e0594cfd5117c这有点棘手,因为container5还不存在。当container5创建,container4将能够解决的名字c5container5的IP地址。 注意:使用旧链接创建的容器之间的任何链接本质上都是静态的,并将容器与别名进行硬绑定。它不容忍链接的容器重新启动。新的链接 用户定义网络中的功能支持容器之间的动态链接,并允许在链接容器中重新启动和IP地址更改。

既然你还没有创建容器container5试图ping它会导致错误。附加container4并尝试ping任一container5或者c5

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

container4使用中分离并保持运行CTRL-p CTRL-q

  • 创建另一个名为的容器container5,并将其链接到container4使用别名c4。$ docker run --network = isolated_nw -itd --name = container5 --link container4c4 busybox 72eccf2208336f31e9e33ba327734125af00d1e1d2657878e2ee8154fbb23c7a现在连接container4并尝试ping c5container5。$ docker attach container4 /#ping -w 4 c5 PING c5(172.25.0.5):56数据字节来自172.25.0.5的64字节:seq = 0 ttl = 64时间= 0.070 ms来自172.25.0.5的64字节:seq = 1 ttl = 64时间= 0.080毫秒来自172.25.0.5的64字节:seq = 2 ttl = 64时间= 0.080毫秒来自172.25.0.5的64字节:seq = 3 ttl = 64时间= 0.097 ms --- c5 ping statistics --- 4发送数据包,接收到4个数据包,0%丢包往返最小/平均/最大= 0.070 / 0.081 / 0.097 ms /#ping -w 4 container5 PING container5(172.25.0.5):56个数据字节64个字节从172.25.0.5 :seq = 0 ttl = 64时间= 0.070 ms来自172.25.0.5的64字节:seq = 1 ttl = 64时间= 0.080 ms来自172.25.0.5的64字节:seq = 2 ttl = 64时间= 0.080 ms来自172.25的64字节。 0.5:seq = 3 ttl = 64时间= 0.097 ms --- container5 ping statistics ---发送4个数据包,接收4个数据包,0%丢包往返最小/平均/最大= 0.070 / 0.081 / 0。container4并让它继续使用CTRL-p CTRL-q

网络别名范围示例

链接容器时,无论是使用传统link方法还是使用用户定义的网络,您指定的任何别名仅对指定的容器有意义,并且不适用于默认bridge网络上的其他容器。

另外,如果一个容器属于多个网络,则给定的链接别名在给定的网络范围内。因此,容器可以链接到不同网络中的不同别名,并且别名对于不在同一网络中的容器不起作用。

以下示例说明了这些要点。

  • 创建名为的另一个网络local_alias:$ docker network create -d bridge --subnet 172.26.0.0/24 local_alias 76b7dc932e037589e6553f59f76008e5b76fa069638cd39776b890607f567aaa

docker networkd的限制

虽然docker network是控制容器使用网络的推荐方式,但确实存在一些限制。

环境变量注入

环境变量注入本质上是静态的,在启动容器后环境变量不能被改变。遗留--link标志将所有环境变量共享到链接的容器,但该docker network命令没有等效。当使用容器连接到网络时docker network,不能在容器间动态共享环境变量。

使用网络范围的别名

传统链接提供在配置别名的容器内隔离的传出名称解析。网络范围的别名不允许进行此单向隔离,但为网络的所有成员提供别名。

以下示例说明了此限制。

  • 创建另一个container6在网络中调用的容器isolated_nw并为其提供网络别名app。$ docker run --network = isolated_nw -itd --name = container6 --network-alias app busybox 8ebe6767c1e0361f27433090060b33200aac054a68476c3be87ef4005eb1df17

这表明一个别名的作用范围是它定义的网络,只有连接到该网络的容器才能访问该别名。

将多个容器解析为单个别名

多个容器可以在同一个网络中共享相同的网络范围别名。这提供了一种DNS循环高可用性。这在使用Nginx等软件时可能不可靠,该软件通过IP地址缓存客户端。

以下示例说明如何设置和使用网络别名。

注意:那些使用网络别名进行DNS轮询高可用性的应该考虑使用swarm服务。Swarm服务提供了一个类似的负载均衡功能。如果连接到任何节点,即使是没有参与服务的节点。Docker将请求发送给参与服务的随机节点并管理所有通信。

  • 启动container7isolated_nw用相同的别名container6,这是app。$ docker run --network = isolated_nw -itd --name = container7 --network-alias app busybox 3138c678c123b8799f4c7cc6a0cecc595acbdfa8bf81f621834103cd4f504554当多个容器共享相同的别名时,其中一个容器将解析为别名。如果该容器不可用,则另一个具有别名的容器将被解析。这在集群内提供了一种高可用性。 注意:IP地址解析后,选择解析IP地址的容器不是完全可预测的。因此,在下面的练习中,您可能会在某些步骤中得到不同的结果。如果该步骤假设返回的结果是container6但你得到container7,这就是为什么。

断开容器

您可以随时使用docker network disconnect命令将容器与网络断开连接。

  • 断开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": {} } ]

处理陈旧的网络端点

在一些情况下,例如不可靠的docker守护进程会在多主机网络中重新启动,守护进程无法清除过时的连接端点。如果新容器与旧网点的名称相同,则此类旧网点可能会导致错误:

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

要清理这些陈旧的端点,请移除容器并强行断开它与网络的连接(docker network disconnect -f)。现在您可以成功将容器连接到网络。

$ 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

删除网络

当网络中的所有容器都停止或断开连接时,您可以删除网络。如果网络连接了端点,则会发生错误。

  • 断开container3isolated_nw。$ docker network disconnect isolated_nw container3

相关信息

  • network create

commands, Usage, network, docker, cluster