Kuberneters--kubernetes网络实现
一、K8S网络实现在实际的业务场景中,业务组件之间关系十分复杂,特别是随着微服务的发展。为了支持业务应用组件的通信,Kubernetes网络的设计主要致力于解决以下问题:容器与容器之间的直接通信抽象Pod到Pod之间的通信Pod到Service之间的通信集群外部与内部组件之间的通信二、容器到容器的通信同一个Pod内的容器(Pod内的容器不会跨宿主机的)共享一个网络的命名空间,共享同一个Linux协
一、K8S网络实现
在实际的业务场景中,业务组件之间关系十分复杂,特别是随着微服务的发展。为了支持业务应用组件的通信,Kubernetes网络的设计主要致力于解决以下问题:
- 容器与容器之间的直接通信
- 抽象Pod到Pod之间的通信
- Pod到Service之间的通信
- 集群外部与内部组件之间的通信
二、容器到容器的通信
同一个Pod内的容器(Pod内的容器不会跨宿主机的)共享一个网络的命名空间,共享同一个Linux协议栈。所以对于网络的各种操作,就和他们在同一台机器上一台,可以用localhost地址访问彼此的端口。
这样设计简单、安全和高效,也能减小已经存在的程序从物理机或者虚拟机移植到容器下运行的难度。
在Node上运行一个Pod实例,容器就是容器1和容器2。容器1和容器2共享一个网络命名空间,共享一个命名空间的结果就是他们好像在一台机器上运行,它们打开的端口不会有冲突,可以直接使用Linux本地IPC进行通信(例如消息队列或管道)。这和传统一组普通程序运行的环境是一样的,传统程序不需要针对网络做特别的修改就可以移植,它们之间的互相访问只需要localhost就额可以。
三、Pod之间通信
每一个Pod都有一个真实的全局IP地址,同一个Node内不同Pod之间可以之间采用对方Pod的IP地址通信,而且不需要采用 其它发现机制,例如DNS、Consul或etcd。
Pod容器既有可能在同一个Node上运行,也有可能在不同的Node上运行,所以通信分为2类:同一个Node内Pod之间的通信和不同Node上Pod之间通信。
3.1. 同一个Node内Pod通信
Pod1和Pod2都是通过Veth连接到同一个docker0网桥上的,它们的IP地址IP1、IP2都是从docker0的网段上动态获取的,它们和网桥本身的IP3是同一个网段的。在Pod1、Pod2的linux协议栈上,默认路由都是docker0的地址,也就是说非本地地址的网络数据,都会被默认发送到docker0网桥上,由docker0网桥直接中转。
由于同一个Node内的Pod都关联在同一个docker0网桥上,地址段相同,所以它们才会直接通信。
3.2. 不同Node内Pod通信
Pod地址是与docker0在同一个网段的,它们知道docker0网段与宿主机网卡是两个完全不同的IP网段,并且不同Node之间通信只能通过宿主机的物理网卡进行,因此要想实现不同Node上的Pod容器之间的通信,就必须想办法通过主机的这个IP地址进行寻址和通信。
这些动态分配且藏在docker0之后的所谓“私有”IP地址也可以找到。在Kuberbetes会记录所有正在运行的Pod的IP分配信息,并且将这些信息保存在etcd中(作为Service的Endpoint),这些私有IP信息对于Pod到Pod通信非常重要,因为网络模型要求Pod到Pod使用私有IP进行通信。
Kubernetes的网络对Pod的地址是平面的和直达的,所以这些Pod的IP规划很重要,不能有冲突。只要没有冲突,就可以在整个Kubernetes的集群中找到它。
支持不同Node上Pod之间的通信需要满足两个条件:
- 在整个Kubernetes集群中对Pod的IP分配进行规划,不能有冲突
- 找到一种办法,将整个Pod的IP和所在Node的IP关联起来,通过整个关联让Pod之间可以互相访问
根据条件1的要求,在部署Kubernetes时对docker0的IP地址进行规划,保证每个Node上的docker0地址没有冲突。可以在规划后手工配置到每个Node上,或者做一个分配规划,由安装的程序自己去分配占用。例如:Kubernetes的网络增强开源软件Flannel自己能够管理资源池分配
根据条件2的要求,Pod中的数据在发出时,需要由一个机制能够知道对方Pod的IP地址在哪个具体Node上。也就是说先找到Node对应宿主机的IP地址,将数据发送到宿主机的网卡,然后在宿主机上将相应的数据转发到具体的docker0上。一旦数据到达宿主机的Node,则哪个Node内部的docker0便知道如何将数据发送到Pod。
在图7.10中,IP1对应的是Pod1,IP2对应的是Pod2。Pod1在访问Pod2时,首先要将数据从源Node的eth0发送出去,找到并到达Node2的eth0。即先从IP3到达IP4的递送,之后才是从IP4到IP2的递送。
在谷歌的GCE环境中,Pod的IP管理(类似docker0)、分配及它们之间的路由打通都是由GCE完成的。Kubetnetes作为主要在GCE上面运行的框架,它的设计是假设底层已经具备这些条件,所以它分配完地址并将地址记录下来完成了它的工作。在实际的GCE环境中,GCE的网络组件会记录读取这些信息,实现网络打通。
在实际生产环境中,因为费用、安全、合规等种种原因,kubernetes用户不会全部使用GCE环境,在实际私有云环境中,除了需要部署Kubernetes和Docker,还需要部署额外的网络配置,甚至通过一些软件实现Kubertes对网络的要求。做到这些后,Pod和Pod之前才能无差别的通信。
更多推荐
所有评论(0)