Networking Docker网络

Networking Docker网络,networking,docker,subnet,Networking,Docker,Subnet,我试图理解以下两者之间的关系: 主机上的eth0;及 docker0bridge;及 eth0每个容器上的接口 据我了解,Docker: 创建一个docker0网桥,然后为其分配一个与主机上运行的任何内容不冲突的可用子网;然后 Docker将主机上运行的docker0绑定到eth0;然后 Docker将其旋转到的每个新容器绑定到docker0,以便容器的eth0接口连接到主机上的docker0,而主机上的eth0 这样,当主机外部的东西试图与容器通信时,它必须将消息发送到主机IP上的一个端口

我试图理解以下两者之间的关系:

  • 主机上的
    eth0
    ;及
  • docker0
    bridge;及
  • eth0
    每个容器上的接口
据我了解,Docker:

  • 创建一个
    docker0
    网桥,然后为其分配一个与主机上运行的任何内容不冲突的可用子网;然后
  • Docker将主机上运行的
    docker0
    绑定到
    eth0
    ;然后
  • Docker将其旋转到的每个新容器绑定到
    docker0
    ,以便容器的
    eth0
    接口连接到主机上的
    docker0
    ,而主机上的
    eth0
  • 这样,当主机外部的东西试图与容器通信时,它必须将消息发送到主机IP上的一个端口,然后该端口被转发到
    docker0
    网桥,然后该网桥被广播到主机上运行的所有容器,是吗

    同样,通过这种方式,当容器需要与主机外部的某个对象通信时,它有自己的IP(从
    docker0
    子网租用),因此远程调用方将看到来自容器IP的消息

    因此,如果我上面所说的任何内容不正确,请首先为我澄清

    假设我或多或少是正确的,我主要关心的是:

    • 当远程服务“调用”容器时,所有容器都会广播相同的消息,这会产生大量通信量/噪音,但也可能存在安全风险(其中只有容器1应该是某些消息的接收者,但其上运行的所有其他容器也会收到该消息);及
    • 当Docker在不同主机上选择相同的子网时会发生什么?在这种情况下,主机1上的容器1可能与主机2上的容器2具有相同的IP地址。如果容器1需要“调出”到某个外部/远程系统(不在主机上),那么该远程系统如何区分容器1和容器2(两者将显示相同的出口IP)

    我不会说你清楚Docker中的网络概念。 让我先澄清这部分:

    所以,事情是这样的:

  • Docker使用Linux内核名为名称空间的特性对资源进行分类/划分
  • 当容器启动时,Docker会为该容器创建一组名称空间
  • 这提供了一层隔离
  • 其中之一是“网络名称空间”:用于管理网络接口
  • 现在谈谈网络名称空间:

    Net命名空间

    • 让每个容器都有自己的网络资源、自己的网络堆栈。
      • 它有自己的网络接口
      • 它有自己的路由表
      • 这是自己的iptables规则
      • 它自己的套接字(ss、netstat)
    • 我们可以跨网络名称空间移动网络接口
    • 所以我们可以在某处创建一个netns,并在其他容器中使用它
    • 通常:使用两个虚拟接口,作为交叉电缆
    • Eth0@container netNS,与主机中的虚拟接口vethXXX配对 网络安全。 ➔ 所有虚拟接口vethXXX都桥接在一起。(使用桥接器docker0)
    现在,除了名称空间之外,Linux内核中还有第二个特性使创建容器成为可能:c组(或控制组)

    • 控制组允许我们对以下各项进行计量和限制:
      • 记忆
      • 中央处理器
      • 块I/O
      • 网络

    TL/DL

    简言之: 容器之所以成为可能,是因为内核有两个主要特性: 名称空间和C组

    Cgroups--->限制您可以使用的数量

    名称空间--->限制了您可以看到的内容

    你不能影响你看不见的东西


    回到您的问题,当主机接收到用于容器的数据包时,数据包被层层封装,这样每一层都有助于网络控制器,网络控制器一层接一层地剥离数据包以将其发送到目的地。(类似地,在传出时,分组被逐层封装)

    所以,我认为这也回答了你的两个问题

  • 这不完全是广播。其他容器看不到与它们无关的数据包(名称空间)
  • 由于层是在数据包进入外部网络时添加的,因此外部层(对于不同的主机不同)将帮助数据包唯一地识别其接收者

  • 附言:

    如果有人发现一些信息有误,请在评论中告诉我。我很快就写了这篇文章,很快就会用更好的评论文本更新它


    谢谢。

    查找veth(您的“绑定”概念不太正确)和NAT以及IP表(伪装)之类的内容。您可以为容器设置特定端口,以便在docker主机外部连接。你可以在这里找到很好的解释,它不会产生很多流量/噪音,它有一个NAT,并且确切地知道数据包去哪里。这是默认网桥网络的安全风险。这就是Docker创建网络概念的原因。它允许您将流量隔离到应该进行通信的容器:如果它们选择相同的子网,则不会发生任何不好的情况,事实上,它们在默认情况下是这样做的:类似于172.17.255.255。2台主机有2个独立的NAT,因此每个主机负责正确的路由。在外部,它们使用的是唯一的主机接口(eth0)