1. 使用网桥网络
就网络而言,桥接网络是在网段之间转发流量的链路层设备。桥接器可以是在主机内核中运行的硬件设备或软件设备。
就 Docker 而言,桥接网络使用一个软件桥接器,它允许连接到同一桥接网络的容器进行通信,同时提供与未连接到桥接网络的容器的隔离。 Docker 桥接驱动程序在主机上自动安装规则,使不同桥接网络上的容器不能直接相互通信。
桥接网络应用于运行在同一个 Docker 守护进程主机上的容器。 对于运行在不同 Docker 守护进程主机上的容器之间的通信,您可以在操作系统级别管理路由,也可以使用覆盖网络
。
启动Docker时,会自动创建一个默认的桥接网络
(也称为bridge
),除非另有说明,否则新启动的容器将连接到它。您还可以创建用户定义的自定义网桥网络。用户定义的网桥网络优于默认bridge
网络。
1.1 用户定义的网桥和默认网桥之间的区别
用户定义的桥接提供了更好的隔离和容器化应用程序之间的互操作性。
连接到相同的用户定义桥接网络的容器自动将所有端口相互公开,而不向外部世界公开端口。 这使得容器化的应用程序可以轻松地相互通信,而不会意外地打开对外部世界的访问。
想象一下,一个应用程序有一个 web 前端和一个数据库后端。 外部世界需要访问 web 前端(可能在端口80上) ,但只有后端本身需要访问数据库主机和端口。 使用用户定义的网桥,只需要打开 web 端口,数据库应用程序不需要打开任何端口,因为 web 前端可以通过用户定义的网桥到达它。
如果在缺省桥接网络上运行相同的应用程序堆栈,则需要同时打开 web 端口和数据库端口,并为每个端口使用-p 或 – publish 标志。 这意味着 Docker 主机需要通过其他方式阻止对数据库端口的访问。
用户定义的网桥可在容器之间提供自动DNS解析。
默认桥网络上的容器只能通过 IP 地址访问彼此,除非您使用 – link 选项,这被认为是遗留的。 在用户定义的网桥网络上,容器可以通过名称或别名相互解析。
想象一下与前一点相同的应用程序,它有一个 web 前端和一个数据库后端。 如果你调用你的容器 web 和 db,web 容器可以连接到 db 容器,不管 Docker 主机上运行的应用程序堆栈是什么。
如果在默认网桥网络上运行相同的应用程序堆栈,则需要在容器之间手动创建链接(使用旧式–link 标志)。这些链接需要双向创建,因此您可以看到,要进行通信的容器超过两个,这将变得很复杂。另外,您可以操纵/etc/hosts容器中的文件,但这会产生难以调试的问题。
容器可以随时随地从用户定义的网络连接和分离。
在容器的生命周期内,您可以即时将其与用户定义的网络连接或断开连接。要从默认桥接网络中删除容器,您需要停止容器并使用其他网络选项重新创建它。
每个用户定义的网络都会创建一个可配置的网桥。
如果您的容器使用默认桥接网络,则可以对其进行配置,但是所有容器都使用相同的设置,例如MTU和iptables规则。另外,配置默认桥接网络发生在Docker本身之外,并且需要重新启动Docker。
使用
docker network create
创建和配置用户定义的桥接网络。 如果不同的应用程序组有不同的网络需求,您可以在创建用户定义的桥接时分别配置它。默认网桥网络上的链接容器共享环境变量。
最初,在两个容器之间共享环境变量的唯一方法是使用 – link 标志将它们链接起来。 这种类型的变量共享在用户定义的网络中是不可能的。 但是,有一些共享环境变量的优秀方法。 以下是一些建议:
多个容器可以使用Docker卷挂载包含共享信息的文件或目录。
使用可以一起启动多个容器docker-compose,并且compose文件可以定义共享变量。
您可以使用群体服务代替独立容器,并利用共享的
secrets
和configs
。
连接到同一个用户定义的桥接网络的容器有效地将所有端口相互暴露。 对于不同网络上的容器或非 docker 主机可以访问的端口,必须使用 -p 或 – publish 标志发布该端口。
1.2 管理用户定义的网桥
使用该docker network create命令创建用户定义的网桥网络。
docker network create my-net
您可以指定子网,IP地址范围,网关和其他选项。
使用docker network rm
命令删除用户定义的网桥网络。如果容器当前已连接到网络, 请先断开它们。
docker network rm my-net
⚠ 到底发生了什么事?
当您创建或删除用户定义的桥接或从用户定义的桥接连接或断开容器时,Docker 使用特定于操作系统的工具来管理底层网络基础设施(例如添加或删除桥接设备或在 Linux 上配置 iptables 规则)。 这些细节应该被视为实现细节。 让 Docker 为您管理用户定义的网络。
1.3 将容器连接到用户定义的网桥
创建新容器时,可以指定一个或多个网络标志。 此示例将 Nginx 容器连接到 my-net
网络。 它还将容器中的端口80发布到 Docker 主机上的端口8080,这样外部客户机就可以访问该端口。 连接到 my-net
网络的任何其他容器都可以访问 my-nginx
容器上的所有端口,反之亦然。
docker create --name my-nginx \
--network my-net \
--publish 8080:80 \
nginx:latest
若要将正在运行的容器连接到现有的用户定义桥接器,请使用 docker network connect
命令。 下面的命令将一个已经运行的 my-nginx
容器连接到一个已经存在的 my-net
网络:
docker network connect my-net my-nginx
1.4 断开容器与用户定义的网桥的连接
若要断开正在运行的容器与用户定义的桥接器的连接,请使用 docker network disconnect
命令。 下面的命令断开 my-nginx
容器与 my-net
网络的连接。
docker network disconnect my-net my-nginx
1.5 使用IPv6
如果您需要对 Docker 容器的 IPv6支持,那么在创建任何 IPv6网络或为容器分配 IPv6地址之前,您需要启用 Docker 守护进程上的选项并重新加载其配置。
创建网络时,可以指定 --ipv6
标志以启用 IPv6。 你不能选择性地禁用默认桥接网络的 IPv6支持。
1.6 启用从Docker容器到外界的转发
默认情况下,来自连接到默认网桥网络的容器的流量 不会转发到外界。要启用转发,您需要更改两个设置。这些不是Docker命令,它们会影响Docker主机的内核。
配置Linux内核以允许IP转发。
sysctl net.ipv4.conf.all.forwarding=1
将策略的iptables FORWARD策略从更改DROP为 ACCEPT。
sudo iptables -P FORWARD ACCEPT
这些设置不会在重新启动后持续存在,因此您可能需要将它们添加到启动脚本中。
1.7 使用默认的桥接网络
默认bridge
网络被认为是Docker的遗留细节,不建议用于生产环境。对其进行配置是手动操作,并且存在 技术缺陷。
将容器连接到默认网桥网络
如果没有使用 – network 标志指定网络,并且指定了网络驱动程序,则默认情况下容器将连接到默认桥接网络。 连接到默认桥接网络的容器可以通信,但只能通过 IP 地址通信,除非使用遗留的 – link 标志链接它们。
配置默认网桥网络
要配置默认的桥接网络,可以在 daemon.json 中指定选项。 下面是一个指定了几个选项的 daemon.json 示例。 只指定需要自定义的设置。
{
"bip": "192.168.1.5/24",
"fixed-cidr": "192.168.1.5/25",
"fixed-cidr-v6": "2001:db8::/64",
"mtu": 1500,
"default-gateway": "10.20.1.1",
"default-gateway-v6": "2001:db8:abcd::89",
"dns": ["10.20.1.2","10.20.1.3"]
}
重新启动Docker以使更改生效。
将IPv6与默认桥接网络一起使用
如果您为 IPv6支持配置 Docker (请参阅使用 IPv6) ,默认桥接网络也会自动为 IPv6配置。 与用户定义的网桥不同,您不能在缺省网桥上有选择地禁用 IPv6。
2. 实践练习 与独立容器联网
使
用默认桥接网络
演示如何使用 Docker 为您自动设置的默认桥网络。 这个网络不是生产系统的最佳选择。使用用户定义的桥接网络
演示了如何创建和使用自己的定制桥接网络,以连接运行在同一个 Docker 主机上的容器。 建议在生产环境中运行的独立容器使用这种方法。
2.1 使用默认的桥接网络
在本例中,您在同一个 Docker 主机上启动两个不同的 alpine 容器,并进行一些测试以了解它们如何彼此通信。 您需要安装并运行 Docker。
打开终端窗口。 在你做任何事情之前列出当前的网络。 如果您从未在这个 Docker 守护进程上添加过网络或初始化过一个群,下面是您应该看到的内容。 你可能会看到不同的网络,但是你至少应该看到这些(网络 id 不同) :
$ docker network ls NETWORK ID NAME DRIVER SCOPE 17e324f45964 bridge bridge local 6ed54d316334 host host local 7092879f2cc8 none null local
列出了
bridge
、host
和none
。 后两者不是完全成熟的网络,但用于启动直接连接到 Docker 守护进程主机的网络堆栈的容器,或者启动没有网络设备的容器。 本教程将把两个容器连接到桥接网络。启动两个
alpine
运行的容器ash
,这是alpine
的默认shell
程序,而不是bash。-dit
标志意味着启动分离的容器(在后台),交互式的容器(可以在其中键入内容)和 TTY (这样您就可以看到输入和输出)。因为是分离启动的,所以不会马上连接到容器。 相反,容器的 ID 将被打印出来。 因为您没有指定任何--network
标志,因此容器将连接到默认bridge
网络。$ docker run -dit --name alpine1 alpine ash $ docker run -dit --name alpine2 alpine ash
检查两个容器是否确实已启动:
$ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 602dbf1edc81 alpine "ash" 4 seconds ago Up 3 seconds alpine2 da33b7aa74b0 alpine "ash" 17 seconds ago Up 16 seconds alpine1
检查bridge网络以查看连接了哪些容器。
$ docker network inspect bridge [ { "Name": "bridge", "Id": "17e324f459648a9baaea32b248d3884da102dde19396c25b30ec800068ce6b10", "Created": "2017-06-22T20:27:43.826654485Z", "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, "Containers": { "602dbf1edc81813304b6cf0a647e65333dc6fe6ee6ed572dc0f686a3307c6a2c": { "Name": "alpine2", "EndpointID": "03b6aafb7ca4d7e531e292901b43719c0e34cc7eef565b38a6bf84acf50f38cd", "MacAddress": "02:42:ac:11:00:03", "IPv4Address": "172.17.0.3/16", "IPv6Address": "" }, "da33b7aa74b0bf3bda3ebd502d404320ca112a268aafe05b4851d1e3312ed168": { "Name": "alpine1", "EndpointID": "46c044a645d6afc42ddd7857d19e9dcfb89ad790afb5c239a35ac0af5e8a5bc5", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/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": {} } ]
s在顶部附近,
bridge
列出了有关网络的信息,包括Docker主机和bridge
网络之间的网关的IP地址(172.17.0.1
)。在该Containers
键下,列出了每个已连接的容器以及有关其IP地址的信息(172.17.0.2
foralpine1
和172.17.0.3
foralpine2
)。容器在后台运行。使用docker attach 命令连接到alpine1。
$ docker attach alpine1 / #
提示将更改为 # ,以指示您是容器中的根用户。 使用
ip addr show
命令显示alpine1
的网络接口,因为它们从容器内部观察:# ip addr show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1 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 27: eth0@if28: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::42:acff:fe11:2/64 scope link valid_lft forever preferred_lft forever
第一个接口是环回设备。 暂时忽略它。 请注意,第二个接口的 IP 地址为
172.17.0.2
,与前面步骤中显示的alpine1
的地址相同。在
alpine1
内部,确保你可以通过ping google.com
连接到互联网。该-c2
标志将命令限制为两次ping 尝试。# ping -c 2 google.com PING google.com (172.217.3.174): 56 data bytes 64 bytes from 172.217.3.174: seq=0 ttl=41 time=9.841 ms 64 bytes from 172.217.3.174: seq=1 ttl=41 time=9.897 ms \--- google.com ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 9.841/9.869/9.897 ms
现在尝试 ping 第二个容器,首先,ping 它的 IP 地址,
172.17.0.3
:# ping -c 2 172.17.0.3 PING 172.17.0.3 (172.17.0.3): 56 data bytes 64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.086 ms 64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.094 ms \--- 172.17.0.3 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.086/0.090/0.094 ms
成功。接下来,尝试按容器名称
ping alpine2
容器。这将失败。# ping -c 2 alpine2 ping: bad address 'alpine2'
通过使用分离序列,
CTRL + p
CTRL + q
(按住 CTRL,输入 p 后跟 q)从alpine1
中分离,而不停止它。 如果你愿意,连接到alpine2
,重复步骤4,5,6,用alpine1
代替alpine2
。停止并移走两个容器。
$ docker container stop alpine1 alpine2 $ docker container rm alpine1 alpine2
请记住,生产环境中不推荐使用默认的网桥网络。
2.2 使用用户定义的网桥
在这个例子中,我们再次启动两个 alpine
容器,但是将它们附加到我们已经创建的用户定义的网络 alpine-net
中。 这些容器根本没有连接到缺省网桥网络
。 然后我们开始第三个alpine
容器,连接到桥接网络
,但不连接到lpine-net
,和第四个alpine
容器,同事连接到这两个网络。
创建·alpine-net·网络。您不需要
--driver bridge
标志,因为它是默认标志,但是此示例显示了如何指定它。$ docker network create --driver bridge alpine-net
列出Docker的网络:
$ docker network ls NETWORK ID NAME DRIVER SCOPE e9261a8c9a19 alpine-net bridge local 17e324f45964 bridge bridge local 6ed54d316334 host host local 7092879f2cc8 none null local
检查·alpine-net·网络。这显示了它的IP地址以及没有容器连接到它:
$ docker network inspect alpine-net [ { "Name": "alpine-net", "Id": "e9261a8c9a19eabf2bf1488bf5f208b99b1608f330cff585c273d39481c9b0ec", "Created": "2017-09-25T21:38:12.620046142Z", "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, "Containers": {}, "Options": {}, "Labels": {} } ]
请注意,这个网络的网关是172.18.0.1,与缺省网桥网络相反,后者的网关是172.17.0.1。 确切的 IP 地址在您的系统上可能不同。
创建四个容器。注意
--network
标志。在docker run
命令期间,您只能连接到一个网络,因此需要在之后使用docker network connect
将alpine4
连接到桥接网络。$ docker run -dit --name alpine1 --network alpine-net alpine ash $ docker run -dit --name alpine2 --network alpine-net alpine ash $ docker run -dit --name alpine3 alpine ash $ docker run -dit --name alpine4 --network alpine-net alpine ash $ docker network connect bridge alpine4
验证所有容器都在运行:
$ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 156849ccd902 alpine "ash" 41 seconds ago Up 41 seconds alpine4 fa1340b8d83e alpine "ash" 51 seconds ago Up 51 seconds alpine3 a535d969081e alpine "ash" About a minute ago Up About a minute alpine2 0a02c449a6e9 alpine "ash" About a minute ago Up About a minute alpine1
检查
bridge
网络和alpine-net
网络:$ docker network inspect bridge [ { "Name": "bridge", "Id": "17e324f459648a9baaea32b248d3884da102dde19396c25b30ec800068ce6b10", "Created": "2017-06-22T20:27:43.826654485Z", "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, "Containers": { "156849ccd902b812b7d17f05d2d81532ccebe5bf788c9a79de63e12bb92fc621": { "Name": "alpine4", "EndpointID": "7277c5183f0da5148b33d05f329371fce7befc5282d2619cfb23690b2adf467d", "MacAddress": "02:42:ac:11:00:03", "IPv4Address": "172.17.0.3/16", "IPv6Address": "" }, "fa1340b8d83eef5497166951184ad3691eb48678a3664608ec448a687b047c53": { "Name": "alpine3", "EndpointID": "5ae767367dcbebc712c02d49556285e888819d4da6b69d88cd1b0d52a83af95f", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/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": {} } ]
容器
alpine3
和alpine4
连接到bridge
网络。$ docker network inspect alpine-net [ { "Name": "alpine-net", "Id": "e9261a8c9a19eabf2bf1488bf5f208b99b1608f330cff585c273d39481c9b0ec", "Created": "2017-09-25T21:38:12.620046142Z", "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, "Containers": { "0a02c449a6e9a15113c51ab2681d72749548fb9f78fae4493e3b2e4e74199c4a": { "Name": "alpine1", "EndpointID": "c83621678eff9628f4e2d52baf82c49f974c36c05cba152db4c131e8e7a64673", "MacAddress": "02:42:ac:12:00:02", "IPv4Address": "172.18.0.2/16", "IPv6Address": "" }, "156849ccd902b812b7d17f05d2d81532ccebe5bf788c9a79de63e12bb92fc621": { "Name": "alpine4", "EndpointID": "058bc6a5e9272b532ef9a6ea6d7f3db4c37527ae2625d1cd1421580fd0731954", "MacAddress": "02:42:ac:12:00:04", "IPv4Address": "172.18.0.4/16", "IPv6Address": "" }, "a535d969081e003a149be8917631215616d9401edcb4d35d53f00e75ea1db653": { "Name": "alpine2", "EndpointID": "198f3141ccf2e7dba67bce358d7b71a07c5488e3867d8b7ad55a4c695ebb8740", "MacAddress": "02:42:ac:12:00:03", "IPv4Address": "172.18.0.3/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ]
容器
alpine1
,alpine2
和alpine4
连接到alpine-net
网络。在用户定义网络
alpine-net
,容器不仅可以通过IP地址进行通信,还可以将容器名称解析为IP地址。此功能称为自动服务发现。让我们连接alpine1
并测试一下。alpine1
应该能够解析alpine2
和alpine4
(以及alpine1
本身)为IP地址。$ docker container attach alpine1 # ping -c 2 alpine2 PING alpine2 (172.18.0.3): 56 data bytes 64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.085 ms 64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.090 ms \--- alpine2 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.085/0.087/0.090 ms # ping -c 2 alpine4 PING alpine4 (172.18.0.4): 56 data bytes 64 bytes from 172.18.0.4: seq=0 ttl=64 time=0.076 ms 64 bytes from 172.18.0.4: seq=1 ttl=64 time=0.091 ms \--- alpine4 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.076/0.083/0.091 ms # ping -c 2 alpine1 PING alpine1 (172.18.0.2): 56 data bytes 64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.026 ms 64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.054 ms \--- alpine1 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.026/0.040/0.054 ms
从
alpine1
,您根本无法连接alpine3
,因为它不在alpine-net
网络上。# ping -c 2 alpine3 ping: bad address 'alpine3'
不仅如此,您也无法通过
alpine3
的IP地址,从alpine1
连接到alpine3
。回顾网络的docker network inspect
输出bridge
,找到alpine3
的IP地址:172.17.0.2
尝试ping通它。# ping -c 2 172.17.0.2 PING 172.17.0.2 (172.17.0.2): 56 data bytes \--- 172.17.0.2 ping statistics --- 2 packets transmitted, 0 packets received, 100% packet loss
使用分离序列从
alpine1
中分离,CTRL+ p
CTRL+ q
(按住 CTRL,键入 p,然后是 q)。请记住,
alpine4
已连接到默认bridge
网络和alpine-net
。它应该能够到达所有其他容器。但是,您将需要alpine3
的IP地址进行寻址。附加到它并运行测试。$ docker container attach alpine4 # ping -c 2 alpine1 PING alpine1 (172.18.0.2): 56 data bytes 64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.074 ms 64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.082 ms \--- alpine1 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.074/0.078/0.082 ms # ping -c 2 alpine2 PING alpine2 (172.18.0.3): 56 data bytes 64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.075 ms 64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.080 ms \--- alpine2 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.075/0.077/0.080 ms # ping -c 2 alpine3 ping: bad address 'alpine3' # ping -c 2 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.089 ms 64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.075 ms \--- 172.17.0.2 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.075/0.082/0.089 ms # ping -c 2 alpine4 PING alpine4 (172.18.0.4): 56 data bytes 64 bytes from 172.18.0.4: seq=0 ttl=64 time=0.033 ms 64 bytes from 172.18.0.4: seq=1 ttl=64 time=0.064 ms \--- alpine4 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.033/0.048/0.064 ms
作为最终测试,请通过ping确保您的容器都可以连接到互联网
google.com
。您已经接入alpine4
,因此请从那里开始尝试。接下来,断开alpine4并连接到alpine3 (仅连接到bridge网络)并重试。最后,连接到alpine1(仅连接到alpine-net网络),然后重试。# ping -c 2 google.com PING google.com (172.217.3.174): 56 data bytes 64 bytes from 172.217.3.174: seq=0 ttl=41 time=9.778 ms 64 bytes from 172.217.3.174: seq=1 ttl=41 time=9.634 ms \--- google.com ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 9.634/9.706/9.778 ms CTRL+p CTRL+q $ docker container attach alpine3 # ping -c 2 google.com PING google.com (172.217.3.174): 56 data bytes 64 bytes from 172.217.3.174: seq=0 ttl=41 time=9.706 ms 64 bytes from 172.217.3.174: seq=1 ttl=41 time=9.851 ms \--- google.com ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 9.706/9.778/9.851 ms CTRL+p CTRL+q $ docker container attach alpine1 # ping -c 2 google.com PING google.com (172.217.3.174): 56 data bytes 64 bytes from 172.217.3.174: seq=0 ttl=41 time=9.606 ms 64 bytes from 172.217.3.174: seq=1 ttl=41 time=9.603 ms \--- google.com ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 9.603/9.604/9.606 ms CTRL+p CTRL+q
停止并卸下所有容器和alpine-net网络。
$ docker container stop alpine1 alpine2 alpine3 alpine4 $ docker container rm alpine1 alpine2 alpine3 alpine4 $ docker network rm alpine-net