参考:https://docs.docker.com/network/bridge/
在网络方面,桥接网络是一个链路层设备,它在网络段之间转发流量。网桥可以是运行在主机内核中的硬件设备或软件设备。
就Docker而言,桥接网络使用软件桥,允许连接到同一桥接网络的容器进行通信,同时提供与没有连接到桥接网络的容器的隔离。Docker桥驱动程序自动在主机上安装规则,这样不同桥网络上的容器之间就不能直接通信了。
桥接网络适用于运行在同一Docker守护进程主机上的容器。对于运行在不同Docker守护进程主机上的容器之间的通信,您可以在操作系统级别管理路由,也可以使用覆盖网络。
启动Docker时,将自动创建一个默认的桥接网络(也称为桥接),除非另外指定,否则新启动的容器将连接到它。您还可以创建用户定义的桥接网络。用户定义的桥接网络优于默认的桥接网络。
一、用户定义的桥和默认桥之间的区别
1、用户定义的桥提供容器之间的自动DNS解析。
默认桥接网络上的容器只能通过IP地址互相访问,除非使用 --link选项,它被认为是遗留的。在用户定义的桥接网络中,容器可以通过 名称或别名彼此解析。
设想一个应用程序,它具有web前端和数据库后端。如果您调用您的容器web和db, web容器可以在db上连接到db容器,不管应用程序堆栈运行在哪个Docker上。
如果在缺省网桥网络上运行相同的应用程序堆栈,则需要手动创建容器之间的链接(使用遗留的--link标志)。这些链接需要在两个方向上创建,所以您可以看到,如果有两个以上的容器需要通信,情况就会变得非常复杂。或者,您也可以在容器中操作/etc/hosts文件,但是这会产生难以调试的问题。
2、用户定义的桥提供了更好的隔离。
所有没有指定--network的容器都连接到默认的桥接网络。这可能是一种风险,因为不相关的栈/服务/容器可以进行通信。
使用用户定义的网络提供了范围限定的网络,其中只有连接到该网络的容器才能通信。
3、可以动态地从用户定义的网络中附加和分离容器。
在容器的生命周期内,可以动态地将其与用户定义的网络连接或断开连接。要从缺省网桥网络中删除容器,需要停止容器并使用不同的网络选项重新创建它。
4、每个用户定义的网络都创建一个可配置的网桥。
如果您的容器使用默认的桥接网络,您可以配置它,但是所有的容器都使用相同的设置,比如MTU和iptables规则。另外,配置默认的桥接网络发生在Docker本身之外,需要重新启动Docker。
使用docker network create创建和配置用户定义的桥接网络。如果不同的应用程序组有不同的网络需求,您可以在创建每个用户定义的桥接时分别配置它。
4、默认桥接网络上的链接容器共享环境变量。
最初,在两个容器之间共享环境变量的惟一方法是使用--link 标志将它们链接起来。这种类型的变量共享在用户定义的网络中是不可能的。然而,有更好的方法来共享环境变量。几个想法:
- 多个容器可以使用Docker卷挂载包含共享信息的文件或目录。
- 可以使用docker-compose 一起启动多个容器,而compose文件可以定义共享变量。
- 您可以使用swarm services代替独立的容器,并利用共享的 secrets and configs.
连接到同一个用户定义的桥接网络的容器可以有效地相互公开所有端口。要使一个端口可被不同网络上的容器或非docker主机访问,必须使用-p或--publish标志发布该端口。
二、管理用户定义的桥
使用docker network create 命令创建用户定义的桥接网络
$ docker network create my-net
您可以指定子网、IP地址范围、网关和其他选项。有关详细信息,请参阅 the docker network create reference or the output of docker network create --help
for details.
使用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-net网络断开my-nginx容器。
$ docker network disconnect my-net my-nginx
五、使用IPV6
https://docs.docker.com/network/bridge/#use-ipv6
六、允许从Docker容器转发到外部世界
默认情况下,来自连接到默认桥接网络的容器的流量不会转发到外部世界。要启用转发,您需要更改两个设置。这些不是Docker命令,它们影响Docker主机的内核。
1、配置Linux内核以允许IP转发。
$ sysctl net.ipv4.conf.all.forwarding=1
2、将iptables转发策略的策略从DROP更改为ACCEPT。
$ sudo iptables -P FORWARD ACCEPT
这些设置不会在重新启动时持续存在,因此您可能需要将它们添加到启动脚本中。
七、使用默认网桥
默认的桥接网络被认为是Docker的遗留细节,不建议在生产环境中使用。配置它是一个手工操作,并且它有技术缺陷。
八、将容器连接到默认网桥网络
如果没有使用--network标志指定网络,而指定了网络驱动程序,则默认情况下容器将连接到默认网桥网络。连接到缺省桥接网络的容器可以通信,但只能通过IP地址进行通信,除非它们使用遗留的--link 标志进行链接。
九、配置默认网桥网络
要配置默认网桥网络,可以在daemon.json中指定选项。下面是一个示例守护进程。指定了几个选项的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以使更改生效。