k8s网络基础
k8s的4种通信范围
pod内容器通信、各pod间通信、pod与service通信、集群外部与service通信
k8s对service和pod资源对象使用了专门网络,service的网络由k8s管理,但集群自身没有pod网络,需要通过兼容CNI(容器网络接口)规范网络插件配置实现
pod间可不通过NAT机制直接通信
所有节点可不通过NAT机制与容器通信
所有pod对象位于同一平面网络中,而且可以使用pod自身地址直接通信
三个网络
节点网络
各主机自身的网络,就是物理网卡,各主机通过物理网卡通信,该网络本身就存在,不能被k8s管理,需要管理员在集群构建前自行配置并管理
service网络
完全虚拟的网络,此类地址不会配置在物理网卡或pod网卡上,它是由对应节点的
kube-proxy生成对应的iptables或ipvs规则,安照该规则将访问service的数据包转发至后端指定的pod
pod网络
各pod通过该网络进行通信,该网络需要通过网络插件来生成,常见实现机制有overlay和underlay两种,常见解决方案有10多种,
下图客户端pod提供相应service访问,不过集群IP(service地址)是私有网络地址,只能供集群内部访问
总结:k8s创建3种网络分别供节点、pod、service使用,3种网络在node节点实现交汇,由iptables和ipvs规则实现数据转发
也就是说k8s集群中每个节点都有三个维度的网络
pod在不同维度如何通信
pod内容器通信
同一pod内两个容器有一个根容器(pause容器),它是在真正提供服务的容器创建前就创建出来的,不提供任何服务,把所有的容器收纳到一起,一个基础容器,唯一目的就是保存所有的命名空间
同一个节点多个 Pod
pause 容器启动之前,会为容器创建一对虚拟ethernet接口,一个保留在宿主机vethxxx (插在网桥上),一个保留在容器网络命名空间内,并重命名为eth0。两个虚拟接口的两端,从一端进入,另一端出来。任何 Pod 连接到该网桥的 Pod 都可以收发数据
如图所示
通过网桥把veth0和veth1组成为一个以太网,他们直接是可以直接通信的,另外这里通过veth对让pod1的eth0和veth0、pod2的eth0和veth1关联起来,从而让pod1和pod2相互通信。
Pod 1通过自己默认的以太网设备eth0发送一个数据包,eth0把数据传递给veth0,数据包到达网桥后,网桥通过转发表把数据传递给veth1,然后虚拟设备veth1直接把包传递给Pod2网络命名空间中的虚拟设备eth0
linux以太网桥(Linux Ethernet bridge)是一个虚拟的2层网络设备,目的是把多个以太网段链接起来,网桥维护了一个转发表,通过检查转发表通过它传输的数据包的目的地并决定是否将数据包传递到连接到网桥的其他网段,网桥代码通过查看网络中每个以太网设备特有的MAC地址来决定是传输数据还是丢弃数据
通过网桥这里把veth0和veth1组成为一个以太网,他们直接是可以直接通信的,另外这里通过veth对让pod1的eth0和veth0、pod2的eth0和veth1关联起来,从而让pod1和pod2相互通信。
Pod 1通过自己默认的以太网设备eth0发送一个数据包,eth0把数据传递给veth0,数据包到达网桥后,网桥通过转发表把数据传递给veth1,然后虚拟设备veth1直接把包传递给Pod2网络命名空间中的虚拟设备eth0
不同节点两个pod通信
k8s网络模型需要每个pod必须通过ip地址可以进行访问,每个pod的ip地址总是对网络中的其他pod可见,并且每个pod看待自己的ip与别的pod看待的是一样的(虽然他没规定如何实现),下面我们看不同Node间Pod如何交互
k8s中每个集群中的每个Node都会被分配了一个CIDR块(无类别域间路由选择,把网络前缀都相同的连续地址组成的地址组称为CIDR地址块)用来给该Node上的Pod分配IP地址。(保证pod的ip不会冲突)
另外还需要把pod的ip与所在的node ip关联起来
如上图Node1(vm1)上的Pod1与Node2(vm2)上Pod4之间进行交互。
首先pod1通过自己的以太网设备eth0把数据包发送到关联到root命名空间的veth0上,然后数据包被Node1上的网桥设备cbr0接受到,网桥查找转发表发现找不到pod4的Mac地址,则会把包转发到默认路由(root命名空间的eth0设备),然后数据包经过eth0就离开了Node1,被发送到网络。
数据包到达Node2后,首先会被root命名空间的eth0设备接收,然后通过网桥cbr0把数据路由到虚拟设备veth1,最终数据表会被流转到与veth1配对的另外一端(pod4的eth0)
疑问:如果k8s集群有多个node节点的root命名空间网络设备都是eth0,如何将数据转发给正确的node?是不是在集群局域网中广播询问谁有对应的mac地址?
每个Node都知道如何把数据包转发到其内部运行的Pod,当一个数据包到达Node后,其内部数据流就和No