做设计的地图网站网站建设费用申请
news/
2025/9/28 22:11:14/
文章来源:
做设计的地图网站,网站建设费用申请,网站表单功能,重庆公司免费网站建设作者#xff5c;秦承刚#xff0c;吴启翾#xff0c;喻望#xff0c;杨伟
编辑#xff5c;张婵
出处丨高效开发运维
5 月 2 日#xff0c;谷歌发布了一款新型的沙箱容器运行时 gVisor#xff0c;号称能够为容器提供更安全的隔离#xff0c;同时比 VM 更轻量。容器基于共…
作者秦承刚吴启翾喻望杨伟
编辑张婵
出处丨高效开发运维
5 月 2 日谷歌发布了一款新型的沙箱容器运行时 gVisor号称能够为容器提供更安全的隔离同时比 VM 更轻量。容器基于共享内核安全性是大家关注的一大要点gVisor 的发布势必将引来更多对容器隔离性的关注。那么 gVisor 在技术上如何实现隔离其性能如何隔壁阿里巴巴已经有人为你探索了 gVisor 的架构和组件并作了性能分析。
本文首发于 InfoQ 垂直公众号高效开发运维对运维、云计算领域感兴趣的同学可以搜索关注背景介绍
gVisor 的开源为安全容器的实现提供了一种新思路。所谓安全容器需要包含两个要点安全隔离与 OCI 兼容。如今共用内核的容器在安全隔离上还是比较弱。虽然内核在不断地增强自身的安全特性但由于内核自身代码极端复杂CVE 漏洞层出不穷。2018 年至今已经公开了 63 个与内核相关的安全漏洞而 2017 年全年则是 453 个 [1]。
大家已经有了一个共识要有良好的安全隔离就要阻断容器内程序对物理机内核的依赖。HyperClear 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 个组件构成RunscSentry 与 Gofer。类似 RunC 与 RunVRunsc 是一种 Runtime 引擎负责容器的创建与销毁。Sentry 就是上文提到的那个“内核进程”容器内程序的系统调用都由它进行处理。Gofer 是文件系统的操作代理IO 请求都会由它转接到 Host 上。这 3 个组件均由 Go 语言实现。这有利有弊Go 语言开发较简单并且类型安全但是却限制了 gVisor 的性能。各组件间的关系如图 1 所示。图 1: gVisor 的架构
Runsc 的概念较容易理解我们不再多说。基于 Runsc可以通过这种方式启动一个 gVisor 容器
$ docker run --runtimeRunsc hello-gVisor
Sentry
Sentry 是 gVisor 的核心组件它就像一个简单的操作系统内核提供了系统调用进程管理内存管理等功能。
系统调用
gVisor 设计上的一个巧妙之处是它对系统调用的劫持方法。目前提供了两种劫持模式KVM 模式与 ptrace 模式。ptrace 模式的性能不及 KVM 模式。因为应用的每个 SYSCALL 都需要通过 ptrace 访问 Sentry。严格来说它的安全性也不及 KVM 模式。严重怀疑 ptrace 模式是 Google 最初的 demo本文不做过多分析。
在 KVM 模式下gVisor 能够截获应用程序的每个系统调用并将其转交给 Sentry 进行处理。相比较 VM我们看不到 Qemu 的身影也看不到 Guest KernelSentry 包揽了所有必要的操作。这种对虚拟化的实现方法我们称之为“进程级虚拟化”。
既然基于 KVMSentry 就有多种身份。有时它运行在 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 进程。一个进程负责容器创建与 IOGofer另一个向容器内的应用提供系统调用支持也就是我们前面提到的“内核进程”。容器内所有的进程都以 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 提供两种网络通信的方式
通过宿主机 TCP/IP 协议栈通过 gVisor 实现的用户态 TCP/IP 协议栈 (netstack)
默认配置是使用 netstack如果需要更高的网络性能可以通过修改配置文件切换到使用宿主机的 TCP/IP 协议栈。
通过 gVisor 的 netstack 网络通信gVisor 在捕获到应用的程序的系统调用的时候并不使用宿主机的系统调用接口而是调用 netstack 提供的 socket 接口, 在经过 netstack 协议栈之后通过宿主机的 raw socket 的方式进行收发包。
通过宿主机 TCP/IP 协议栈进行网络通信其整个数据流跟原生容器一样唯一区别在于 gVisor 需要捕获到安全容器内应用程序关于网络的系统调用。例如, listen/accept/sendmsg 等等。之后再将其转换成 host 的系统调用来进行网络通信。
文件系统 gVisor 也跟 linux 一样对文件系统做了一层抽象提供了 VFS 层在其之下分别实现具体的文件系统。有 9ptmpfsprocfssysfs 等。
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)runcrunvaliukmemcached11.8M/s13.5M/s66.5M/s57.8M/s82.7M/s
如上为几种模型对 memcached 的 net_rate 指标数值越大性能越好发现 gVisor(ptrace) 确实小于 gVisor(kvm), 并且明显低于 runc/runv/aliukaliuk 的性能最佳。
2. mysql在我们的测试中mysql 主要开销在 IO 处理。gVisor 的根文件系 . 统通过 9p 协议访问 Host 上的文件。9p 协议性能相比 runc 容器本地 fs 性 能甚至是 runv 和 aliuk 的 qcow2 的虚拟磁盘性能都要差很多。
gVisor(kvm)runcaliukmysql22773.19ms1371.44ms1673.86ms
如上为 gVisor(kvm)、runc、aliuk 使用 sysbench 对 mysql oltp.lua 进行混合测试的平均时延gVisor 的性能明显也最低。
另外Sentry 对 Host 内核的依赖与 Syscall 劫持的低效也是 gVisor 比 AliUK 要差的原因之一。
功能对比
runc容器RunVgVisorAliUK备注自包含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_id33
[2] https://github.com/kata-containers
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/921187.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!