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