Dockernetworking
我正在尝试了解下列之间的关系:
- 主机上的
eth0
; 和 -
docker0
桥; 和 - 每个容器上的
eth0
接口
我的理解是Docker:
- 创build一个
docker0
网桥,然后为其分配一个与主机上运行的任何内容不冲突的可用子网; 然后 - Docker将
docker0
绑定到主机上运行的eth0
; 然后 - Docker绑定每个新build的容器,将其
docker0
到docker0
,以便容器的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概念很清楚。 让我先澄清这一部分:
所以这是如何发生的:
- Docker使用称为命名空间的Linux内核function对资源进行分类/划分。
- 当容器启动时,Docker会为该容器创build一组名称空间。
- 这提供了一个隔离层。
- 其中之一是“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控制器,这个层将数据包层剥离后发送到它的目的地。 (同样,在外发时,数据包是逐层封装的)
所以,我认为这也回答了你的两个问题。
- 这不完全是一个广播。 其他容器看不到与它们不相关的数据包(名称空间)。
- 由于数据包是在外部networking传输时添加的,所以外部层(对于不同的主机不同)将有助于数据包唯一地识别接收者。
PS:
如果有人发现一些错误的信息,请在评论中告诉我。 我已经写了这个匆忙,将尽快与更好的审查文本更新。
谢谢。