Docker Bridge与主机网络冲突 [英] Docker Bridge Conflicts with Host Network

查看:201
本文介绍了Docker Bridge与主机网络冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在容器开始运行之后,Docker似乎正在创建一个与我的主机网络冲突的桥。这不是默认桥docker0,而是在容器启动后创建的另一个桥。我能够根据旧的用户指南链接 https://docs.docker.com/v17.09/engine/userguide/networking/default_network/custom-docker0/ ,但是,我不知道如何配置另一个网桥,因此它不与172.17冲突。

Docker seems to be creating a bridge after a container starts running that then conflicts with my host network. This is not the default bridge docker0, but rather another bridge that is created after a container has started. I am able to configure the default bridge according to the older user guide link https://docs.docker.com/v17.09/engine/userguide/networking/default_network/custom-docker0/, however, I do not know how to configure this other bridge so it does not conflict with 172.17.

然后,此当前问题是当此网桥变为活动状态时,我的容器无法访问主机网络上的其他系统。

This current issue is then that my container cannot access other systems on the host network when this bridge becomes active.

有什么想法吗?

码头工人的版本:

Version 18.03.1-ce-mac65 (24312)

这是创建的桥梁。有时不是172.17,但有时不是。

This is the bridge that gets created. Sometimes it is not 172.17, but sometimes it is.

br-f7b50f41d024 Link encap:Ethernet  HWaddr 02:42:7D:1B:05:A3  
      inet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0


推荐答案

创建docker网络时(例如使用 docker network create 或间接通过docker-compose),而未明确指定子网范围,dockerd从 172.N.0.0 / 16 开始分配一个新的 / 16 网络,其中 N 是一个递增的数字(例如N = 17,N = 18,N = 19,N = 20等)。如果范围中已经存在docker网络(自定义网络或默认docker网桥),则跳过给定的 N

When docker networks are created (e.g. using docker network create or indirectly through docker-compose) without explicitly specifying a subnet range, dockerd allocates a new /16 network, starting from 172.N.0.0/16, where N is a number that is incremented (e.g. N=17, N=18, N=19, N=20, ...). A given N is skipped if a docker network (a custom one, or the default docker bridge) already exists in the range.

您可以在CLI上创建docker网桥(即,不包括网络中的主机ip的网桥)时显式指定一个安全IP范围。但通常,网桥网络是由docker-compose自动创建并带有默认块的。要可靠地排除这些IP,需要修改遇到的每个docker-compose.yaml文件。在组合文件中包含特定于主机的内容是一种不好的做法。

You can specify explicitly a safe IP range when creating a docker bridge (i.e. one that excludes the host ips in your network) on the CLI. But usually bridge networks are created automatically by docker-compose with default blocks. To exclude these IPs reliably would require modifying every docker-compose.yaml file you encounter. It's bad practice to include host-specific things inside a compose file.

相反,您可以使用docker认为已分配的网络,以强制dockerd跳过子网。我概述了以下三种方法:

Instead, you can play with the networks that docker considers allocated, to force dockerd to "skip" subnets. I'm outlining three methods below:

方法#0-在守护程序配置中配置ips池

如果您的Docker版本足够新(TODO检查最低版本),并且您有权配置docker守护程序的命令行参数,则可以尝试传递 --default- dockerd命令的地址池ARG 选项。例如:

If your docker version is recent enough (TODO check minimum version), and you have permissions to configure the docker daemon's command line arguments, you can try passing --default-address-pool ARG options to the dockerd command. Ex:

 # allocate /24 subnets with the given CIDR prefix only.
 # note that this prefix excludes 172.17.*
 --default-address-pool base=172.24.0.0/13,size=24

您可以在以下一个文件中添加此设置: / etc / default / docker / etc / sysconfig / docker ,具体取决于您的分布。还有一种方法可以在daemon.json(请参见语法

You can add this setting in one of the etc files: /etc/default/docker, or in /etc/sysconfig/docker, depending on your distribution. There is also a way to set this parameter in daemon.json (see syntax)

方法1-创建虚拟占位符网络

通过在<$内的任何地方创建一个非常小的docker网络,可以防止整个 172.17.0.0/16 被dockerd使用(在将来的桥接网络中) c $ c> 172.17.0.0/16 。

You can prevent the entire 172.17.0.0/16 from being used by dockerd (in future bridge networks) by creating a very small docker network anywhere inside 172.17.0.0/16.

172.17。** $$ c中找到四个连续的IP。您知道主机网络中没有使用的$ c>,并在逻辑删除泊坞桥中牺牲了它们。下面,我假设ips 172.17.253.0 172.17.253.1 172.17。 253.2 172.17.253.3 (即 172.17.253.0/30 )在您的未使用状态

Find 4 consecutive IPs in 172.17.* that you know are not in use in your host network, and sacrifice them in a "tombstone" docker bridge. Below, I'm assuming the ips 172.17.253.0, 172.17.253.1, 172.17.253.2, 172.17.253.3 (i.e. 172.17.253.0/30) are unused in your host network.

docker network create --driver=bridge --subnet 172.17.253.0/30 tombstone
# created: c48327b0443dc67d1b727da3385e433fdfd8710ce1cc3afd44ed820d3ae009f5

请注意此处的 / 30 后缀,它定义了4个不同IP的块。从理论上讲,最小的有效网络子网应该是 / 31 ,它总共包含2个IP(网络标识符+广播)。 Docker要求最低为 / 30 ,可能是为了说明网关主机和另一个容器。我任意选择了 .253.0 ,您应该选择环境中不使用的东西。另外请注意,标识符墓碑没什么特别的,您可以将其重命名为可以帮助您记住几个月后再次找到它的原因的任何东西。

Note the /30 suffix here, which defines a block of 4 different IPs. In theory, the smallest valid network subnet should be a /31 which consists of a total of 2 IPs (network identifier + broadcast). Docker asks for a /30 minimum, probably to account for a gateway host, and another container. I picked .253.0 arbitrarily, you should pick something that's not in use in your environment. Also note that the identifier tombstone is nothing special, you can rename it to anything that will help you remember why it's there when you find it again several months later.

Docker将修改您的路由表,以发送这4个IP的流量通过新桥而不是主机网络:

Docker will modify your routing table to send traffic for these 4 IPs to go through that new bridge instead of the host network:

# output of route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.5.1     0.0.0.0         UG    0      0        0 eth1
172.17.253.0    0.0.0.0         255.255.255.252 U     0      0        0 br-c48327b0443d
172.20.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
192.168.5.0     0.0.0.0         255.255.255.0   U     0      0        0 eth1

注意:流量为172.17.253。 {0,1,2,3}经过刚创建的墓碑泊坞桥(br-c4832 ...)。 172.17。*中任何其他IP的流量将通过默认路由(主机网络)。我的docker网桥(docker0)位于172.20.0.1,这可能看起来很不正常-我已经在/etc/docker/daemon.json中修改了 bip 来执行此操作。请参见此页面有关更多详细信息。

Note: Traffic for 172.17.253.{0,1,2,3} goes through the tombstone docker bridge just created (br-c4832...). Traffic for any other IP in the 172.17.* would go through the default route (host network). My docker bridge (docker0) is on 172.20.0.1, which may appear unusual -- I've modified bip in /etc/docker/daemon.json to do that. See this page for more details.

转折点:如果存在一个桥,甚至占据了/ 16的一部分,那么创建的新桥将跳过该范围。如果创建新的docker网络,则可以看到 172.17.0.0/16 的其余部分被跳过,因为范围不完全可用。

The twist: if there exists a bridge occupying even a subportion of a /16, new bridges created will skip that range. If we create new docker networks, we can see that the rest of 172.17.0.0/16 is skipped, because the range is not entirely available.

docker network create foo_test
# c9e1b01f70032b1eff08e48bac1d5e2039fdc009635bfe8ef1fd4ca60a6af143
docker network create bar_test
# 7ad5611bfa07bda462740c1dd00c5007a934b7fc77414b529d0ec2613924cc57

生成的路由表:

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.5.1     0.0.0.0         UG    0      0        0 eth1
172.17.253.0    0.0.0.0         255.255.255.252 U     0      0        0 br-c48327b0443d
172.18.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-c9e1b01f7003
172.19.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-7ad5611bfa07
172.20.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
192.168.5.0     0.0.0.0         255.255.255.0   U     0      0        0 eth1

请注意, 172.17.0.0/16 中的其余IP尚未使用。新的广告网络保留 .18。 .19。。将流量发送到该逻辑删除网络之外的任何冲突IP都将通过您的主机网络。

Notice that the rest of the IPs in 172.17.0.0/16 have not been used. The new networks reserved .18. and .19.. Sending traffic to any of your conflicting IPs outside that tombstone network would go via your host network.

您必须将该逻辑删除网络保留在docker中,但不能使用它在您的容器中。这是一个虚拟的占位符网络。

You would have to keep that tombstone network around in docker, but not use it in your containers. It's a dummy placeholder network.

方法2 –消除冲突的桥接网络

如果希望暂时避免IP冲突,则可以使用 ip 将冲突的Docker桥关闭: ip链接集dev br- xxxxxxx down (其中xxxxxx代表来自 route -n ip链接显示)。这将具有删除路由表中相应的网桥路由条目的效果,而无需修改任何docker元数据。

If you wish to temporarily avoid the IP conflict, you can bring the conflicting docker bridge down using ip: ip link set dev br-xxxxxxx down (where xxxxxx represents the name of the bridge network from route -n or ip link show). This will have the effect of removing the corresponding bridge routing entry in the routing table, without modifying any of the docker metadata.

可以说这不如上面的方法好,因为您可能需要在每次dockerd启动时关闭该接口,并且如果有使用该桥的任何容器,它将干扰您的容器网络。

This is arguably not as good as the method above, because you'd have to bring down the interface possibly every time dockerd starts, and it would interfere with your container networking if there was any container using that bridge.

如果方法1将来会停止工作(例如,因为docker尝试变得更聪明并重用了ip块的未使用部分),您可以将两种方法结合使用:例如创建一个具有整个 / 16 的大型墓碑网络,而不是在任何容器中使用它,然后关闭其相应的br-x设备。

If method 1 stops working in the future (e.g. because docker tries to be smarter and reuse unused parts of an ip block), you could combine both approaches: e.g. create a large tombstone network with the entire /16, not use it in any container, and then bring its corresponding br-x device down.

方法#3-重新配置您的Docker桥以占用冲突的/ 16的子部分

上面的变体,您可以使默认docker bridge与主机网络中未使用的 172.17。*。* 区域重叠。您可以通过更改 /etc/docker/daemon.json bip 键)来更改默认的Docker网桥子网。 $ c>(请参见此页面了解更多信息)。只需将其设为/ 16的子区域即可,例如在/ 24或更小的范围内。

As a slight variation of the above, you could make the default docker bridge overlap with a region of 172.17.*.* that is not used in your host network. You can change the default docker bridge subnet by changing the bridge ip (i.e. bip key) in /etc/docker/daemon.json (See this page for more details). Just make it a subregion of your /16, e.g. in a /24 or smaller.

我尚未对此进行测试,但我认为任何新的docker网络都将跳过 172.17.0.0的其余部分/ 16 并为每个新桥分配一个完全不同的 / 16

I've not tested this, but I presume any new docker network would skip the remainder of 172.17.0.0/16 and allocate an entirely different /16 for each new bridge.

这篇关于Docker Bridge与主机网络冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆