名称空间的六种分别是:UTC,User,Mount,ipc,pid,Net。网络的名称空间在早些时候就已经添加到内核当中,现在的内核上,基本上是支持的。
网络名称空间主要用于协议栈,网络设备的隔离实现。
一般情况,一个网卡设备只能关联到一个名称空间上,并且都会配置ip地址与外部通讯。假如现在名称空间数量超过物理网卡数量,每一个名称空间内部的进程也需要通过网络进行通讯。 当然,我们是不可能有那么多的网卡设备,而用纯软件的方式模拟一组设备使用。
我们先来看虚拟化网络
虚拟化网络
linux内核支持2层和三层设备来模拟,物理的网卡也就是2层设备,工作在链路层能够封装物理报文,实现在各个设备之间进行报文转发的组件。而这个功能完全可以在linux之上用内核当中对虚拟设备的支持创建虚拟网卡接口的。
而这种网卡接口很独特,是成对出现。可以模拟为一根网线的两头,而linux内核原生支持二层虚拟网桥设备,也就是软件交换机。一头在名称空间,一头在交换机,就相当于模拟了让一个主机链接到交换机上来。如下:
假如有多个一样的名称空间,各自创建虚拟的网卡,一半留在名称空间上,一半留在交换机上,模拟接入机制,就能实现网络功能。如果配置的网络在同一个网段就完成了网络通讯,这种方式就是虚拟化网络。从网络设备通讯到网卡都是用纯软件的方式实现,并且我们能够在一组主机上用纯软件的方式实现,这种实现就是网络虚拟化技术中的一种简单实现。
如著名的OVS(openVswitch)用纯软件实现,并且能够模拟网络的高级功能,如vlan,vxlan,qos,sdn等,都用纯软件实现,额外安装即可。
容器网络
如果是在同一个物理机上的两个容器/名称空间,需要通讯就需要在其物理机之上创建一个交换机,两个容器各自创建一个虚拟网卡,一边在容器之上,一边在交换机上,从而建立通讯联系。如下:
两个交换机内链接交换机的容器各自需要通讯的时候,相互通讯就需要在做一个虚拟网卡,将他们互相链接。
桥接
但是,如果期望经过路由转发,就需要在linux之上打开路由转发,或者通过iptables实现。
- 路由器是三层设备,在linux内核使用单独的名称空间就能支持。
那么,如果现在是第一个host上的namespace1期望与其他host的namespace通讯,按照之前的虚拟机物理桥接方式后,将物理网卡当交换机来使用。所有发往sw1和sw2(上图)的上的容器的通讯先到达物理网卡,物理网卡根据mac地址来判断是最终到达哪里。如果是发给物理网卡本身,就会转交到另外一个的虚拟网卡,这个网卡接收物理网卡报文。而物理网卡本身是交换机。类似于这种。如下:
但是这种方式所有的容器都是桥接的,就容器产生网络风暴,隔离也是问题。
net网络
如果不桥接还要与外部通信,也可以使用net网络。
如果此时namspace2要与namespace3通信,namspace2与host网段也不在同一个网段,namspace2的网关指向sw1,并且在物理主机打开核心转发。
当namspace2和namespace3通讯的时候,先送往sw1,在到达物理内核,物理机查看路由表发出去。其中,namspace2在离开物理机host之前将源ip改成物理网卡的ip地址 。namespace3回复给host物理机的Ip即可。如下图:
这种方式是经过了连击NAT实现,NAT后的ip要想被访问是需要暴露出去的,这就需要DNAT。
如上,namespace2访问namespace3的时候,namespace2出去的时候是做了SNAT,实际上访问的namespace3的host主机地址。而namespace3要想被访问到就需要做DNAT。
这样一来namespace2访问namespace3都是隔着两层,这种方式效率也是很低的,并且互相都不知道真实的ip。但是,这种方式网络是易于管理的。
当然,还有一种网络,比桥接和NAT实现都快速,这种网络就是叠加网络。
在多个物理机有虚拟桥,通讯的时候借助每个物理机器上的物理网卡完成报文隧道转发,通讯中互相就能看到自己。如上图中,namespace2访问namespace3。在叠加网络中namespace2和namespace3是在同一个网段中的,当namespace2访问namespace3时候,网桥是知道namespace3在哪里的
namespace2访问namespace3是做隧道转发的,原地址是namespace2,目标地址是namespace3,报文中还封装了各个namespace位于物理host主机的ip地址。当拆分第一层后就到了namespace的地址了。而后交给软交换到达目标。
参考flannel