Kubernetes CNI网络插件

容器网络接口,就是在网络解决方案由网络插件提供,这些插件配置容器网络则通过CNI定义的接口来完成,也就是CNI定义的是容器运行环境与网络插件之间的接口规范。这个接口只关心容器的网络连接,在创建容器是分配网络,删除容器是移除网络。插件就是对CNI的规范的具体实现。

Network Namespace提供的是什么

这里我们简要回顾一下,容器具有自己的网络协议栈而且被隔离在它自己的网络名称空间内,在这个隔离的网络空间里会为容器提供网卡、回环设备、IP地址、路由表、防火墙规则等这些基本的网络环境。

为什么POD中的容器共享同一网络名称空间

每一个POD中都有一个特殊的容器且永远是POD中创建的第一个容器,只是我们查看的时候看不到,因为它完成作用就暂停了。这个容器就是Infra容器,使用汇编语言编写。当创建POD的时kubernetes先创建名称空间,然后把其中的网络名称空间和这个Infra关联,后面属于你的创建的容器都是通过Join的方式与这个Infra容器关联在一起,这样这些容器和Infra都属于一个网络名称空间,这也就是为什么POD中多个容器可以使用本地通信的原因,所以严格意义来说网络名称空间属于Infra。我们看下面的演示

我们启动POD

Kubernetes CNI网络插件

登陆Srv03

Kubernetes CNI网络插件

查看这个进程所属的名称空间,如下图:

Kubernetes CNI网络插件

上图说容器名称空间,其实是那个进程的名称空间,名称空间名称-->该名称空间的文件描述符。

就拿net来说,它为进程提供了一个完全独立的网络协议栈视图,包括网络接口、IPV4/6协议栈、IP路由表、防火墙规则等,也就是为进程提供一个独立的网络环境。

进入POD中的容器,查看这个名称空间

Kubernetes CNI网络插件

可以看到链接的文件的指向的都是一样的,我这里的POD只有一个容器,如果设置2个你就可以分别进入查看,指向都是一样的。

上面的结果其实为进程创建的名称空间,Infra容器抓住网络名称空间,然后POD中的容器JOIN到Infra中,这样POD中的容器就能使用这个网络名称空间。所以Kubernetes的网络插件考虑的不是POD中容器的网络配置,而是配置这个POD的Network Namespace。

Infra是为了给容器共享网络名称空间,当然也可以共享volume。

理解了为什么POD里面的容器可以进行本地通信的原因,我们就要向下看一层,是谁给这个Infra使用的网络名称空间提供的各种网络栈配置呢?

谁为容器提供的网络配置

我们这里以网桥模式为例来说明。容器就是进程,容器拥有隔离的网络名称空间,就意味着进程所在的网络名称空间也是隔离的且和外界不能联系,那么如何让实现和其他容器交互呢?你就理解为2台独立的主机要想通信就把它们连接到一个交换机上,通过一个中间设备来连接两个独立的网络。这个就是能起到交换机作用的网桥,Linux中就有这样一个虚拟设备。有了这样一个设备那么就要解决谁来创建、谁来连接两个容器的网络名称空间的问题。

Docker项目

在Dcoker项目中,这个网桥是由docker来创建的且安装完之后就会默认创建一个这样的设备,默认叫做docker0,这种网桥并不是docker的专利,是属于Linux内核就支持的功能,docker只是通过某些接口调用创建这样一个网桥并且命名为docker0。

网桥是一个二层设备,传统网桥在处理报文时只有2个操作,一个是转发;一个是丢弃。当然网桥也会做MAC地址学习就像交换机一样。但是Linux中的虚拟网桥除了具有传统网桥的功能外还有特殊的地方,因为运行虚拟网桥的是一个运行着Linux内核的物理主机,有可能网桥收到的报文的目的地址就是这个物理主机本身,所以这时候处理转发和丢弃之外,还需要一种处理方式就是交给网络协议栈的上层也就是网络层,从而被主机本身消化,所以Linux的虚拟网桥可以说是一个二层设备也可以说是一个三层设备。另外还有一个不同的地方是虚拟网桥可以有IP地址。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpgffx.html