1、和host共享network namespace
在这种接入模式下,不会为容器创建网络协议栈,即容器没有独立于host的network namespace,但是容器的其他namespace(如IPC、PID、Mount等)还是和host的namespace独立的。容器中的进程处于host的网络环境中,与host共用L2~L4网络资源。该方式的优点是,容器能够直接使用host的网络资源与外界进行通信,没有额外的开销(如NAT);缺点是网络的隔离性差,容器和host所使用的端口号经常发生冲突。
2、和host共享物理网卡
这种方式与上一种方式的区别在于,容器和host共享物理网卡,但容器拥有独立于host的network namespace,容器有自己的MAC地址、IP地址、端口号。这种接入方式主要使用了SR-IOV技术,每个容器分配一个VF,直接通过硬件网卡与外界通信,优点是旁路了内核不占任何计算资源,而且IO速度较快,缺点是VF数量有限且对迁移的支持不足。
3、和另外一个容器共享network namespace
在这种方式中,容器没有独立的network namespace,但是以该方式新创建的容器将与一个已经存在的容器共享其network namespace(包括MAC、IP以及端口号等)。从网络角度上两者将作为一个整体对外提供服务,不过两个容器的其他namespace(如IPC、PID、Mount等)是彼此独立的。这种方式的优点是,network namespace相关的容器间的通信高效便利,缺点是由于其他的namespace仍然是彼此独立的,因此容器间无法形成一个业务逻辑上的整体。
4、通过vSwitch/vRouter接入
在这种方式中,容器拥有独立的network namespace,通过veth-pair连接到vSwitch/vRouter上。这种方式对于网络来说是最为直接的,在vSwitch/vRouter看来,通过这种方式连接的容器与虚拟机并没有任何区别。vSwitch的实现有很多,如Linux Bridge, Open vSwitch等,可用于容器间二层流量的互通,能够对VLAN、Tunnel、SDN Controller等高级功能进行支持。vRouter可用于容器间三层流量的路由,能够对BGP、Tunnel、SDN Controller等提供高级功能的支持。
5、Macvlan/IPvlan
通过vSwitch或者vRouter来接入容器,虽然可以实现丰富的功能,但是却引入了相当的复杂性。Macvlan/IPvlan是由Linux原生提供的网络虚拟化方案,由于二者在部署和使用上的简单性,因此在容器网络中得到了广泛的使用。
Macvlan将一个物理网卡虚拟出多个虚拟网卡,并提供多个虚拟的MAC地址,使用macvlan接入的容器即会获得虚拟的MAC地址。物理网卡在收到流量后,在发送到协议栈前,会在RX函数中判断目的MAC地址,如果为本地容器的虚拟MAC则直接发给相应的namespace。容器的虚拟网卡在发出流量时,会在TX函数中判断目的MAC地址,如果为本地容器的虚拟MAC则直接发给相应的namespace,否则交给物理网卡来处理。Macvlan提供了Bridge、VEPA、Private、Pass Through等多种工作模式。
IPvlan在一个物理网卡上虚拟出多个IP地址,使用IPvlan接入的容器会复用物理网卡的MAC地址,并获得虚拟的IP地址。物理网卡在收到流量后,在发送到协议栈前,会在RX函数中判断目的IP地址,如果为容器的IP则直接发给相应的namespace。容器的虚拟网卡在发出流量时,会在TX函数中判断目的IP地址,如果为本地容器的虚拟IP则直接发给相应的namespace,否则交给宿主机的协议栈进行处理。IPvlan提供了L2和L3两种工作模式,其中L3模式可以实现不同网段间的路由。
6、嵌套部署在VM中
这种方式在生产环境也比较常见,由于一台host中往往部署着多方的容器,所示存在安全隐患,因此许多用户会选择先启动自己的虚拟机,然后在自己的虚拟机上运行容器。这种方式其实是一种嵌套虚拟化。从本质上来说,在这种方式下容器的接入对于host可以是完全透明的,容器在虚拟机内部的接入可以采用上述其他方法。不过这对于云平台来说,这就意味着失去了对容器接入的管理能力,为了保留这一能力,往往需要在虚拟机内部和host中分别部署vswitch并实现级联,由虚拟机内部的vswitch来接入容器并对其进行特定的标记(云平台分配),以便host中的vswitch对其进行识别。一种常见的方式是使用Open vSwitch对容器标记VLAN ID。