Networking 为Kubernetes建立网络

Networking 为Kubernetes建立网络,networking,docker,kubernetes,subnet,Networking,Docker,Kubernetes,Subnet,我正在阅读《恐怖》一书,并已到达《恐怖》一书,书中写道: Kubernetes imposes the following fundamental requirements on any networking implementation (barring any intentional network segmentation policies): * all containers can communicate with all other containers without NAT *

我正在阅读《恐怖》一书,并已到达《恐怖》一书,书中写道:

Kubernetes imposes the following fundamental requirements on any networking implementation
(barring any intentional network segmentation policies):
* all containers can communicate with all other containers without NAT
* all nodes can communicate with all containers (and vice-versa) without NAT
* the IP that a container sees itself as is the same IP that others see it as
我的第一个困惑是:这与“标准”Docker模型有何不同?Docker与w.r.t.这3个Kubernetes要求有何不同

文章接着总结了GCE是如何达到这些要求的:

对于GoogleComputeEngine集群配置脚本,我们使用高级路由为每个VM分配一个子网(默认为/24-254 IP)。任何绑定到该子网的流量都将通过GCE网络结构直接路由到VM。这是除了分配给虚拟机的“主”IP地址之外的另一个IP地址,该IP地址被NAT用于出站internet访问。linux网桥(称为cbr0)配置为存在于该子网上,并传递给docker的--bridge标志

我的问题是:这一段提到了上面3条中的哪些要求?更重要的是,它是如何达到要求的?我想我不明白每个虚拟机一个子网是如何实现的:容器通信、节点容器通信和静态IP


另外,作为一个额外的问题:为什么Marathon没有像Kubernetes在这里所说的那样受到同样的网络问题的困扰呢?

Docker的标准为您选择一个容器子网。只要它不与主机上的任何接口冲突,Docker就可以接受它

然后,Docker插入一个iptables伪装规则,允许容器使用主机的默认接口与外部世界对话

Kubernetes的3个要求被违反,因为子网仅根据主机上使用的地址进行选择,这迫使要求使用伪装规则NAT所有容器通信

考虑以下3主机Docker设置(有点刻意突出显示):

主持人1: eth0:10.1.2.3

docker0:172.17.42.1/16

集装箱-A:172.17.42.2

主持人2: eth0:10.1.2.4

docker0:172.17.42.1/16

集装箱-B:172.17.42.2

主持人3: eth0:172.17.42.2

docker0:172.18.42.1

假设container-B想要访问container-A的端口80上的HTTP服务。您可以让docker在主机1上的某个位置公开容器-A的端口80。然后,容器-B可能会向10.1.2.3:43210发出请求。这将在容器-A的端口80上收到,但由于NAT正在离开主机2,它看起来像是来自10.1.2.4上的某个随机端口。这违反了所有容器在没有NAT的情况下通信,并且容器看到的IP与其他容器相同的要求。尝试直接从主机2访问容器-A的服务,您的节点可以在不违反NAT的情况下与容器通信

现在,如果这两个容器中的任何一个想要与主机3进行通信,那么它们就是SOL(这只是小心自动分配的docker0子网的一般理由)


关于GCE/AWS/Flannel/…的Kubernetes方法。。。对于每个主机VM,都是从平面专用网络中分割出来的子网。没有子网与VM地址重叠或相互重叠。这让容器和虚拟机可以自然地进行通信。

感谢您提供了如此棒的答案@CJ Cullen(+1)-您的一些快速跟进应该可以为我提供支持,灯泡已经开始亮了。(1) 当你说Docker为你选择一个子网时,你的意思是它选择了一个子网掩码,对吗?您能否确认您的意思是故意选择子网掩码,以避免与主机上正在使用的IP地址冲突?如果是这样,子网掩码如何与主机IP冲突?(2) 为什么这种“子网掩码”选择策略会迫使路由器NAT所有来自主机的流量“然后container-B可能会向10.1.2.3:43210发出请求。这将在container-A的端口80上接收,但看起来它来自10.1.2.4上的某个随机端口,因为NAT正在离开主机2。“您能再解释一下吗?为什么在端口80上会收到对端口43210的请求?NAT如何混淆来自主机2的出口IP/端口?(4)为什么Kubernetes如此担心不使用NAT?!?这有什么不好?最后(我知道很抱歉!)(5)当你说“现在,如果这些容器中的任何一个想要与主机3对话,它们就是SOL”…为什么?!我只是没有看到它。再次感谢这里的所有帮助/澄清!(1)Docker选择整个子网(例如172.17.42.1/16)。子网掩码就是“/16”“部分。Docker避免与主机上使用的地址发生冲突。例如,如果默认接口(或本地名称服务器)具有IP 172.17.42.2,Docker将无法选择172.17.42.1/16(因为它包括172.17.42.2)。(2) 因为Docker只能查看本地使用的地址,所以它分配给容器的地址可能与网络中的其他内容冲突。它可以假定您的主机IP在网络上是唯一的(否则其他所有内容都会中断)。(3)为了向其他机器公开服务,您必须将容器端口绑定到主机端口(请参阅)。端口43210是我选择作为示例的主机端口。(4) Kubernetes的服务模式依赖于平坦的网络空间,还有其他原因(请参阅)。(5) 主机3和容器具有相同的IP。为了进行通信,他们必须进行某种时髦的本地处理(即container-B如何说“将这些数据包发送到主机3”?)。