桥接网络驱动程序
在网络方面,桥接网络是一个链路层设备,用于在网络段之间转发流量。桥接可以是硬件设备,也可以是在主机内核中运行的软件设备。
就Docker而言,桥接网络使用一种软件桥,它允许连接到同一桥接网络的容器进行通信,同时与未连接到该桥接网络的容器隔离。Docker桥接驱动程序会自动在主机上安装规则,以便不同桥接网络上的容器无法直接相互通信。
桥接网络适用于在同一 Docker 守护进程主机上运行的容器。 对于在不同 Docker 守护进程主机上运行的容器之间的通信, 您可以在操作系统级别管理路由,或者使用 覆盖网络。
当您启动 Docker 时,会自动创建一个
默认桥接网络(也称为
bridge),除非另有说明,新启动的容器都会连接到它。您还可以创建用户定义的自定义桥接网络。
用户定义的桥接网络优于默认的
bridge
网络。
用户定义桥接网络与默认桥接网络的区别
用户定义的网桥在容器之间提供自动 DNS 解析。
默认桥接网络上的容器只能通过 IP 地址互相访问,除非您使用
--link选项,这被认为是传统方法。在用户定义的桥接网络上,容器可以通过名称或别名相互解析。想象一个具有 Web 前端和数据库后端的应用程序。如果您将容器命名为
web和db,则 Web 容器可以在db处连接到数据库容器,无论应用程序栈运行在哪个 Docker 主机上。如果你在默认的桥接网络上运行相同的应用程序栈,你需要 手动在容器之间创建链接(使用传统的
--link标志)。这些链接需要在两个方向上创建,因此你可以看到,当需要通信的容器超过两个时,这会变得复杂。 或者,你可以操作容器内的/etc/hosts文件, 但这会产生难以调试的问题。用户定义的网桥提供更好的隔离。
所有没有指定
--network的容器都附加到默认的桥接网络上。这可能是一个风险,因为不相关的堆栈/服务/容器能够进行通信。使用用户定义的网络提供了一个作用域网络,只有连接到该网络的容器才能进行通信。
容器可以随时连接到或断开用户定义的网络.
在容器的生命周期内,您可以动态地将其连接到或断开用户定义的网络。要从默认的桥接网络中移除容器,您需要停止该容器并使用不同的网络选项重新创建它。
每个用户定义的网络都会创建一个可配置的网桥.
如果您的容器使用默认的桥接网络,您可以对其进行配置,但 所有容器都使用相同的设置,例如 MTU 和
iptables规则。 此外,配置默认桥接网络是在 Docker 本身之外进行的,并且需要重启 Docker。用户定义的桥接网络是通过使用
docker network create创建和配置的。如果不同的应用程序组有不同的 网络需求,您可以在创建时分别配置每个用户定义的桥接网络。默认桥接网络上的链接容器共享环境变量.
最初,在两个容器之间共享环境变量的唯一方法是使用
--link标志来链接它们。这种类型的变量共享在用户定义的网络中是不可能的。然而,有更好的方法来共享环境变量。一些想法:
连接到同一用户定义桥接网络的容器实际上会向彼此暴露所有端口。
若要使端口对其他网络上的容器或非 Docker 主机可访问,必须使用 -p 或 --publish 标志来发布该端口。
选项
下表描述了在使用 bridge 驱动程序创建自定义网络时,可以传递给 --option 的驱动程序特定选项。
| 选项 | 默认 | 描述 |
|---|---|---|
com.docker.network.bridge.name | 创建 Linux 网桥时要使用的接口名称。 | |
com.docker.network.bridge.enable_ip_masquerade | true | 启用 IP 伪装。 |
com.docker.network.bridge.gateway_mode_ipv4com.docker.network.bridge.gateway_mode_ipv6 | nat | 启用 NAT 和伪装 (nat),或仅允许直接路由到容器 (routed)。 |
com.docker.network.bridge.enable_icc | true | 启用或禁用容器之间的连接。 |
com.docker.network.bridge.host_binding_ipv4 | 所有 IPv4 和 IPv6 地址 | 绑定容器端口时的默认 IP。 |
com.docker.network.driver.mtu | 0 (无限制) | 设置容器的网络最大传输单元(MTU)。 |
com.docker.network.container_iface_prefix | eth | 为容器接口设置自定义前缀。 |
com.docker.network.bridge.inhibit_ipv4 | false | 防止 Docker 分配 IP 地址 到网络。 |
这些选项中的一些也可以作为 dockerd CLI 的标志使用,您可以使用它们在启动 Docker 守护进程时配置默认的 docker0 桥接。下表显示了哪些选项在 dockerd CLI 中有等效的标志。
| 选项 | Flag |
|---|---|
com.docker.network.bridge.name | - |
com.docker.network.bridge.enable_ip_masquerade | --ip-masq |
com.docker.network.bridge.enable_icc | --icc |
com.docker.network.bridge.host_binding_ipv4 | --ip |
com.docker.network.driver.mtu | --mtu |
com.docker.network.container_iface_prefix | - |
Docker 守护进程支持一个 --bridge 标志,您可以使用它来定义自己的 docker0 网桥。如果您想在同一主机上运行多个守护进程实例,请使用此选项。有关详细信息,请参阅
运行多个守护进程。
默认主机绑定地址
如果在端口发布选项(如 -p 80 或 -p 8080:80)中未指定主机地址,则默认是将容器的 80 端口在所有主机地址(IPv4 和 IPv6)上开放。
网桥网络驱动程序选项 com.docker.network.bridge.host_binding_ipv4
可用于修改已发布端口的默认地址。
尽管该选项的名称如此,但也可以指定 IPv6 地址。
当默认绑定地址是分配给特定接口的地址时, 容器的端口将只能通过该地址访问。
将默认绑定地址设置为 :: 意味着发布的端口将仅在主机的 IPv6 地址上可用。然而,将其设置为 0.0.0.0 意味着它将在主机的 IPv4 和 IPv6 地址上可用。
要将已发布的端口限制为仅限 IPv4,必须在容器的发布选项中包含地址。例如,-p 0.0.0.0:8080:80。
管理用户定义的网桥
使用 docker network create 命令创建用户定义的桥接网络。
$ docker network create my-net
您可以指定子网、IP 地址范围、网关和其他选项。请参阅
docker network create
参考文档或 docker network create --help 的输出以获取详细信息。
使用 docker network rm 命令删除用户定义的桥接网络。如果容器当前连接到该网络,
请先断开它们。
$ docker network rm my-net
到底发生了什么?
当您创建或删除用户定义的网桥,或者将容器连接到或断开与用户定义的网桥的连接时,Docker 使用特定于操作系统的工具来管理底层网络基础设施(例如在 Linux 上添加或删除网桥设备或配置
iptables规则)。这些细节应被视为实现细节。让 Docker 为您管理用户定义的网络。
将容器连接到用户定义的网桥
当您创建一个新容器时,可以指定一个或多个 --network 标志。
此示例将一个 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
将容器与用户定义的网桥断开连接
要将正在运行的容器与用户定义的桥接网络断开连接,请使用
docker network disconnect 命令。以下命令将
my-nginx 容器从 my-net 网络中断开连接。
$ docker network disconnect my-net my-nginx
在用户定义的桥接网络中使用 IPv6
当您创建网络时,可以指定 --ipv6 标志以启用 IPv6。
$ docker network create --ipv6 --subnet 2001:db8:1234::/64 my-net
使用默认桥接网络
默认的 bridge 网络被视为 Docker 的遗留细节,不建议在生产环境中使用。配置它需要手动操作,并且它存在 技术缺陷。
将容器连接到默认桥接网络
如果您不使用 --network 标志指定网络,但指定了网络驱动程序,则您的容器默认连接到默认的 bridge 网络。连接到默认 bridge 网络的容器可以通信,但只能通过 IP 地址进行通信,除非它们使用
传统 --link 标志进行链接。
配置默认桥接网络
要配置默认 bridge 网络,您需要在 daemon.json 中指定选项。
以下是一个包含多个指定选项的 daemon.json 示例。仅指定您需要自定义的设置。
{
"bip": "192.168.1.1/24",
"fixed-cidr": "192.168.1.0/25",
"mtu": 1500,
"default-gateway": "192.168.1.254",
"dns": ["10.20.1.2","10.20.1.3"]
}重启 Docker 以使更改生效。
在默认桥接网络上使用 IPv6
可以通过在 daemon.json 中使用以下选项或其等效的命令行参数来为默认网桥启用 IPv6。
这三个选项仅影响默认桥接网络,不适用于用户定义的网络。下面的地址是IPv6文档范围中的示例。
- 选项
ipv6是必需的 - 选项
fixed-cidr-v6是必需的,它指定要使用的网络前缀。- 前缀通常应为
/64或更短。 - 在本地网络上进行实验时,使用唯一本地前缀(匹配
fd00::/8)比使用链路本地前缀(匹配fe80::/10)更好。
- 前缀通常应为
- 选项
default-gateway-v6是可选的。如果未指定,默认值为fixed-cidr-v6子网中的第一个地址。
{
"ipv6": true,
"fixed-cidr-v6": "2001:db8::/64",
"default-gateway-v6": "2001:db8:abcd::89"
}桥接网络的连接限制
受 Linux 内核限制的影响,当 1000 个或更多容器连接到单个网络时,桥接网络会变得不稳定,容器间通信可能会中断。
有关此限制的更多信息,请参阅 moby/moby#44973。
跳过 IP 地址配置
com.docker.network.bridge.inhibit_ipv4 选项允许您创建一个使用现有网桥的网络,并让 Docker 跳过在网桥上配置 IPv4 地址。如果您想手动为网桥配置 IP 地址,这非常有用。例如,如果您将物理接口添加到网桥中,并且需要将其 IP 地址移动到网桥接口上。
要使用此选项,您应首先配置 Docker 守护进程以使用自管理的网桥,方法是在 daemon.json 或 dockerd --bridge 标志中使用 bridge 选项。
使用此配置,除非您已手动为网桥配置了 IP 地址,否则南北向流量将无法正常工作。
后续步骤
- 浏览 独立网络教程
- 了解 容器视角下的网络
- 了解 overlay networks
- 了解 Macvlan 网络