谷歌新作gVisor:VM容器融合技术已经到来

谷歌新作gVisor:VM容器融合技术已经到来

作者|秦承刚,吴启翾,喻望,杨伟

编辑|张婵

出处丨高效开发运维

5 月 2 日,谷歌发布了一款新型的沙箱容器运行时 gVisor,号称能够为容器提供更安全的隔离,同时比 VM 更轻量。容器基于共享内核,安全性是大家关注的一大要点,gVisor 的发布势必将引来更多对容器隔离性的关注。那么 gVisor 在技术上如何实现隔离,其性能如何?隔壁阿里巴巴已经有人为你探索了 gVisor 的架构和组件,并作了性能分析。

本文首发于 InfoQ 垂直公众号高效开发运维,对运维、云计算领域感兴趣的同学可以搜索关注!

背景介绍

gVisor 的开源为安全容器的实现提供了一种新思路。所谓安全容器需要包含两个要点:安全隔离与 OCI 兼容。如今,共用内核的容器在安全隔离上还是比较弱。虽然内核在不断地增强自身的安全特性,但由于内核自身代码极端复杂,CVE 漏洞层出不穷。2018 年至今,已经公开了 63 个与内核相关的安全漏洞,而 2017 年全年则是 453 个 [1]。

大家已经有了一个共识:要有良好的安全隔离,就要阻断容器内程序对物理机内核的依赖。Hyper,Clear Container 以及二者合二为一的 KATA[2],就遵循了这个思路。KATA 容器本质上是个虚拟机,但兼容了 OCI 标准。每个容器都有一个自己的 Guest Kernel。KATA 通过对 Qemu 与 Guest Kernel 的深度优化,减弱了 VM 在启动速度与运行效率上的劣势。

gVisor 也隔离了容器内的恶意代码对 Host Kernel 的访问,但使用了另一种方法。我们将这种方法称之为进程虚拟化。它在内核之外实现了一个“内核进程”,Sentry,它提供了大部分 Linux Kernel 的系统调用。并且通过巧妙的方式将容器内进程的系统调用转化为对这个“内核进程”的访问。Google 将 gVisor 定位为“Sandbox”,而不是安全容器,一个原因是 Sentry 还不能完全代替 Linux Kernel,部分系统调用还是要转接到 Host Kernel 上。

Google 当前开源的 gVisor 版本更像是一个 Demo 版,在一些典型的应用场景下,性能比不上 KATA。但是我们把它的名字拆解来看:gVisor = Google’s new HyperVisor? 猜测 Google 还会有后招。

本文简单分析了 gVisor 的技术实现。时间仓促,文中叙述难免有不妥甚至错误之处,欢迎大家拍砖。

架构分析

整体架构

gVisor 由 3 个组件构成:Runsc,Sentry 与 Gofer。类似 RunC 与 RunV,Runsc 是一种 Runtime 引擎,负责容器的创建与销毁。Sentry 就是上文提到的那个“内核进程”,容器内程序的系统调用都由它进行处理。Gofer 是文件系统的操作代理,IO 请求都会由它转接到 Host 上。这 3 个组件均由 Go 语言实现。这有利有弊:Go 语言开发较简单,并且类型安全,但是却限制了 gVisor 的性能。各组件间的关系如图 1 所示。

谷歌新作gVisor:VM容器融合技术已经到来

图 1: gVisor 的架构

Runsc 的概念较容易理解,我们不再多说。基于 Runsc,可以通过这种方式启动一个 gVisor 容器:

$ docker run --runtime=Runsc hello-gVisor

Sentry

Sentry 是 gVisor 的核心组件,它就像一个简单的操作系统内核,提供了系统调用,进程管理,内存管理等功能。

系统调用

gVisor 设计上的一个巧妙之处是它对系统调用的劫持方法。目前提供了两种劫持模式:KVM 模式,与 ptrace 模式。ptrace 模式的性能不及 KVM 模式。因为应用的每个 SYSCALL 都需要通过 ptrace 访问 Sentry。严格来说,它的安全性也不及 KVM 模式。严重怀疑 ptrace 模式是 Google 最初的 demo,本文不做过多分析。

在 KVM 模式下,gVisor 能够截获应用程序的每个系统调用,并将其转交给 Sentry 进行处理。相比较 VM,我们看不到 Qemu 的身影,也看不到 Guest Kernel,Sentry 包揽了所有必要的操作。这种对虚拟化的实现方法,我们称之为“进程级虚拟化”。

既然基于 KVM,Sentry 就有多种身份。有时它运行在 Guest 态的 Ring0, 此时它就像容器内应用的 Kernel。有时运行在 Host 态的 Ring 3,此时它就像 Host 上的一个普通进程。Sentry 处在什么状态上,完全取决于它当前正在处理的工作。当它在处理容器内的系统调用时,就处于 Guest 态。而当它需要跟 Host Kernel 进行交互时,就会通过 HLT 指令陷回 Host 模式。

Sentry 目前约实现了 200 个左右的系统调用,而 Linux Kernel 则为 X86_64 提供了 318 个系统调用 (4.16 内核)。当应用调用了那些未被实现的系统调用时,Sentry 会直接报错返回。由于系统调用尚未完备,导致部分软件还不能无缝地运行在 gVisor 中。而且 gVisor 已支持的系统调用中,有若干还必须依赖 Host 内核。当处理这些系统调用时,Sentry 会陷回 Host 模式。

Sentry 的进程管理

Sentry 承担了一定的进程管理职责。启动 gVisor 容器后,可以在 Host 上看到两个 Runsc 进程。一个进程负责容器创建与 IO(Gofer),另一个向容器内的应用提供系统调用支持,也就是我们前面提到的“内核进程”。容器内所有的进程,都以 Runsc 进程的线程存在。这有点像 Qemu。Runsc 进程在启动时会创建一定量的 vCPU 线程。

Sentry 复用了 go 语言的 GMP 模型 [3]。每个应用的线程均对应到 go 语言内置的 goroutine(参见 kernle.Task.Start 函数),即 G。go runtime 会根据情况,选择是通过 Host 内核的原生 sys_clone 生成新的 M(工作线程)还是复用之前的。在这里 vCPU 即 P。最后 go runtime 调度器,将 goroutine、vCPU 和工作线程三者结合起来。M、P 线程的调度由 Host 内核来调用。

内存管理

容器内应用的所有代码均由 Runsc 进程进行映射,并代理执行。gVisor 为每个应用进程都维护了一个 Guest 页表, Runsc 进程自身也有一个 Guest 页表。这么做是出于安全性的考虑,隔离了各个进程以及 Runsc 之间的地址空间。避免它们在内存上相互踩踏,也避免了恶意代码对 Runsc 的攻击。但在这种架构下,应用程序每次触发 syscall,都会伴随着一次 Guest 页表的切换。熟悉虚拟化的同学知道,这是一个非常可观的开销。

可以与之鲜明对比的是 Unikernel[4],在典型的 Unikernel 的架构下,所有的进程 / 内核均运行在同一个地址空间中,系统调用等同于一次函数调用。但是应用程序中的任何一个不小心都可能导致整个系统 core 掉。安全与性能永远是个 Tradeoff。

网络

gVisor 里面看到的网络设备是由 docker 创建容器的时候创建的 veth pair,并且在容器内部将虚拟网络设备改名为 eth0。这与普通的容器并没有太大区别。

谷歌新作gVisor:VM容器融合技术已经到来

gVisor 提供两种网络通信的方式:

  1. 通过宿主机 TCP/IP 协议栈

  2. 通过 gVisor 实现的用户态 TCP/IP 协议栈 (netstack)

默认配置是使用 netstack,如果需要更高的网络性能可以通过修改配置文件切换到使用宿主机的 TCP/IP 协议栈。

通过 gVisor 的 netstack 网络通信,gVisor 在捕获到应用的程序的系统调用的时候,并不使用宿主机的系统调用接口而是调用 netstack 提供的 socket 接口, 在经过 netstack 协议栈之后,通过宿主机的 raw socket 的方式进行收发包。

通过宿主机 TCP/IP 协议栈进行网络通信,其整个数据流跟原生容器一样,唯一区别在于 gVisor 需要捕获到安全容器内应用程序关于网络的系统调用。例如, listen/accept/sendmsg 等等。之后再将其转换成 host 的系统调用来进行网络通信。

文件系统

谷歌新作gVisor:VM容器融合技术已经到来

gVisor 也跟 linux 一样对文件系统做了一层抽象,提供了 VFS 层,在其之下分别实现具体的文件系统。有 9p,tmpfs,procfs,sysfs 等。

gVisor 兼容 OCI,因此它的 rootfs 的文件来源就来自容器 OCI 镜像各层聚合以后的 rootfs。为了减少 Guest App 直接对 Host 系统调用的依赖,Sentry 使用了 9pfs。应用程序通过 9p 协议与 Runsc 进程通信(内部运行着 Gofer Server 的功能),通过 Runsc 间接地来对 Host 的 rootfs 进行操作。

gVisor 本身并未提供 Library,容器中的应用可以直接链接镜像 rootfs 中的 Library。所有的 binary 无需重新编译链接,确保了 gVisor 对已有程序的兼容性。

除此之外,Sentry 还开发了内部的 tmpfs,这主要是为了保证运行性能。如果应用程序的临时文件也要经过 9pfs,性能上将无法忍受。Sentry 还模拟 Linux,开发了 /proc 与 /sys 文件系统中的部分文件,做到与 Linux 的兼容性。

性能测试

数据对比

我们利用 memcached 与 mysql 对比了 gVisor 与普通容器, RunV (类似 KATA),与 AliUK(阿里内部自研的下一代执行单元)。

1. memcached: memcached 的主要开销在网络上。gVisor 在 memcached 的 性能的差距是由于它自身的协议栈未被优化过。

gVisor(ptrace)

gVisor(kvm)

runc

runv

aliuk

memcached

11.8M/s

13.5M/s

66.5M/s

57.8M/s

82.7M/s

如上为几种模型对 memcached 的 net_rate 指标,数值越大性能越好,发现 gVisor(ptrace) 确实小于 gVisor(kvm), 并且明显低于 runc/runv/aliuk;aliuk 的性能最佳。

2. mysql:在我们的测试中,mysql 主要开销在 IO 处理。gVisor 的根文件系 . 统通过 9p 协议访问 Host 上的文件。9p 协议性能相比 runc 容器本地 fs 性 能,甚至是 runv 和 aliuk 的 qcow2 的虚拟磁盘性能,都要差很多。

gVisor(kvm)

runc

aliuk

mysql

22773.19ms

1371.44ms

1673.86ms

如上为 gVisor(kvm)、runc、aliuk 使用 sysbench 对 mysql oltp.lua 进行混合测试的平均时延,gVisor 的性能明显也最低。

另外,Sentry 对 Host 内核的依赖,与 Syscall 劫持的低效也是 gVisor 比 AliUK 要差的原因之一。

功能对比

runc容器

RunV

gVisor

AliUK

备注

自包含

NA

完整

较完整

完整

gVisor有部分SYSCALL的实现依赖于Host内核

性能

较高

资源占用

较少

较少

较少

兼容性

NA

较强

gVisor某些内核功能支持不完整,同时/proc /sys接口与Linux差别较大

安全性

较强

gVisor某些非外部资源访问的内核功能对Host内核产生依赖,增大了安全容器与Host内核的攻击面

前景展望

gVisor 是一种对安全容器的解决方案。它在 OCI 兼容、二进制兼容、多进程方面实现得很巧妙,随着 SYSCALL 的完善和软件代码的成熟,会有越来越多的容器能够无缝地迁移到 gVisor 上。

但是 gVisor 的当前版本在性能上还不尽如人意。应用程序每次调用 SYSCALL 都伴有页表切换,而且部分功能还依赖于 Host 内核而陷出到 Host。同时 IO 方面采用了性能不佳的 9pfs,加上网络协议栈方面未进行过优化。这些都导致了它的性能相比较普通容器来说,有较大程度地降低。对性能有较高要求的应用无法应用在 gVisor 上面。

参考文献:

[1]https://www.cvedetails.com/product/47/Linux-Linux-Kernel.html?vendor_id=33

[2] https://github.com/kata-containers

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/538481.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安卓androidstudio访问本地接口_安卓开发之数据存储在本地的四种方式

​安卓开发之数据存储在本地的四种方式本地数据存储,在安卓开发过程中是不可避免的一个话题。这些本地的数据可能是用户的设置,程序的设置,用户的数据图片, 也可能是网络传输的一些缓冲数据。基本上我们有4种方法可以存储安卓程序的数据。第1…

java vector 线程安全_关于Vector到底是不是 线程安全的 问题

线程安全,在java的多并发编程中是重要概念,意思是,多个线程同时操作一个对象,在各种不同情况下,都不会造成不同的后果。一个经典问题,Vector到底是不是线程安全的?很多人都会回答,是…

C# Winform使用Windows Media Player播放多媒体整理

一、简单使用示例步骤 1.添加Windows Media Player 组件当前是系统的 Com组件 工具箱》右键“选择项”》选择Com组件 2.控件拖拽到桌面,使用 private void button1_Click(object sender, EventArgs e) {//播放开始声音axWindowsMediaPlayer2.URL "start.mp3&q…

618选购手机正当时,好评率高达99%的手机了解一下!

一年一度的京东618年中购物狂欢节如火如荼的进行中,手机厂商们都使出了浑身解数,对消费者进行争夺。对于用户来说,618绝对是更换手机的好时机。不过,小伙伴们面对市场上的众多机型,也有可能挑花了眼,不知道…

IntelliJ IDEA 2017.2 x64 安装Scala

从官网下载好IntelliJ IDEA 和scala IntelliJ IDEA 安装scala插件 新建scala项目 建好后,发现src右键--新建---没有 .scala选项 解决方法

Django-ORM数据库操作

背景 Django框架功能齐全自带数据库操作功能,由于工作中设计巨量的api接口,需要一个很好的web后端服务框架,Django给了莫大的帮助。本文主要介绍Django的ORM框架我们一般对数据库的使用的认识是: 创建数据库,设计表结构…

Kingback小组冲刺博客

一、6月13日 1、今日完成的任务 李可欣 项目首页的框架设计 项目首页的导航栏部分 对于项目的配色进行了改进,并且设计了logo 杨帆 今天进行了数据库的设计,完成了数据库的增删改查,并建立了两个jsp页面,还学习了一些数据库设计的…

使用Git上传本地项目到oschina

原文地址:https://my.oschina.net/158/blog/530112 --------------------------------------------- 1.首先看一下自己是否有公钥, 在 我的资料-->SSH公钥 查看,如果没有,添加自己的SSH 公钥: SSH key 可以让你在…

整数数组按绝对值排序

2019独角兽企业重金招聘Python工程师标准>>> 题目: 给出一组整数数组,要求按照绝对值从小到大进行排序后输出。 可以用经典的冒泡排序法来计算此问题,计算过程: 1、比较相邻两个元素绝对值,如果第一个比第二…

pearson相关系数_pearson相关系数与典型相关性分析(CCA)

本文主要介绍相关系数的概念,以及简单相关系数中的pearson相关系数及其局限性。随后介绍pearson相关系数无法解决的问题(两个变量组之间的相关性问题)的解决方案。1、pearson相关系数在日常中,我们经常会遇到一些关于相关性的分析,例如&#…

seo自动工具_爱站SEO工具包详细介绍

爱站SEO工具-seoer的瑞士军刀!这个工具主要是为了方便SEOer查询一些网站的问题,监控关键词排名收录等等,新手老手都可以用的工具,更快的让SEOer上手。相信有很多SEOer都使用过爱站SEO工具包,也有很多新入行的小伙伴可能…

人物三(依芙蒂法)

转载于:https://www.cnblogs.com/song1900/p/9189921.html

XML文件结构和基本语法

XML文件的结构性内容,包括节点关系以及属性内容等等。元素是组成XML的最基本的单位,它由开始标记,属性和结束标记组成。就是一个元素的例子,每个元素必须有一个元素名,元素可以若干个属性以及属性值。 xml文件和html文…

fatal: Could not read from remote repository.的解决办法

原文地址:http://blog.csdn.net/huahua78/article/details/52330792 --------------------------------------------------------------------------------- 查看远端地址 git remote –v 查看配置 git config --list git status git add . // 暂存所有的更改git…

springmvc是什么_SpringBoot与SpringMVC的区别是什么?

简单的来说:SpringMVC和SpringBoot都是Spring家族的重要成员。Spring家族的使命就是为了简化而生。SpringMVC简化我们日常Web开发的,后来随着自身的发展,SpringMVC变得臃肿复杂,而SpringBoot则进一步简化了SpringMVC开发。SpringM…

git 上传代码到码云

与码云建立连接教程:http://blog.csdn.net/zengmingen/article/details/76045076 如果完成了上面步骤的,且有了git。上传项目步骤: 代码提交 代码提交一般有五个步骤: 1.查看目前代码的修改状态 2.查看代码修改内容 3.暂存需要提交…

visual studio过期登录不了账户_具有最高管理权限账户,Windows 7设置Administrator密码永不过期...

今天介绍操作系统具有最高管理权限的账户,Windows 7如何设置Administrator账户密码永不过期。小伙伴们可能不知道,和Windows Vista操作系统一样,在Windows 7操作系统中是不能预先使用Administrator这个具有最高管理权限的账户的。同时也可能不…

cad隐藏图层命令快捷键_cad快捷键f是什么命令?cad中f快捷键都有哪些?

1. F1 该功能键打开AutoCAD帮助窗口。如果用户遇到此软件中的任何功能问题,它可以使用户在线获得帮助。如果用户离线工作,而不是按此键,则该软件的所有功能都将以PDF格式打开。 2. F2 该键将打开一个弹出屏幕,在底部显示命令行。该命令对于在屏幕底部看不到命令窗口的用户很…

java 高级编程进阶_JAVA高级编程之hibernate进阶学习

二级缓存hibernate的session缓存在事务级别进行持久化数据的缓存操作。 当然,也有可能分别为每个类(或集合),配置集群、或 JVM 级别(SessionFactory 级别)的缓存。你甚至可以为之插入一个集群的缓存。注意,缓存永远不知道其他应用程序对持久化…

SpringMvc+Tomcat+Angular4 部署运行

这次的团队开发是,前端开发人员和后台开发人员完全分开开发的。 前端开发采用了Angular4,webstorm 后端开发采用了:springspringmvcmybatis,eclipse --------------------------------------- 最后要整合了。 1、angular项目编…