使用网络命令(引擎) | 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
网络。$ sudoifconfig
-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
container5
:c5
busybox 01b5df970834b77a9eadbaff39051f237957bd35c4c5
6f11193e0594cfd5117c这有点棘手,因为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'
从container4
使用中分离并保持运行CTRL-p CTRL-q
。
- 创建另一个名为的容器
container5
,并将其链接到container4
使用别名c4
。$ docker run --network = isolated_nw -itd --name =container5
--linkcontainer4
:c4
busybox 72eccf2208336f31e9e33ba327734125af00d1e1d2657878e2ee8154fbb23c7a现在连接container4
并尝试pingc5
和container5
。$ docker attachcontainer4
/#ping -w 4c5
PINGc5
(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 4container5
PINGcontainer5
(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/24local_alias
76b7dc932e037589e6553f59f76008e5b76fa069638cd39776b890607f567aaa
docker networkd的限制
虽然docker network
是控制容器使用网络的推荐方式,但确实存在一些限制。
环境变量注入
环境变量注入本质上是静态的,在启动容器后环境变量不能被改变。遗留--link
标志将所有环境变量共享到链接的容器,但该docker network
命令没有等效。当使用容器连接到网络时docker network
,不能在容器间动态共享环境变量。
使用网络范围的别名
传统链接提供在配置别名的容器内隔离的传出名称解析。网络范围的别名不允许进行此单向隔离,但为网络的所有成员提供别名。
以下示例说明了此限制。
- 创建另一个
container6
在网络中调用的容器isolated_nw
并为其提供网络别名app
。$ docker run --network =isolated_nw
-itd --name =container6
--network-aliasapp
busybox 8ebe6767c1e0361f27433090060b33200aac054a68476c3be87ef4005eb1df17
这表明一个别名的作用范围是它定义的网络,只有连接到该网络的容器才能访问该别名。
将多个容器解析为单个别名
多个容器可以在同一个网络中共享相同的网络范围别名。这提供了一种DNS循环高可用性。这在使用Nginx等软件时可能不可靠,该软件通过IP地址缓存客户端。
以下示例说明如何设置和使用网络别名。
注意
:那些使用网络别名进行DNS轮询高可用性的应该考虑使用swarm服务。Swarm服务提供了一个类似的负载均衡功能。如果连接到任何节点,即使是没有参与服务的节点。Docker将请求发送给参与服务的随机节点并管理所有通信。
- 启动
container7
在isolated_nw
用相同的别名container6
,这是app
。$ docker run --network =isolated_nw
-itd --name =container7
--network-aliasapp
busybox 3138c678c123b8799f4c7cc6a0cecc595acbdfa8bf81f621834103cd4f504554当多个容器共享相同的别名时,其中一个容器将解析为别名。如果该容器不可用,则另一个具有别名的容器将被解析。这在集群内提供了一种高可用性。注意
:IP地址解析后,选择解析IP地址的容器不是完全可预测的。因此,在下面的练习中,您可能会在某些步骤中得到不同的结果。如果该步骤假设返回的结果是container6
但你得到container7
,这就是为什么。
断开容器
您可以随时使用docker network disconnect
命令将容器与网络断开连接。
- 断开
container2
与isolated_nw
网络,然后检查container2
和isolated_nw
网络。$ docker network disconnectisolated_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 inspectisolated_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
删除网络
当网络中的所有容器都停止或断开连接时,您可以删除网络。如果网络连接了端点,则会发生错误。
- 断开
container3
的isolated_nw
。$ docker network disconnectisolated_nw
container3
相关信息
- network create