为Kubernetesbuild立networking

我正在阅读Kubernetes的“ 从头开始 ”指南,并已到达可怕的networking科 ,他们在这里指出:

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与3 Kubernetes的要求有何不同?

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

对于Google Compute Engine群集configuration脚本,我们使用高级路由为每个VM分配一个子网(默认值为24到254个IP)。 任何绑定到该子网的stream量将由GCEnetworking结构直接路由到VM。 这是除了分配给虚拟机的“主”IP地址之外,这个IP地址已经被NAT用于出站互联网访问。 一个linux桥(称为cbr0)被configuration为存在于该子网上,并被传递给docker的-bridge标志。

这里我的问题是: 这个段落地址中的以上3个要求什么? 更重要的是,它是如何达到要求的? 我想我只是不明白如何1-subnet-per-VM完成:容器容器通信,节点容器通信和静态IP。


而且,作为一个奖励/延伸的关注:为什么马拉松不像Kubernetes在这里要解决的networking问题?

Docker的标准networkingconfiguration会为您select一个容器子网。 只要不与主机上的任何接口相冲突,Docker都可以。

然后,Docker插入一个iptables MASQUERADE规则,允许容器使用主机的默认接口与外部世界进行通信。

Kubernetes的3要求违反了这样一个事实,即只根据主机上使用的地址来select子网,这强制要求使用MASQUERADE规则对所有的容器通信进行NAT。

考虑下面的三主机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

比方说容器B想要访问容器-A的 80端口上的HTTP服务。 你可以让docker在主机1的某个地方展示container-A的端口80。 然后, 容器B可能会向10.1.2.3:43210发出请求。 这将在容器A的端口80上接收,但是看起来像来自10.1.2.4上的一些随机端口,因为在主机2出口的NAT。 这违反了所有容器在没有NAT情况下进行通信,并且容器看到与其他要求相同的IP 。 尝试直接从主机2访问容器-A的服务,并且您的节点可以与容器进行通信,而不会违反NAT

现在,如果其中任何一个容器都要与主机3通信 ,那么它们就是SOL(只是小心使用自动分配的docker0子网的一般参数)。

Kubernetes在GCE / AWS / Flannel / …上的做法是为每个主机VM 分配一个从平面专用networking中划分出来的子网。 没有子网与VM地址或彼此重叠。 这使得容器和虚拟机无缝地通信。