本文假设你已经搭建好了kubernetes集群,那么请求是如何到达pod,然后被container处理的。都是干货。
上图显示了kubernetes的基本结构图。
最重要的是最后一句话:一个pod内的container共享同样的网络地址空间。这是通过mapped container做到的。
基本描述为下:
2.1 共享网络模式
下面是一个例子来验证,我这里创建了一个busybox的pod。
我们去192.168.1.226看下这个pod和其container.
发现有两个容器,一个是pause容器,一个是busybox容器。其中pause容器为主网络容器,其他容器都共享pause容器的网络模式。我们分别看下其网络模式。下面是两个容器的网络模式。
所以可以看到fc8580292210(busybox)使用的是pause容器的网络空间。
让我们进一步验证。
2.2 ip地址和hostname、网络io
下面我在 192.168.1.224 搭建了一个dns的pod,里面有4个容器,共享一个网络空间,我们采用查看其ip地址、hostname和网络io的方式来鉴定。 下面是容器的id号
我们查看前三个 b00a08d078d6 4e843585b938 296ff779abb2的上述属性。
2.2.1 dns设置和hostname
2.2.2 ip地址
2.2.3 网络连接io
下面分析下最复杂的container之间的通信。
3.1 pod 之内 container 通信
先说最简单的, pod内的container通信,由于共享网络地址空间,直接访问127.0.0.1即可。
3.2 跨机器之间contianer通信
3.2.1 背景引导
例子: 192.168.1.224的fluentd-elasticsearch容器要连接192.168.1.223的elasticsearch-logging容器。
那么这个过程是如何完成的呢???
3.2.2 container间通信流程
192.168.1.224/fluentd-elasticsearch -> 192.168.1.223/elasticsearch-logging
192.168.1.224/fluentd-elasticsearch 需要连接到elasticsearch-logging容器.
kubernetes的container之间的通信最为复杂。下面是一个小结:
首先需要一个可用的跨机器的容器间网络请求,我这里是flannel,最终的container间通信是通过flannel达成的。
kubernetes让在一个pod的一组container共享一个网络空间,从而让关联密切的container之间的通信变得十分容易。
如果要访问kubernetes集群的其他服务,则需要经过宿主机的iptables的nat规则,请求会发给kube-proxy,kube-proxy知道所有的服务的endpoints,并且知道服务请求是由哪些pod来处理(而这通过label selector完成)。
kube-proxy选择出相应的pod,并且把请求发送给他们处理,而这个pod的地址是 172.16.x.x 也就是docker0网桥桥接的地址,也就是说这时候交给flannel这一层进行处理(如果跨机器的话)或者直接交给本机处理(不跨机器)。