这周我一直在阅读有关网络方面的资料,但我的理解仍然存在一个看似重大的漏洞,该漏洞与我的主机可以访问哪些 IP 地址以及如何访问有关。
具体来说,ip -br addr
表现为:
lo UNKNOWN 127.0.0.1/8 ::1/128
tunl0@NONE DOWN
sit0@NONE DOWN
ip6tnl0@NONE DOWN
eth0@if15 UP 198.19.249.109/24 metric 1024 fd07:b51a:cc66:0:439:fcff:fe3f:27d6/64 fe80::439:fcff:fe3f:27d6/64
docker0 DOWN 172.17.0.1/16 fe80::acc7:7cff:fe73:5421/64
br-140e1fbca70a UP 172.18.0.1/16 fe80::34c3:10ff:fe55:2464/64
vethbf1bfcc@if5 UP fe80::38fd:c6ff:fe37:f54/64
veth7e8fb76@if5 UP fe80::689e:8bff:fe81:d8c3/64
并ip route
显示:
default via 198.19.249.1 dev eth0 proto dhcp src 198.19.249.109 metric 1024
0.250.250.200 via 198.19.249.1 dev eth0 proto dhcp src 198.19.249.109 metric 1024
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
172.18.0.0/16 dev br-140e1fbca70a proto kernel scope link src 172.18.0.1
198.19.249.0/24 dev eth0 proto kernel scope link src 198.19.249.109 metric 1024
198.19.249.1 dev eth0 proto dhcp scope link src 198.19.249.109 metric 1024
并ip neigh
显示:
198.19.249.1 dev eth0 lladdr da:9b:d0:54:e0:02 STALE
172.18.0.3 dev br-140e1fbca70a lladdr fe:50:d0:de:5a:ce STALE
fe80::d84c:3aff:fef1:e382 dev eth0 lladdr da:9b:d0:54:e0:02 router STALE
此外,docker network inspect ..._..._default
表示网络有网关172.18.0.1
,并有两个容器与其连接,包括172.18.0.3
。
iptables
仅包含标准Docker 规则。
问题:
我运行ip route del 172.18.0.0/16
并从路由表中删除了该条目。
我现在怎么无法访问docker容器了?
该172.18.0.3
容器在我的计算机上本地运行,因此我希望能够访问它,只要我以iptable
某种方式调整规则即可。难道这样不对吗?
容器作为单独的“网络命名空间”运行。即使它物理上位于您的计算机上,它也有自己独立的网络堆栈 - 自己的接口、自己的路由、自己的 iptables,甚至自己的“localhost”概念 -从所有意图和目的来看,它的行为就像是与主机完全分离的机器一样。
(主机内核跟踪哪些进程位于哪个命名空间中;可以使用
lsns
、unshare
和等工具nsenter
进行探索。)这两个命名空间之间的唯一互连是作为虚拟以太网电缆的两端的一对“veth”接口(它们总是成对创建,然后一个被重新分配给容器的命名空间,而另一个留在主机端)。
主机端的 veth 可以是桥接的,也可以不是,随你喜欢——桥接是为了方便,就像通过交换机连接机器而不是使用多条一对一的电缆连接机器一样——但无论哪种方式,都必须设置 IP 地址、子网掩码和路由,就像你实际上连接单独的机器一样。
所以,您不能仅通过调整 iptables 规则来访问该地址。它没有任何在路由表之前生效的特殊快捷路径(实际上,网络命名空间的全部意义就在于不存在这样的事情),因此,如果您没有通向它的路由,您就无法向其发送数据包。
然而,并非所有容器都像这样具有命名空间;Docker 具有“主机网络”模式,该模式不使用网络命名空间,容器仅共享主机的 IP 地址。