Kubernetes网络原理

来源:互联网 发布:js初始化加载 编辑:程序博客网 时间:2024/06/06 11:49

概述

Kubernetes的搭建与使用少不了网络基础设施的搭建工作, 本文简述了Kubernetes所需要的网络基础环境,Docker的网络实现以及Kubernetes的网络实现。最后,简单提了一下可以实现这些网络基础的网络开源组件Flannel。希望可以通过这些简单的语言描述,让初学者能够初步了解Kubernetes的网络原理。

Kubernetes网络模型

Kubernetes网络模型设计的基础原则:每个Pod都有一个独立的IP地址,这样Pod之间可以直接进行通信,无论它们是否在同一个Node上。而且用户就不需要考虑将容器的端口映射到节点的物理端口上了。

一个Pod分配一个独立的IP,一个Pod内部的所有容器共享一个Linux网络堆栈,包括它们的IP地址、网络设备、配置等都是共享的。所以容器之间是可以通过localhost来连接对方端口的。从这个层面来看,Pod内部容器之间的隔离性相比于不同Pod的容器有所降低,但也只是它们不用相同的端口而已。Pod中的容器有点类似于VM中的进程。

Kubernetes网络模型的必要基础:
1.集群中所有的容器和容器之间可以不通过NAT进行通信
2.节点可以不通过NAT与任一容器进行通信
3.容器的地址和别人看到的地址是一样的

就是说,并不是节点安装了Kubernetes与Docker就可以工作了。还必须满足以上的网络模型才行。而原生的Docker并不能很好的支持这些要求。所以需要一些网络组件来满足这些基础网络要求。

Docker的网络基础

Docker本身的技术依赖于近年来Linux内核虚拟化技术的发展,所以Docker对Linux内核有很强的依赖性。这接下来讲述一下Docker使用到的与Linux网络有关的主要技术。

网络的命名空间

网络命名空间代表的是一个独立的协议栈,所以它们之间是相互隔离的。Docker利用了网络的命名空间特性,实现了不同容器之间网络的隔离。

Veth设备对

引入Veth设备对的目的是让两个网络命名空间进行通信。在Docker内部,Veth设备对也是联系容器到外面的重要设备,离开它是不行的。

网桥

网桥是二层交换机(数据链路层),转发的依据是MAC地址。
在Linux的内部网络栈里也实现了网桥设备,与实际的网桥设备作用相似。是Linux内部各种网络设备之间相互转发数据的二层设备。但Linux网桥与实际的交换机又有不同之处,因为它不仅可能会转发或丢弃,还可能被送到网络协议栈的上层(网络层),从而被自己(网络协议栈)所消化。

Iptables/Netfilter

iptables-save命令可以查看Iptables中的内容
这里写图片描述
我们可以看到service的IP转发到Pod的IP

路由

Linux系统包含一个完整的路由功能。当IP层进行数据的发送或转发时,会使用路由表来决定发往哪里。

Docker的网络实现

标准的Docker支持四种网络模式:host、container、none、bridge。
在Kubernetes管理模式下,通常只会使用bridge模式。如图:
这里写图片描述
这里写图片描述
这里写图片描述
使用ip route show table local type local可以查看本地设备的地址,也显示了docker0网桥的IP地址
这样,在节点内部容器之间可以相互通信,在节点外部则不行。必须将容器的端口映射到主机的端口上才行,docker在跨主机通信时会面临很多的问题。

Kubernetes的网络实现

Kubernetes网络设计主要解决以下场景:
1.容器之间的通信
2.Pod之间的通信
3.Pod到Service之间的通信
4.集群外部与内部组件之间的通信

容器之间的通信

同一个Pod下的容器共享同一个网络命名空间,共享同一个Linux协议栈。所以它们就像在同一台机器上一样。可以相互之间直接通信。可以用localhost访问彼此的端口。

如果容器2运行的是mysql容器,那么容器1通过localhost:3306就直接能够访问运行在容器2上的Mysql了。当然,既然像是在同一台机器上的不同进程,那么它们之间也就是可以通过IPC(进程间通信)进行通信(如消息队列或管道)。
这里写图片描述

Pod之间的通信

同一Node内的Pod之间的通信

这里写图片描述
同一个Node内的不同Pod都是通过Veth连接在同一个Docker0网桥上的。所以它们之间是可以直接进行通信的。而且,非本地数据的网络数据都是默认发送到Docker0网桥然后由它进行中转的。
Docker0网桥会路由到节点上的所有Pod的,这个可以通过看Kubernetes任一节点上的路由表了解
这里写图片描述
这个就表示docker0的IP地址为10.0.82.1,而该节点上的Pod都是10.0.82网段的。

不同Node上的Pod之间的通信

不同Node上的Pod与Pod之间进行通信,肯定是要通过节点的物理网卡的。而且不同的Pod肯定是不能有相同的私有IP的。另外,我们还必须要有Node IP找到该Pod的IP才成。
对于这些要求,Flannel就可以做得到。
这里写图片描述

开源的网络组件

Kubernetes是谷歌的开源项目,它假定了所有的Pod都是在一个可以直接连通的扁平的网络空间中,因为它建立在GCE上,而GCE已经实现了这些要求。

但是对于一个私有云来说,要想用Kubernetes就必须自己来实现这个网络假设。有些开源软件可以做到这些。

Flannel

Flannel实现了两点来保证Kubernetes的底层网络:
1.保证集群中每个Pod的IP不冲突
2.建立了一个覆盖网络,保证数据可以在不同节点之间的Pod传递(通过Pod节点路由表可以找到Pod与节点的对应关系)
这里写图片描述

原创粉丝点击