Dockernetworking

我正在尝试了解下列之间的关系:

  • 主机上的eth0 ; 和
  • docker0桥; 和
  • 每个容器上的eth0接口

我的理解是Docker:

  1. 创build一个docker0网桥,然后为其分配一个与主机上运行的任何内容不冲突的可用子网; 然后
  2. Docker将docker0绑定到主机上运行的eth0 ; 然后
  3. Docker绑定每个新build的容器,将其docker0docker0 ,以便容器的eth0接口连接到docker0上的docker0 ,主机又连接到主机上的eth0

这样,当主机外部的东西试图与容器通信时,它必须将消息发送到主机IP上的端口,然后转发到docker0网桥,然后广播到主机上运行的所有容器,是吗?

另外,这样,当一个容器需要与主机之外的某个东西进行通信时,它有自己的IP(从docker0子网租用),所以远程调用者将看到来自容器IP的消息。

所以,如果我上面说的是不正确的, 请首先澄清我!

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

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

我不会说你对Docker中的networking概念很清楚。 让我先澄清这一部分:

所以这是如何发生的:

  1. Docker使用称为命名空间的Linux内核function对资源进行分类/划分。
  2. 当容器启动时,Docker会为该容器创build一组名称空间。
  3. 这提供了一个隔离层。
  4. 其中之一是“networking名称空间”:用于pipe理networking接口。

现在谈一下关于networking命名空间:

networking名称空间,

  • 让每个容器都有自己的networking资源,拥有自己的networking堆栈。
    • 它是自己的networking接口。
    • 它是自己的路由表。
    • 这是自己的iptables规则。
    • 它是自己的套接字(ss,netstat)
  • 我们可以通过networking名称空间来移动networking接口。
  • 所以我们可以在某个地方创build一个netns,并在其他容器中使用它。
  • 通常:使用两个虚拟接口,它们充当交叉电缆。
  • Eth0 @ container netNS,与主机networkingns中的虚拟接口vethXXX配对。 ➔所有虚拟接口vethXXX桥接在一起。 (使用网桥docker0)

现在,除了命名空间之外,Linux内核中还有第二个function可以创build容器:c组(或控制组)。

  • 控制组让我们实施计量和限制:
    • 记忆
    • 中央处理器
    • 块I / O
    • networking

TL / DL

简而言之:由于内核的两个主要特性:名称空间和C组,使得容器成为可能。

Cgroups —>限制你可以使用多less。

命名空间—>限制你可以看到。

而你不能影响你看不到的东西。


回到你的问题,当一个容器的主机接收到一个数据包的时候,它被封装在一个层中,使得每一层都帮助networking控制器,这个层将数据包层剥离后发送到它的目的地。 (同样,在外发时,数据包是逐层封装的)

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

  1. 这不完全是一个广播。 其他容器看不到与它们不相关的数据包(名称空间)。
  2. 由于数据包是在外部networking传输时添加的,所以外部层(对于不同的主机不同)将有助于数据包唯一地识别接收者。

PS:

如果有人发现一些错误的信息,请在评论中告诉我。 我已经写了这个匆忙,将尽快与更好的审查文本更新。

谢谢。