k8s 网络模型

一、前言
k8s对Pods之间如何进行组网通信提出了要求,k8s对集群的网络有以下要求:
k8s网络模型设计基础原则:每个Pod都拥有一个独立的 IP地址,而且 假定所有 Pod 都在一个可以直接连通的、扁平的网络空间中。所以不管它们是否运行在同 一 个 Node (宿主机)中,都要求它们可以直接通过对方的 IP 进行访问 。设计这个原则的原因 是,用户不需要额外考虑如何建立 Pod 之间的连接,也不需要考虑将容器端口映射到主机端口等问题 。
由于的网络模型假设 Pod 之间访问时使用的是对方 Pod 的实际地址,所以一个
Pod 内部的应用程序看到的自己的 IP 地址和端口与集群内其他 Pod 看到的一样 。它们都是 Pod 实际分配的IP地址 (从上分配的) 。将IP地址和端口在Pod内部和外部都保持一致,我们可以不使用 NAT 来进行转换,地址空间也自然是平的 。
鉴于上面这些要求,我们需要解决四个不同的网络问题::
下面我们一一进行讨论每种网络问题,以及如何解决 。
二、容器和容器之间的网络
image.png
模式指定新创建的容器和已经存在的一个容器共享一个网络命名空间,而不是和宿主机共享 。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等
每个Pod容器有有一个pause容器其有独立的网络命名空间,在Pod内启动容器时候使用 –net=就可以让当前容器加入到Pod容器拥有的网络命名空间(pause容器)
image.png
三、Pod与Pod之间的网络
image.png
那么是如何做到的?这多亏了使用linux虚拟以太网设备或者说是由两个虚拟接口组成的veth对使不同的网络命名空间链接起来,这些虚拟接口分布在多个网络命名空间上(这里是指多个Pod上) 。
为了让多个Pod的网络命名空间链接起来,我们可以让veth对的一端链接到root网络命名空间(宿主机的),另一端链接到Pod的网络命名空间 。
每对Veth就像一根接插电缆,连接两侧并允许流量在它们之间流动;这种veth对可以推广到同一个Node上任意多的Pod上,如上图这里展示使用veth对链接每个Pod到虚拟机的root网络命名空间 。
下面我们看如何使用网桥设备来让通过veth对链接到root命名空间的多个Pod进行通信 。
linux以太网桥(Linux)是一个虚拟的2层网络设备,目的是把多个以太网段链接起来,网桥维护了一个转发表,通过检查转发表通过它传输的数据包的目的地并决定是否将数据包传递到连接到网桥的其他网段,网桥代码通过查看网络中每个以太网设备特有的MAC地址来决定是传输数据还是丢弃数据 。
image.png
网桥实现了ARP协议用来根据给定的ip地址找到对应机器的数据链路层的mac地址,一开始转发表为空,当一个数据帧被网桥接受后,网桥会广播该帧到所有的链接设备(除了发送方设备),并且把响应这个广播的设备记录到转发表;随后发往相同ip地址的流量会直接从转发表查找正确的mac地址,然后转发包到对应的设备 。
image.png
如上图显示了两个Pod通过veth对链接到root网络命名空间,并且通过网桥进行通信
3.1 同一个Node中的Pod之间的一次通信
鉴于每个Pod有自己独立的网络命名空间,我们使用虚拟以太网设备把多个Pod的命名空间链接到了root命名空间,并且使用网桥让多个Pod之间进行通信,下面我们看如何在两个pod之间进行通信:
image.png
3.2 不同Node中的Pod之间通信
k8s网络模型需要每个pod必须通过ip地址可以进行访问,每个pod的ip地址总是对网络中的其他pod可见,并且每个pod看待自己的ip与别的pod看待的是一样的(虽然他没规定如何实现),下面我们看不同Node间Pod如何交互