文章首发于我的公众号「Linux云计算网络」,欢迎关注,第一时间掌握技术干货!

知其然而不知其所以然,不知也。老古人说得多好,学知识不懂得知识背后的原理,等于白学。

通过前面两篇文章,我们知道了容器的单主机网络和多主机网络,对于这么多网络方案,我们看到对 Docker 的整体网络结构好像没有改动,都是水平扩展的,那 Docker 网络究竟是怎么集成这么多网络方案而不改变自身原有的结构呢?本文就来一探究竟。

1 Docker 的总体框架


要回答这个问题,得从 Docker 的总体框架说起。

容器和虚拟机一样,都是虚拟化的产品,都包括计算虚拟化,存储虚拟化和 IO 虚拟化。容器作为轻量级的进程,不像虚拟机那般复杂,这三块分别靠三个 Driver 来完成的,execdriver 负责计算虚拟化,networkdriver 负责网络虚拟化,graphdriver 负责存储虚拟化。由此可见,Docker 靠 Driver 这种设计思想来支撑起它的基础平台,再往深了挖,它的每个子模块都随处可见这种设计思想,就网络这个子模块来看,也是如此。

2 Docker 的网络模型


docker engine + libcontainer


期初的 Docker 网络子模块的代码是分散在 docker daemon 和 libcontainer 中的,libcontainer 是一个独立的容器管理包,execdriver 和 networkdriver 都是通过 libcontainer 来实现对容器的具体操作。

随着业务场景越来越复杂,这种内嵌的方式很难针对不同的网络场景进行扩展。后来,Docker 收购了一个做多主机网络解决方案的公司 SocketPlane,然后让那帮人专门来解决这个问题。这就是接下来要介绍的 libnetwork。

libnetwork && CNM


libnetwork 起初的做法很简单,就是将 docker engine 和 libcontainer 中网络相关的代码抽出来,合并成一个单独的库,做成网络抽象层,并对外提供 API。Docker 的愿景就是希望 libnetwork 能够做像 libcontainer 那样,成为一个多平台的容器网络基础包。

后来受一个 GitHub issue ( https://github.com/moby/moby/issues/9983) 的启发,libnetwork 引入容器网络模型(Container Network Model,CNM),该模型进一步对 Docker 的网络结构进行了细分,提出了三个概念:network、sandbox 和 endpoint。

network

network 是一个抽象的概念,你可以把它理解成一个网络的插件,或者是网络的 Driver,比如说单主机网络的 Driver 就有 none、host、bridge,joined container 这四种,多主机网络就有 overlay、macvlan、flannel 这些。network 可以独立出去做,只需调用 Docker 对外提供的 API 就可以作为插件集成到 Docker 网络中使用。

sandbox

sandbox 实现了容器内部的网络栈,它定义容器的虚拟网卡,路由表和 DNS 等配置,其实就是一个标准的 linux network namespace 实现。

endpoint

network 实现了一个第三方的网络栈,sandbox 则实现了容器内部的网络栈,那这两者怎么联系起来呢?答案就是通过 endpoint,endpoint 实现了 veth pair,一个 endpoint 就表示一对 veth pair,一端挂在容器中,另一端挂在 network 中。

network、sandbox 和 endpoint 三者之间的关系:
一个 network 可以包含多个 endpoint,自然也就包含多个 sandbox。
一个 sandbox 可以包含多个 endpoint,可以属于多个 network。
一个 endpoint 只可以属于一个 network,并且只属于一个 sandbox。

如上图显示三个容器,每个容器一个 sandbox,除了第二个容器有两个 endpoint 分别接入 network1 和 network2 之外,其余 sandbox 都只有一个 endpoint 分别接入不同的 network。

到此,我们就可以解答文章开篇提到的问题,“不同的网络方案如何集成到 Docker 网络模型中而不改变原有结构?”

答案就是基于 libnetwork CNM,将各个网络模型以插件或 Driver 的形式集成到 Docker 网络中来,与 docker daemon 协同工作,实现容器网络。Docker 原生的 Driver 包括单主机的 none、bridge、joined container 和 多主机的 overlay、macvlan,第三方 Driver 就包括多主机的 flannel、weave、calico 等。

3 总结


  1. libnetwork 基于 CNM 模型将 Docker 网络结构从原生方案中抽离出来,增强了网络扩展性,以至于现在各种网络方案层出不穷,都可以轻松集成到 Docker 中。
  2. network,sandbox,endpoint 三个概念。

PS:文章未经我允许,不得转载,否则后果自负。

–END–

欢迎扫👇的二维码关注我的微信公众号,后台回复「m」,可以获取往期所有技术博文推送,更多资料回复下列关键字获取。

文章首发于我的公众号「Linux云计算网络」,欢迎关注,第一时间掌握技术干货!

上篇文章介绍了容器网络的单主机网络,本文将进一步介绍多主机网络,也就是跨主机的网络。总结下来,多主机网络解决方案包括但不限于以下几种:overlay、macvlan、flannel、weave、cacico 等,下面将分别一一介绍这几种网络,

PS:本文仅从原理上对几种网络进行简单的对比总结,不涉及太多的细节。

1 overlay


俗称隧道网络,它是基于 VxLAN 协议来将二层数据包封装到 UDP 中进行传输的,目的是扩展二层网段,因为 VLAN 使用 12bit 标记 VLAN ID,最多支持 4094 个 VLAN,这对于大型云网络会成为瓶颈,而 VxLAN ID 使用 24bit 来标记,支持多达 16777216 个二层网段,所以 VxLAN 是扩展了 VLAN,也叫做大二层网络。

overlay 网络需要一个全局的“上帝”来记录它网络中的信息,比如主机地址,子网等,这个上帝在 Docker 中是由服务发现协议来完成的,服务发现本质上是一个 key-value 数据库,要使用它,首先需要向它告知(注册)一些必要的信息(如网络中需要通信的主机),然后它就会自动去收集、同步网络的信息,同时,还会维护一个 IP 地址池,分配给主机中的容器使用。Docker 中比较有名的服务发现有 Consul、Etcd 和 ZooKeeper。overlay 网络常用 Consul。

创建 overlay 网络会创建一个 Linux bridge br0,br0 会创建两个接口,一个 veth2 作为与容器的虚拟网卡相连的 veth pair,另一个 vxlan1 负责与其他 host 建立 VxLAN 隧道,跨主机的容器就通过这个隧道来进行通信。

为了保证 overlay 网络中的容器与外网互通,Docker 会创建另一个 Linux bridge docker_gwbridge,同样,该 bridge 也存在一对 veth pair,要与外围通信的容器可以通过这对 veth pair 到达 docker_gwbridge,进而通过主机 NAT 访问外网。

2 macvlan


macvlan 就如它的名字一样,是一种网卡虚拟化技术,它能够将一个物理网卡虚拟出多个接口,每个接口都可以配置 MAC 地址,同样每个接口也可以配自己的 IP,每个接口就像交换机的端口一样,可以为它划分 VLAN。

macvlan 的做法其实就是将这些虚拟出来的接口与 Docker 容器直连来达到通信的目的。一个 macvlan 网络对应一个接口,不同的 macvlan 网络分配不同的子网,因此,相同的 macvlan 之间可以互相通信,不同的 macvlan 网络之间在二层上不能通信,需要借助三层的路由器才能完成通信,如下,显示的就是两个不同的 macvlan 网络之间的通信流程。

我们用一个 Linux 主机,通过配置其路由表和 iptables,将其配成一个路由器(当然是虚拟的),就可以完成不同 macvlan 网络之间的数据交换,当然用物理路由器也是没毛病的。

3 flannel


flannel 网络也需要借助一个全局的上帝来同步网络信息,一般使用的是 etcd。

flannel 网络不会创建新的 bridge,而是用默认的 docker0,但创建 flannel 网络会在主机上创建一个虚拟网卡,挂在 docker0 上,用于跨主机通信。

组件方式让 flannel 多了几分灵活性,它可以使用二层的 VxLAN 隧道来封装数据包完成跨主机通信,也可以使用纯三层的方案来通信,比如 host-gw,只需修改一个配置文件就可以完成转化。

4 weave


weave 网络没有借助服务发现协议,也没有 macvlan 那样的虚拟化技术,只需要在不同主机上启动 weave 组件就可以完成通信。

创建 weave 网络会创建两个网桥,一个是 Linux bridge weave,一个是 datapath,也就是 OVS,weave 负责将容器加入 weave 网络中,OVS 负责将跨主机通信的数据包封装成 VxLAN 包进行隧道传输。

同样,weave 网络也不支持与外网通信,Docker 提供 docker0 来满足这个需求。

weave 网络通过组件化的方式使得网络分层比较清晰,两个网桥的分工也比较明确,一个用于跨主机通信,相当于一个路由器,一个负责将本地网络加入 weave 网络。

5 calico


calico 是一个纯三层的网络,它没有创建任何的网桥,它之所以能完成跨主机的通信,是因为它记住 etcd 将网络中各网段的路由信息写进了主机中,然后创建的一对的 veth pair,一块留在容器的 network namespace 中,一块成了主机中的虚拟网卡,加入到主机路由表中,从而打通不同主机中的容器通信。

calico 相较其他几个网络方案最大优点是它提供 policy 机制,用户可以根据自己的需求自定义 policy,一个 policy 可能对应一条 ACL,用于控制进出容器的数据包,比如我们建立了多个 calico 网络,想控制其中几个网络可以互通,其余不能互通,就可以修改 policy 的配置文件来满足要求,这种方式大大增加了网络连通和隔离的灵活性。

6 总结


1、除了以上的几种方案,跨主机容器网络方案还有很多,比如:Romana,Contiv 等,本文就不作过多展开了,大家感兴趣可以查阅相关资料了解。

2、跨主机的容器网络通常要为不同主机的容器维护一个 IP 池,所以大多方案需要借助第三方的服务发现方案。

3、跨主机容器网络按传输方式可以分为纯二层网络,隧道网络(大二层网络),以及纯三层网络。

PS:文章未经我允许,不得转载,否则后果自负。

–END–

欢迎扫👇的二维码关注我的微信公众号,后台回复「m」,可以获取往期所有技术博文推送,更多资料回复下列关键字获取。

文章首发于我的公众号「Linux云计算网络」,欢迎关注,第一时间掌握技术干货!

在看本文之前,建议先看 virtio 简介,vhost 简介,vhost-user 简介。

virtio-user 是 DPDK 针对特定场景提出的一种解决方案,它主要有两种场景的用途,一种是用于 DPDK 应用容器对 virtio 的支持,这是 DPDK v16.07 开始支持的;另一种是用于和内核通信,这是 DPDK v17.02 推出的。

1 virtio_user 用于容器网络


我们知道,对于虚拟机,有 virtio 这套半虚拟化的标准协议来指导虚拟机和宿主机之间的通信,但对于容器的环境,直接沿用 virtio 是不行的,原因是虚拟机是通过 Qemu 来模拟的,Qemu 会将它虚拟出的整个 KVM 虚拟机的信息共享给宿主机,但对于 DPDK 加速的容器化环境来说显然是不合理的。因为 DPDK 容器与宿主机的通信只用得到虚拟内存中的大页内存部分,其他都是用不到的,全部共享也没有任何意义,DPDK 主要基于大页内存来收发数据包的。

所以,virtio_user 其实就是在 virtio PMD 的基础上进行了少量修改形成的,简单来说,就是添加大页共享的部分逻辑,并精简了整块共享内存部分的逻辑。

有兴趣可以对照 /driver/net/virtio 中的代码和 DPDK virtio_user 代码,其实大部分是相同的。

从 DPDK 的角度看,virtio_user 是作为一个虚拟设备(vdev)来加载的,它充当的是一个 virtio 前端驱动,与之对应的后端通信驱动,是用户态的 vhost_user,在使用的时候,我们只需要定义好相应的适配接口即可,如下:

vhost 和 vhost_user 本质上是采用共享内存的 IPC 方式,通过在 host 端创建 vhost_user 共享内存文件,然后 virtio_user 启动的时候指定该文件即可,如:

1
2
3
4
1)首先创建 vhost_user 共享内存文件
--vdev 'eth_vhost_user0,iface=/tmp/vhost_user0'
2)启动 virtio_user 指定文件路径
--vdev=virtio_user0,path=/tmp/vhost_user0

2 virtio_user 作为 exception path 用于与内核通信


virtio_user 的一个用途就是作为 exception path 用于与内核通信。我们知道,DPDK 是旁路内核的转包方案,这也是它高性能的原因,但有些时候从 DPDK 收到的包(如控制报文)需要丢到内核网络协议栈去做进一步的处理,这个路径在 DPDK 中就被称为 exception path。

在这之前,已经存在几种 exception path 的方案,如传统的 Tun/Tap,KNI(Kernel NIC Interface),AF_Packet 以及基于 SR-IOV 的 Flow Bifurcation。这些方案就不做过多介绍了,感兴趣的可看 DPDK 官网,上面都有介绍。

和容器网络的方案使用 vhost_user 作为后端驱动一样,要使得 virtio_user 和内核通信,只需加载内核模块 vhost.ko,让它充当的是 virtio_user 的后端通信驱动即可。

所以,我们可以看到,其实这两种方案本质上是一样,只是换了个后端驱动而已,这也是 virtio 的优势所在,定义一套通用的接口标准,需要什么类型的通信方式只需加载相应驱动即可,改动非常少,扩展性非常高。

PS:文章未经我允许,不得转载,否则后果自负。

–END–

欢迎扫👇的二维码关注我的微信公众号,后台回复「m」,可以获取往期所有技术博文推送,更多资料回复下列关键字获取。

文章首发于我的公众号「Linux云计算网络」,欢迎关注,第一时间掌握技术干货!

01 写在前面


我的读者当中应该有一部分人是做 DPDK 相关的,我自己虽然现在已经不做 DPDK 了,但对这块仍然有兴趣,今天这篇文章就来总结下 DPDK 的技术栈。注意:这篇文章是小白文,不适合大神哦。

文章从 DPDK 的产生背景,到核心技术,再到应用场景,都进行了阐述,有可能是你见过的讲得最全面的文章了,当然,讲得全面自然会少了深度,你如果不屑忽略就好了。

其实,本文之前已经发过,但在整理的时候不小心删了,索性就重发一次,但这一次多了一些内容,文末我还会推荐一些学习资料,有需要的可以拉到最下面查看获取方法。

02 高性能网络技术


随着云计算产业的异军突起,网络技术的不断创新,越来越多的网络设备基础架构逐步向基于通用处理器平台的架构方向融合,从传统的物理网络到虚拟网络,从扁平化的网络结构到基于 SDN 分层的网络结构,无不体现出这种创新与融合。

这在使得网络变得更加可控制和成本更低的同时,也能够支持大规模用户或应用程序的性能需求,以及海量数据的处理。究其原因,其实是高性能网络编程技术随着网络架构的演进不断突破的一种必然结果。

03 C10K 到 C10M 问题的演进


说到高性能网络编程,一定逃不过 C10K 问题(即单机 1 万个并发连接问题),不过这个问题已经成为历史了,很多技术可以解决它,如常用的 I/O 多路复用模型,select, poll, epoll 等。在此基础上也出了很多优秀的框架,比如 Nginx 基于事件驱动的 Web 服务框架,以及基于 Python 开发的 Tornado 和 Django 这种非阻塞的 Web 框架。

如今,关注的更多是 C10M 问题(即单机 1 千万个并发连接问题)。很多计算机领域的大佬们从硬件上和软件上都提出了多种解决方案。从硬件上,比如说,现在的类似很多 40Gpbs、32-cores、256G RAM 这样配置的 X86 服务器完全可以处理 1 千万个以上的并发连接。

但是从硬件上解决问题就没多大意思了,首先它成本高,其次不通用,最后也没什么挑战,无非就是堆砌硬件而已。所以,抛开硬件不谈,我们看看从软件上该如何解决这个世界难题呢?

这里不得不提一个人,就是 Errata Security 公司的 CEO Robert Graham,他在 Shmoocon 2013 大会上很巧妙地解释了这个问题。有兴趣可以查看其 YouTube 的演进视频: C10M Defending The Internet At Scale。

他提到了 UNIX 的设计初衷其实为电话网络的控制系统而设计的,而不是一般的服务器操作系统,所以,它仅仅是一个负责数据传送的系统,没有所谓的控制层面和数据层面的说法,不适合处理大规模的网络数据包。最后他得出的结论是:

OS 的内核不是解决 C10M 问题的办法,恰恰相反 OS 的内核正式导致 C10M 问题的关键所在。

04 为什么这么说?基于 OS 内核的数据传输有什么弊端?


1、中断处理: 当网络中大量数据包到来时,会产生频繁的硬件中断请求,这些硬件中断可以打断之前较低优先级的软中断或者系统调用的执行过程,如果这种打断频繁的话,将会产生较高的性能开销。

2、内存拷贝: 正常情况下,一个网络数据包从网卡到应用程序需要经过如下的过程:数据从网卡通过 DMA 等方式传到内核开辟的缓冲区,然后从内核空间拷贝到用户态空间,在 Linux 内核协议栈中,这个耗时操作甚至占到了数据包整个处理流程的 57.1%。

3、上下文切换: 频繁到达的硬件中断和软中断都可能随时抢占系统调用的运行,这会产生大量的上下文切换开销。另外,在基于多线程的服务器设计框架中,线程间的调度也会产生频繁的上下文切换开销,同样,锁竞争的耗能也是一个非常严重的问题。

4、局部性失效: 如今主流的处理器都是多个核心的,这意味着一个数据包的处理可能跨多个 CPU 核心,比如一个数据包可能中断在 cpu0,内核态处理在 cpu1,用户态处理在 cpu2,这样跨多个核心,容易造成 CPU 缓存失效,造成局部性失效。如果是 NUMA 架构,更会造成跨 NUMA 访问内存,性能受到很大影响。

5、内存管理: 传统服务器内存页为 4K,为了提高内存的访问速度,避免 cache miss,可以增加 cache 中映射表的条目,但这又会影响 CPU 的检索效率。

综合以上问题,可以看出内核本身就是一个非常大的瓶颈所在。那很明显解决方案就是想办法绕过内核。

05 解决方案探讨


针对以上弊端,分别提出以下技术点进行探讨。

1、控制层和数据层分离: 将数据包处理、内存管理、处理器调度等任务转移到用户空间去完成,而内核仅仅负责部分控制指令的处理。这样就不存在上述所说的系统中断、上下文切换、系统调用、系统调度等等问题。

2、多核技术: 使用多核编程技术代替多线程技术,并设置 CPU 的亲和性,将线程和 CPU 核进行一比一绑定,减少彼此之间调度切换。

3、NUMA 亲和性: 针对 NUMA 系统,尽量使 CPU 核使用所在 NUMA 节点的内存,避免跨内存访问。

4、大页内存: 使用大页内存代替普通的内存,减少 cache-miss。

5、无锁技术: 采用无锁技术解决资源竞争问题。

经研究,目前业内已经出现了很多优秀的集成了上述技术方案的高性能网络数据处理框架,如 6wind、Windriver、Netmap、DPDK 等,其中,Intel 的 DPDK 在众多方案脱颖而出,一骑绝尘。

DPDK 为 Intel 处理器架构下用户空间高效的数据包处理提供了库函数和驱动的支持,它不同于 Linux 系统以通用性设计为目的,而是专注于网络应用中数据包的高性能处理。

也就是 DPDK 绕过了 Linux 内核协议栈对数据包的处理过程,在用户空间实现了一套数据平面来进行数据包的收发与处理。在内核看来,DPDK 就是一个普通的用户态进程,它的编译、连接和加载方式和普通程序没有什么两样。

06 DPDK 的突破


相对传统的基于内核的网络数据处理,DPDK 对从内核层到用户层的网络数据流程进行了重大突破,我们先看看传统的数据流程和 DPDK 中的网络流程有什么不同。

传统 Linux 内核网络数据流程:

1
2
硬件中断--->取包分发至内核线程--->软件中断--->内核线程在协议栈中处理包--->处理完毕通知用户层
用户层收包-->网络层--->逻辑层--->业务层

dpdk 网络数据流程:

1
2
硬件中断--->放弃中断流程
用户层通过设备映射取包--->进入用户层协议栈--->逻辑层--->业务层

下面就具体看看 DPDK 做了哪些突破?

6.1 UIO (用户空间的 I/O 技术)的加持。


DPDK 能够绕过内核协议栈,本质上是得益于 UIO 技术,通过 UIO 能够拦截中断,并重设中断回调行为,从而绕过内核协议栈后续的处理流程。

UIO 设备的实现机制其实是对用户空间暴露文件接口,比如当注册一个 UIO 设备 uioX,就会出现文件 /dev/uioX,对该文件的读写就是对设备内存的读写。除此之外,对设备的控制还可以通过 /sys/class/uio 下的各个文件的读写来完成。

6.2 内存池技术


DPDK 在用户空间实现了一套精巧的内存池技术,内核空间和用户空间的内存交互不进行拷贝,只做控制权转移。这样,当收发数据包时,就减少了内存拷贝的开销。

6.3 大页内存管理


DPDK 实现了一组大页内存分配、使用和释放的 API,上层应用可以很方便使用 API 申请使用大页内存,同时也兼容普通的内存申请。

6.4 无锁环形队列


DPDK 基于 Linux 内核的无锁环形缓冲 kfifo 实现了自己的一套无锁机制。支持单生产者入列/单消费者出列和多生产者入列/多消费者出列操作,在数据传输的时候,降低性能的同时还能保证数据的同步。

6.5 poll-mode 网卡驱动


DPDK 网卡驱动完全抛弃中断模式,基于轮询方式收包,避免了中断开销。

6.6 NUMA


DPDK 内存分配上通过 proc 提供的内存信息,使 CPU 核心尽量使用靠近其所在节点的内存,避免了跨 NUMA 节点远程访问内存的性能问题。

6.7 CPU 亲和性


DPDK 利用 CPU 的亲和性将一个线程或多个线程绑定到一个或多个 CPU 上,这样在线程执行过程中,就不会被随意调度,一方面减少了线程间的频繁切换带来的开销,另一方面避免了 CPU 缓存的局部失效性,增加了 CPU 缓存的命中率。

6.8 多核调度框架


DPDK 基于多核架构,一般会有主从核之分,主核负责完成各个模块的初始化,从核负责具体的业务处理。

除了上述之外,DPDK 还有很多的技术突破,可以用下面这张图来概之。

07 DPDK 的应用


DPDK 作为优秀的用户空间高性能数据包加速套件,现在已经作为一个“胶水”模块被用在多个网络数据处理方案中,用来提高性能。如下是众多的应用。

数据面(虚拟交换机)


OVS

Open vSwitch 是一个多核虚拟交换机平台,支持标准的管理接口和开放可扩展的可编程接口,支持第三方的控制接入。

https://github.com/openvswitch/ovs

VPP

VPP 是 cisco 开源的一个高性能的包处理框架,提供了 交换/路由 功能,在虚拟化环境中,使它可以当做一个虚拟交换机来使用。在一个类 SDN 的处理框架中,它往往充当数据面的角色。经研究表明,VPP 性能要好于 OVS+DPDK 的组合,但它更适用于 NFV,适合做特定功能的网络模块。

https://wiki.fd.io/view/VPP

Lagopus

Lagopus 是另一个多核虚拟交换的实现,功能和 OVS 差不多,支持多种网络协议,如 Ethernet,VLAN,QinQ,MAC-in-MAC,MPLS 和 PBB,以及隧道协议,如 GRE,VxLan 和 GTP。

https://github.com/lagopus/lagopus/blob/master/QUICKSTART.md

Snabb

Snabb 是一个简单且快速的数据包处理工具箱。

https://github.com/SnabbCo/snabbswitch/blob/master/README.md

数据面(虚拟路由器)


OPENCONTRAIL

一个集成了 SDN 控制器的虚拟路由器,现在多用在 OpenStack 中,结合 Neutron 为 OpenStack 提供一站式的网络支持。

http://www.opencontrail.org/

CloudRouter

一个分布式的路由器。

https://cloudrouter.org/

用户空间协议栈


mTCP

mTCP 是一个针对多核系统的高可扩展性的用户空间 TCP/IP 协议栈。

https://github.com/eunyoung14/mtcp/blob/master/README

IwIP

IwIP 针对 RAM 平台的精简版的 TCP/IP 协议栈实现。

http://git.savannah.gnu.org/cgit/lwip.git/tree/README

Seastar

Seastar 是一个开源的,基于 C++ 11/14 feature,支持高并发和低延迟的异步编程高性能库。

http://www.seastar-project.org/

f-stack

腾讯开源的用户空间协议栈,移植于 FreeBSD协议栈,粘合了 POSIX API,上层应用(协程框架,Nginx,Redis),纯 C 编写,易上手。

https://github.com/f-stack/f-stack

存储加速


SPDK

SPDK 是 DPDK 的孪生兄弟,专注存储性能加速,目前的火热程度丝毫不亚于 DPDK,Intel 近来对 SPDK 特别重视,隔三差五就发布新版本。

https://github.com/spdk/spdk

08 总结


DPDK 绕过了 Linux 内核协议栈,加速数据的处理,用户可以在用户空间定制协议栈,满足自己的应用需求,目前出现了很多基于 DPDK 的高性能网络框架,OVS 和 VPP 是常用的数据面框架,mTCP 和 f-stack 是常用的用户态协议栈,SPDK 是存储性能加速器,很多大公司都在使用 DPDK 来优化网络性能。

PS:本文所有的图来自网络,侵权必删。

09 DPDK 资料推荐


在我看来,DPDK 最好的学习资料是官网,没有之一:

http://core.dpdk.org/doc/

其次是看 Intel 技术专家出的书 《深入浅出 DPDK》。

本书详细介绍了DPDK 技术发展趋势,数据包处理,硬件加速技术,包处理和虚拟化 ,以及 DPDK 技术在 SDN,NFV ,网络存储等领域的实际应用。

本书是国内第一本全面的阐述网络数据面的核心技术的书籍,面向 IT 网络通讯行业的从业人员,以及大专院校的学生,用通俗易懂的文字打开了一扇通向新一代网络处理架构的大门。

本书我有电子版(但只有一部分,推荐大家买书),需要的公众号后台回复 “DPDK” 查看获取方式。

除了书之外,就是看大牛的博客,加入相关的群和优秀的人一起学习,我整理了几份网上较好的博客资料,和书一起附赠,如果想加群学习,回复 “加群”。

PS:文章未经我允许,不得转载,否则后果自负。

–END–

欢迎扫👇的二维码关注我的微信公众号,后台回复「m」,可以获取往期所有技术博文推送,更多资料回复下列关键字获取。

文章首发于我的公众号「Linux云计算网络」,欢迎关注,第一时间掌握技术干货!

当容器逐步向容器集群,容器云技术演进的时候,一个不得不面对的问题就是各个容器的管理问题,有些容器需要交互,有些容器需要隔离,如何保证这些操作能够顺利地进行,这个时候,很多容器管理和编排的平台就应运而生了。首先,当然是 Docker 社区自己开发的 Swarm+Machine+Compose 的集群管理套件,然后还有 Twitter 主推 Apache 的 Mesos,最有名的应该为 Google 开源的 Kubernetes。

这些平台综合了容器集群资源管理,服务发现和扩容缩融等问题,是一个集大成的解决方案,但其实这些问题本质上都离不开网络,资源在各容器之间调度需要网络,服务发现需要网络,所以,可以说网络是容器集群环境下最基础的一环。

Docker 容器网络根据容器的部署位置,可以分为单主机网络(host)和多主机网络(multi-host),本文先看 Docker host 网络。

Docker host 网络分为 none,host,joined container 和 bridge 网络。

none 网络模式下,Docker 容器拥有自己的 network namespace,但是并不为容器进行任何的网络配置,也就是说容器除了 network namespace 本身自带的 localback 网卡外什么都没有,包括网卡、IP、路由等信息。用户如何要使用 none 网络,就需要自己添加特定的网卡,并配置 IP、路由等信息,但一般不会这么干,none 网络很好地做到了隔离,一般是用来跑那些对安全性要求极高且不需要联网的应用。

比如某个容器的唯一用途是生成随机密码,就可以放到 none 网络中避免密码被窃取。

想要使 Docker 使用 none 网络,只需要在创建容器的时候附带 –network = none 即可。

host 网络,顾名思义就是 Docker 容器使用宿主机的网络,相当于和 host 共用了同一个 network namespace,Docker 容器使用 host 的网卡、IP 和路由等功能对外通信。

虽然这种模式下 Docker 没有创建独立的 network namespace,但其他 namespace 仍然是隔离的,如文件系统、进程列表等。host 网络最大的好处就是使得 Docker 容器对外通信变得简单,直接使用 host 的 IP 进行通信即可,但缺点也很明显,就是降低了隔离性,同时还会存在和其他容器对网络资源的竞争与冲突的问题。

同样要使用 host 网络,只需创建容器时附带 –network = host 即可。

joined container 网络和 host 网络不同的是,它是和其他的 container 共享一个 network namespace,一个 network namespace 可以被一个或者多个 Docker 容器共享。在这种模式下,两个容器之间可以通过 localback 回环网卡通信,增加了容器间通信的便利性。

同样可以在创建容器时,使用参数 –network = container:another_container_name 来和另外容器共享网络。

bridge 网络是最常用的网络模式,它兼顾了安全性和功能的完备性,但其与外部通信要通过 NAT 转换,在复杂的网络场景下会存在诸多不便。

bridge 网络在创建的时候通过 –network = bridge 指定,Docker daemon 会为创建的容器自动创建一个 Docker 网桥——docker0(也可以人为指定名称 –driver bridge my_net),这个 docker0 就用来联结 Docker 容器和 host 的桥梁。

然后,Docker daemon 会创建一对虚拟网卡 veth pair,一块网卡留在宿主机的 root network namespace 中,并绑定到 docker0 上,另一块放在新创建的 network namespace 中,命名为 eth0,并为其配置 IP 和路由,将其网关设为 docker0,如下,这样整个容器的 bridge 网络通信环境就建立起来了,其他容器的建立方式也是如此,最终各容器之间就通过 docker0 这个桥梁互联互通了。

下文将讨论更为复杂的 multi-host 网络。

PS:文章未经我允许,不得转载,否则后果自负。

–END–

欢迎扫👇的二维码关注我的微信公众号,后台回复「m」,可以获取往期所有技术博文推送,更多资料回复下列关键字获取。