Docker入门系列 4. Docker 容器网络的概念及网络配置 网桥网络


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文件可以定义共享变量。

    • 您可以使用群体服务代替独立容器,并利用共享的secretsconfigs

连接到同一个用户定义的桥接网络的容器有效地将所有端口相互暴露。 对于不同网络上的容器或非 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主机的内核。

  1. 配置Linux内核以允许IP转发。

    sysctl net.ipv4.conf.all.forwarding=1
  2. 将策略的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。

  1. 打开终端窗口。 在你做任何事情之前列出当前的网络。 如果您从未在这个 Docker 守护进程上添加过网络或初始化过一个群,下面是您应该看到的内容。 你可能会看到不同的网络,但是你至少应该看到这些(网络 id 不同) :

    
    $ docker network ls
    
    NETWORK ID          NAME                DRIVER              SCOPE
    17e324f45964        bridge              bridge              local
    6ed54d316334        host                host                local
    7092879f2cc8        none                null                local
    

    列出了bridgehostnone。 后两者不是完全成熟的网络,但用于启动直接连接到 Docker 守护进程主机的网络堆栈的容器,或者启动没有网络设备的容器。 本教程将把两个容器连接到桥接网络。

  2. 启动两个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
    
  3. 检查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.2for alpine1172.17.0.3for alpine2)。

  4. 容器在后台运行。使用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的地址相同。

  5. 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
    
  6. 现在尝试 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'
  7. 通过使用分离序列,CTRL + p CTRL + q (按住 CTRL,输入 p 后跟 q)从 alpine1中分离,而不停止它。 如果你愿意,连接到 alpine2,重复步骤4,5,6,用 alpine1代替 alpine2

  8. 停止并移走两个容器。

    $ docker container stop alpine1 alpine2
    $ docker container rm alpine1 alpine2 

请记住,生产环境中不推荐使用默认的网桥网络。

2.2 使用用户定义的网桥

在这个例子中,我们再次启动两个 alpine 容器,但是将它们附加到我们已经创建的用户定义的网络 alpine-net 中。 这些容器根本没有连接到缺省网桥网络。 然后我们开始第三个alpine容器,连接到桥接网络,但不连接到lpine-net,和第四个alpine容器,同事连接到这两个网络。

  1. 创建·alpine-net·网络。您不需要--driver bridge标志,因为它是默认标志,但是此示例显示了如何指定它。

    $ docker network create --driver bridge alpine-net
  2. 列出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 地址在您的系统上可能不同。

  3. 创建四个容器。注意--network标志。在docker run命令期间,您只能连接到一个网络,因此需要在之后使用 docker network connectalpine4连接到桥接网络。

    $ 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
  4. 检查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": {}
     }
    ]

    容器alpine3alpine4连接到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": {}
     }
    ]

    容器alpine1alpine2alpine4连接到 alpine-net网络。

  5. 在用户定义网络alpine-net,容器不仅可以通过IP地址进行通信,还可以将容器名称解析为IP地址。此功能称为自动服务发现。让我们连接alpine1并测试一下。alpine1应该能够解析 alpine2alpine4(以及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
  6. 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)。

  7. 请记住,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
  8. 作为最终测试,请通过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
  9. 停止并卸下所有容器和alpine-net网络。

    $ docker container stop alpine1 alpine2 alpine3 alpine4
    
    $ docker container rm alpine1 alpine2 alpine3 alpine4
    
    $ docker network rm alpine-net

文章作者: Baymax
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Baymax !
评论
 上一篇
Docker入门系列  5. Docker 容器网络的概念及网络配置 覆盖网络 Docker入门系列 5. Docker 容器网络的概念及网络配置 覆盖网络
1. 使用覆盖网络覆盖网络驱动程序在多个 Docker 守护进程主机之间创建一个分布式网络。 这个网络位于(覆盖)主机特定网络的顶部,允许连接到它的容器(包括群服务容器)在启用加密时进行安全通信。 Docker 透明地处理每个数据包与正确的
2020-05-24
下一篇 
Docker入门系列  3. Docker 容器网络的概念及网络配置 网络概述 Docker入门系列 3. Docker 容器网络的概念及网络配置 网络概述
1. 网络概述  Docker容器和服务如此强大的原因之一是你可以将它们连接在一起,或将它们连接到非Docker工作负载。Docker容器和服务甚至不需要知道它们已部署在Docker上,也不必知道它们的对等对象是否也是Docker工作负载。
2020-05-14
  目录