阿里开源富容器引擎PouchContainer的网络连接机制



PouchContainer 源自阿里巴巴内部场景,诞生初期,在如何为互联网应用保驾护航方面,倾尽了阿里巴巴工程师们的设计心血。PouchContainer 的强隔离、富容器等技术特性是最好的证明。在阿里巴巴的体量规模下,PouchContainer 对业务的支撑得到双 11 史无前例的检验,开源之后,阿里容器成为一项普惠技术,定位于「助力企业快速实现存量业务容器化」。

本文将给大家介绍 PouchContainer 实现 network 的机制以及将容器连接到 network 上的原理。为了充分阐述 network 的连接机制,本文将以Connect方法为例,叙述如何动态地将一个 container 连接到一个已存在的 network 上。

在目前的容器网络虚拟化技术中,Docker 推行的 CNM (Container Network Model)模型是一种通用的解决方案,CNM 构建了一种成熟的容器虚拟化网络模型,并定义了多种供开发者调用的标准化接口。PouchContainer 沿用了 CNM 模型,基于 libnetwork 来实现容器间通信。下面先对 Sandbox、Endpoint 和 Network 这三个 CNM 中的核心组件进行介绍。

Sandbox

Sandbox 一词在不同的机制里,被分别赋予了不同的定义。例如,在 CRI(container runtime interface)里面 sandbox 就代表着 pod 的概念。而在 CNM 模型里,sandbox 代表着一个容器的网络栈配置,包含管理容器的网卡,路由表以及 DNS 设置。Sandbox 的具体实现可以通过 Linux 系统的 network namespace,一个 FreeBSD Jail 或者其他类似的概念。一个 sandbox 可以包含多个 endpoints。

Endpoint

一个 endpoint 将 sandbox 连接到 network 上。一个 endpoint 的实现可以通过 veth pair,Open vSwitch internal port 或者其他的方式。比较常见的方法是用 veth pair,顾名思义,所有目的地址为容器 IP 的数据包都要经过 eth0 网卡;从 veth 设备出去的数据包,会转发到对应的 eth0 设备上,当数据包的目的地址为 eth0 设备的 IP 时,就能被内核协议栈处理。用 veth pair 来连接两个 network namespace,从而建立网络连通关系。一个 Endpoint 只能属于一个 Network,也只能属于一个 Sandbox。

Network

一个 Network 是一组可以相互通信的 Endpoints 的集合。一个 network 的实现可以通过 Linux bridge,VLAN 或者其他方式。值得一提的是,一个 network 中可以包含很多个 endpoints。

可以看到,在如下图所示的结构下,Container A 和 Container B 同属于 backend network,这两个 container通过各自紫色的 endpoint 构成 network 连接;container B和 container C 同属于 frontend network,通过蓝色的 endpoint 构成 network 连接。因此 container A 和 container B之间可以通信,container B和 container C之间也可以通信。

接下来重点看一下 container B 内部的两个 endpoints,虽然 backend network 和 frontend network 在 container B 内都有各自对应的 endpoint,但紫色 endpoint 和蓝色 endpoint 间不构成通信。因此 backend network 和 frontend network 是两个完全隔离的 network,并不因为连接同一个 container 而产生连通。显而易见,container A 和 container C 间其实是无法通信的。

阿里开源富容器引擎 PouchContainer 的 network 连接机制

bridge 模式是 PouchContainer 默认的网络模式,在创建容器不指定 network 模式,即不写--net参数,该容器就会以 bridge 模式创建。pouchd启动的时候,会自动在主机上创建一个虚拟网桥 p0。后续以 bridge 模式创建容器时,pouchd从 p0 网桥所在的 IP 网段中选取一个未使用的 IP 分配给容器的 eth0 网卡,p0 的 IP 是这些容器的默认网关。

阿里开源富容器引擎 PouchContainer 的 network 连接机制 

在启动容器的时候,选择 host 模式,那么容器将不会获得独立的 network namespace,而是和主机共享 network namespace。因此,这个容器也就没有自己的网卡和 IP 配置,会使用主机的 IP 和端口,但 fs 和 pid 等与主机还是隔离的。

阿里开源富容器引擎 PouchContainer 的 network 连接机制

以 container 模式创建的容器,会和已经存在的容器共享一个 network namespace,直接沿用其 veth 设备对。

阿里开源富容器引擎 PouchContainer 的 network 连接机制

阿里开源富容器引擎PouchContainer的网络连接机制