networking - 为什么当我关闭iptables时docker容器仍然可以与外部通信

标签 networking docker

我是Docker的新手,并且有关于Docker容器网络的一些基本问题以寻求帮助,我阅读了有关Docker的网络配置的文章:https://docs.docker.com/articles/networking/

有一部分介绍了如何使用iptables使docker容器与外部通信,实际上我可以理解这一部分:

1从容器到外部,路由后链上有一个伪装规则,与SNAT相同

    Chain POSTROUTING (policy ACCEPT)
    target     prot opt source               destination
    MASQUERADE  all  --  172.17.0.0/16       !172.17.0.0/16

2从外部访问容器内部的服务,在预路由链中有一个DNAT规则,然后主机将其转发到docker0,容器最终将接收到数据包
    Chain DOCKER (2 references)
    target     prot opt source               destination
    DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:49153 to:172.17.0.2:80

但是实际上,当我停止iptables服务时, docker 的网络仍然可以正常工作,我使用“iptables -L”和“iptables -t nat -L”进行检查,并且内核中没有规则,这是我的设置(假设10.170.28.0/24是外部网络,而172.17.0.0/16是docker容器的内部网络):

首先,iptables服务被关闭,fiter和nat表为空,如下所示:
    iptables -t nat -L
    Chain PREROUTING (policy ACCEPT)
    target     prot opt source               destination         

    Chain POSTROUTING (policy ACCEPT)
    target     prot opt source               destination         

    Chain OUTPUT (policy ACCEPT)
    target     prot opt source 

    iptables -L
    Chain INPUT (policy ACCEPT)
    target     prot opt source               destination         

    Chain FORWARD (policy ACCEPT)
    target     prot opt source               destination         

    Chain OUTPUT (policy ACCEPT)
    target     prot opt source               destination

这是主机中的路由表(主机ip为10.170.28.8):
    route
    Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    10.170.28.0     *               255.255.255.192 U     0      0        0 eth0
    192.168.0.0     *               255.255.255.0   U     0      0        0 br-data
    link-local      *               255.255.0.0     U     1002   0        0 eth0
    link-local      *               255.255.0.0     U     1003   0        0 eth1
    link-local      *               255.255.0.0     U     1040   0        0 br-data
    172.17.0.0      *               255.255.0.0     U     0      0        0 docker0
    default         10.170.28.1     0.0.0.0         UG    0      0        0 eth0

确实,上表中有规则将目标为172.17.0.0/16的数据包转发到桥接docker0,但在此之前,DNAT是谁将10.170.28.8转换为172.17.0.2(容器IP)的?从容器(172.17.0.0/16)到外部(10.170.28.0/24)的流量在没有SNAT或伪装的情况下如何工作?

最佳答案

首先,“停止” iptables是不可能的,它只是重置规则。如您的帖子所示,* filterINPUT链的策略为ALLOW。

Docker默认运行TCP转发代理,捕获所有转发端口的流量(通过ss -lnp | grep 49153验证)。

在我的机器上进行的测试表明,无法进行出站连接:

  • 启动容器
  • '停止'iptables
  • 执行到它
  • ping 1.1 ...无响应

  • 如果省略2.,则ping会按预期工作。
    $ docker --version
    Docker version 18.09.2-ce, build 62479626f2
    

    更多细节:
  • why is a userspace tcp proxy needed
  • traversal of iptables when connecting to docker client
  • 关于networking - 为什么当我关闭iptables时docker容器仍然可以与外部通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29629620/

    相关文章:

    .net - 处理服务中传入请求的体系结构

    docker - 将docker服务容器中的应用程序连接到在外部网络docker容器上运行的数据库

    docker - docker在启动时撰写run bash命令

    java - Java中如何查找IP地址建立的TCP连接数?

    docker-registry磁盘已满,没有节食的想法

    python - uwsgi-nginx-flask : unable to load app 0 (mountpoint ='' ) (callable not found or import error)

    docker - 无法配置/注册 dockerized gitlab runner

    Docker compose v3 指定网络为入口?

    python - 反序列化 C 数据

    linux - linux如何将数据包转发给k8s服务