访问不同子网中的docker容器(网桥)

Joe*_*ach 2 networking docker

我想访问另一个子网(不同网桥)中的容器。src 和 dst 桥通过 veth-pair 连接。

这是测试设置所必需的,我想在其中操纵这些网桥之间的连接属性(速率、延迟等)。这些网桥中的虚拟机能够相互 ping 通,但无法对容器进行 ping 操作(如果虚拟机或其他容器连接到另一个网桥,则无法相互 ping 通)。

首先,我在没有任何网络配置的情况下启动容器,并尝试将主机上的 veth 对应项连接到我也手动创建的那些桥。

实际上我间接创建了这些桥梁

docker network create --subnet 192.168.1.0/26 \
  -o "com.docker.network.bridge.enable_icc"="true" \
  -o "com.docker.network.driver.mtu"="1500" \
  -o "com.docker.network.bridge.name"="br-side-a" \
  br-side-a
docker network create --subnet 192.168.1.64/29 \
  -o "com.docker.network.bridge.enable_icc"="true" \
  -o "com.docker.network.driver.mtu"="1500" \
  -o "com.docker.network.bridge.name"="br-side-b" \
  br-side-b
Run Code Online (Sandbox Code Playgroud)

并将它们与

ip link add dev vsidea type veth peer name vsideb
brctl addif br-side-a vsidea
brctl addif br-side-b vsideb
ip addr add 192.168.1.10/26 dev vsidea
ip addr add 192.168.1.66/29 dev vsideb
ip link set vsidea up
ip link set vsideb up
Run Code Online (Sandbox Code Playgroud)

我连接到这些网桥的虚拟机(具有所连接子网的 IP)能够互相 ping 通。

我的容器是这样启动的:

docker run -ti --network br-side-a --ip 192.168.1.20 -p 10001:10000 --name csidea --privileged debian bash
docker run -ti --network br-side-a --ip 192.168.1.67 -p 10001:10000 --name csideb --privileged debian bash
Run Code Online (Sandbox Code Playgroud)

我可以 ping 通每个子网的两个容器上的所有(gateway-ips、vsidea/b、...),但不能 ping 通我分配给这些容器的 IP。虚拟机也无法访问容器 IP。

我认为 docker 做了一些路由/过滤,我必须关闭它们,但我不知道如何关闭。

Joe*_*ach 5

所以我找到了解决我的问题的方法。就像提到的 docker 进行过滤一样,我现在知道了。

Docker 自动创建 iptables 规则来限制创建的网桥的网络访问。为了向他们展示如何使用,iptables [-L|-S]应该有三个特定的规则链“DOCKER-USER”、“DOCKER-ISOLATION-STAGE-1”和“Docker-ISOLATION-STAGE-2”。

这些隔离阶段链中的规则确实阻止了我的网络之间的联网。它们的形式如下:

-I DOCKER-ISOLATION-STAGE-1 -i <my_network> ! -o <my_network> -j DOCKER-ISOLATION-STAGE2
-I DOCKER-ISOLATION-STAGE-2 -i <my_network> ! -o <my_network> DROP
Run Code Online (Sandbox Code Playgroud)

我首先设置了从 DROP 到 ACCEPT 的最后规则,只是为了证明我的发现。并查看这些网络之间的网络工作原理。

因此,我搜索了如何阻止 docker 创建这些规则,但您只能禁用 docker 创建任何 iptables 条目,而不仅仅是其中一些。另外,不建议更改隔离链,但 DOCKER-USER 链正是用于此目的。它将在任何其他 docker 规则之前进行评估,因此您可以指定接受这些包而不是删除它们。为您将允许通信的每个子网添加以下规则iptables -I DOCKER-USER -i <my_bridge_network> ! -o <my_bridge_network> ACCEPT

PS:抱歉我的英语。我希望这是可以理解的,但如果有难以忍受的错误,请随时给我一个提示,让我可以做得更好。