gvisor的网络栈实现

2018年9月29日 0 条评论 1.6k 次阅读 0 人点赞

gvisor简介

gvisor是google新推出一款沙箱运行时,他可以和docker和k8s无缝连接。 gVisor能够在保证轻量化优势的同时,提供与虚拟机类似的隔离效果。gVisor的核心为一套运行非特权普通进程的内核, 且支持大多数Linux系统调用。该内核使用Go编写,这主要是考虑到Go语言拥有良好的内存管理机制与类型安全性。 与在虚拟机当中一样,gVisor沙箱中运行的应用程序也将获得自己的内核与一组虚拟设备——这一点与主机及其它沙箱方案有所区别。

当然gvisor实现的不仅仅是一个完整的网络栈,还实现了文件系统等,但这里我只对网络栈感兴趣,所以也只讲网络栈的实现

netstack

gvisor的网络实现在readme里有介绍,是另一个google项目,netstack, 详细介绍期源码前我们先复习一下网络栈的一些知识。

理论和现实

网络信息的传输其实很复杂,一个信息传到另一个地方,需要各种过五关斩六将。但庆幸的是,网络硬件已经帮我们做了大部分的事,我们只要考虑软件的事。

理论七层模型

+------------------------------+
|           应用层              | Application
+------------------------------+
|           表示层              | Presentation
+------------------------------+
|           会话层              | Session
+------------------------------+
|           传输层              | Transport
+------------------------------+
|           网络层              | Network
+------------------------------+
|           链路层              | Link
+------------------------------+
|           物理层              | Physical
+------------------------------+

现实五层模型(tcpip网络分层)

+------------------------------+
|           应用层              | Application
+------------------------------+
|           传输层              | Transport
+------------------------------+
|           网络层              | Network
+------------------------------+
|           链路层              | Link
+------------------------------+
|           物理层              | Physical
+------------------------------+

现实中大部分的实现都是按tcpip网络分层来实现的,netstack也不例外,可以说现在的网络是tcpip的天下,据说史前公网上还是有其他协议的, 反正数据包不是用ip报文来传输的,但后来都被淘汰了,作为一个90后,我也只是听说,从来没见过除了ip之外的其他协议,即使有,现在也不必深究。 netstack其实只实现了链路层、网络层、传输层这三层。

干嘛要分层?

不就是发送数据包和接收数据包吗?干嘛搞得好像很复杂,分这么多层,分这么多层当然是有原因的,主要的目的是为了灵活性和方便实现。 每层只要专注自己的事情,而不是关心其他层,这样方便软件或者硬件的实现,定义好每个层之间的接口,更改一层的内部实现,不会影响其他层,这样更灵活。 这种思想到处可见,我们要解决一个复杂的问题时,一般都是拆分层小问题,然后分别解决小问题,分层也是一样,它的本质就是为了分离关注点 而让问题简单化或者更高效。现实中也有很多这样的模型,比如,过年了,大家买火车票回家(ps:土豪可以买机票)的流程:

+------------------------------+          +------------------------------+
|        到有美眉的窗口买票       |          |          出火车站回家          |
+------------------------------+          +------------------------------+
|           托运行李            |          |             认领行李           |
+------------------------------+          +------------------------------+
|           登上火车            |          |              离开火车          |
+------------------------------+          +------------------------------+
|           火车出站            |          |              火车进站          |
+------------------------------+          +------------------------------+
|           火车按道路行驶       |          |            火车按线路行驶       |
+------------------------------+          +------------------------------+

是不是很像数据的发送和接收,而且看起来也是分层的。如果没有分层会怎么样呢?比如只有一层,窗口售卖,行李托运办理,登火车检票,开火车, 全部让一个人来做,那不得累死啊,而且没有分层,意味着可以打乱顺序,有人上火车前买票,有人上火车后买票,更有人下火车的时候买票,不方便管理。 采用分层的思想,就让一些人专门负责那一层,不用管其他层了,做好自己的分内事就OK,售票的美眉就不要去开火车了,专心做好售票即可。

每层的功能

分层的第一件事要做的就是,确定每层改干啥。

应用层

应用层是利用传输层的接口来实现用户自定义的网络应用,例如HTTP应用,SMTP(邮件传输)应用等。

传输层

传输层最主要的目的就是给两个应用程序传输数据,注意是两个程序,不是两个主机。主要的协议有tcp和udp,tcp为应用提供了虚拟连接的服务, 也提供了数据的可靠性。udp提供的是无连接服务,也不提供可靠服务,仅仅实现让两个程序之间交换数据。

网络层

网络层负责将数据报从一台主机发送到一台目标主机上(注意:这两个主机可以不相邻),并给每个主机分配一个地址。最著名的就是IP协议了,每个主机都至少有一个IP地址, 根据路由策略将收到数据报发往下一个主机。

链路层

链路层也是将数据包发送到另一台主机,但是这两台主机一定是相邻的(不考虑广域网二层打通的情况),链路层负责将网络层交下来的IP数据报组装程帧, 在两个相邻节点间的链路上传送帧。

物理层

在物理层上所传送的数据单位是比特。 物理层的作用是实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异。 使其上面的数据链路层不必考虑网络的具体传输介质是什么。“透明传送比特流”表示经实际电路传送后的比特流没有发生变化,对传送的比特流来说,这个电路好像是看不见的。

最后附上一张网上的高清协议栈图

管理员

这个人太懒什么东西都没留下