随着 IT 技术的发展,AI、区块链和大数据等技术提升了对应用毫秒级扩展的需求,开发人员也面临着的功能快速推出的压力。混合云是新常态,数字化转型是保持竞争力的必要条件,虚拟化成为这些挑战的基本技术。

在虚拟化的世界,有两个词耳熟能详:虚拟机和容器。前者是对硬件的虚拟化,后者则更像是操作系统的虚拟化。两者都提供了沙箱的能力:虚拟机通过硬件级抽象提供,而容器则使用公共内核提供进程级的隔离。有很多人将容器看成是“轻量化的虚拟机”,通常情况下我们认为容器是安全的,那到底是不是跟我们想象的一样?

容器:轻量化的虚拟机?

容器是打包、共享和部署应用的现代化方式,帮助企业实现快速、标准、灵活地完成服务交互。容器化是建立在 Linux 的命名空间(namespace)和控制组(cgroup) 的设计之上。

命名空间创建一个几乎隔离的用户空间,并为应用提供专用的系统资源,如文件系统、网络堆栈、进程ID和用户ID。随着用户命名空间的引入,内核版本 3.8 提供了对容器功能的支持:Mount(mnt)、进程 ID(pid)、Network(net)、进程间通信(ipc)、UTS、用户 ID(user)6 个命名空间(如今已达 8 个,后续加入了 cgroup 和 time 命名空间)。

cgroup 则实施对应用的资源限制、优先级、记账和控制。cgroup可以控制 CPU、内存、设备和网络等资源。

同时使用 namespace 和 cgroup 使得我们可以在一台主机上安全地运行多个应用,并且每个应用都位于隔离的环境中。

虚拟机提供更强大的隔离

虽然容器很棒,足够轻量级。但通过上面的描述,同一个主机上的多个容器其实是共享同一个操作系统内核,只是做到了操作系统级的虚拟化。虽然命名空间提供了高度的隔离,但仍然有容器可以访问的资源,这些资源并没有提供命名空间。这些资源是主机上所有容器共有的,比如内核 Keyring、/proc、系统时间、内核模块、硬件。

我们都知道没有 100% 安全的软件,容器化的应用也一样,从应用源码到依赖库到容器 base 镜像,甚至容器引擎本身都可能存在安全漏洞。发生容器逃逸的风险远高于虚拟机,黑客可以利用这些逃逸漏洞,操作容器的外部资源也就是宿主机上的资源。除了漏洞,有时使用的不当也会带来安全风险,比如为容器分配了过高的权限(CAP_SYS_ADMIN 功能、特权权限),都可能导致容器逃逸。

而虚拟机依靠硬件级的虚拟化,实现的硬件隔离比命名空间隔离提供了更强大的安全边界。与容器相比,虚拟机提供了更高程度的隔离,只因其有自己的内核

由此可见,容器并不是真正的“沙盒”,也并不是轻量化的虚拟机。有没有可能为容器增加一个更安全的边界,尽可能的与主机操作系统隔离,做到类似虚拟机的强隔离,使其成为真正的“沙盒”?

沙盒化容器

答案是有,就是沙盒容器。这种容器就像虚拟机一样有自己的内核,这层内核成为用户空间内核。这层内核要保持容器的轻量级,使用现代编程技术编写,本身非常轻,仅用于作为容器和主机之间的强隔离层。

并且还要支持 OCI 和 CRI 规范,可以与 Docker 和 Kubernetes 等容器工具很好的集成。

这里简单介绍下 gVisor 和 Kata Containers。

gVisor

gVisor 是使用 Go 编写的应用内核,实现了 Linux 操作系统的大部分接口。其包含了一个叫做 runsc 的 OCI 运行时,提供了应用和宿主机内核间的隔离层。runsc 也实现了与 Docker 和 Kubernetes 的集成,可以很容易的运行沙盒容器。

gVisor 为每个容器提供了独立的操作系统内核。应用与 gVisor 内核提供的虚拟环境进行交互,不是直接访问宿主机的内核。gVisor 还限制和管理文件和网络操作,确保容器化应用和主机操作系统之间有两个隔离层。通过减少和限制应用与主机内核的交互,尽可能减小攻击者绕过容器隔离机制的攻击面。

与大部分内核不同,gVisor 不需要固定的物理资源;相反,其利用现有的主机内核功能,并作为一个正常进程运行。换句话说,gVisor 以 Linux 的方式实现了 Linux。

gVisor 沙盒由多个进程组成,这些进程共同构成了可以运行一个或多个容器的环境。

每个沙盒都有其独立的实例:

  • Sentry:运行容器的内核,拦截并响应应用的系统调用。

沙盒中的每个容器都有其独立的实例:

  • Gofer:提供容器文件系统的访问。

Kata Containers

Kata Containers 与容器一样轻量级且快,并与容器管理层集成-- 包括 Docker 和 Kubernetes 等流行的容器编排工具 -- 同时还提供了与虚拟机一样的安全。

Kata Containers 与 OCI、容器运行时接口(CRI)和容器网络接口(CNI)完全集成。它支持各种类型的网络模型(例如,passthrough、MacVTap、桥接、tc 镜像)和可配置的访客内核,以便需要特殊网络模型或内核版本的应用都可以在上面运行。上图显示了 Kata VM 中的容器如何与现有编排平台交互。

Kata 在主机上有一个 kata 运行时来启动和配置新容器。对于 Kata VM 中的每个容器,主机上都有一个相应的 Kata Shim。Kata Shim 接收来自客户端(例如 docker 或 kubectl)的 API 请求,并通过 VSock 将请求转发给 Kata VM 内的代理。Kata 容器进一步进行了几项优化,以减少 VM 启动时间。

Kata Containers 由两个开源项目合并而来:Intel 的 Clear containers 和 Hyper runV。前者注重性能(引导时间小于 100ms)和安全;而后者通过支持不同的 CPU 架构和管理系统,将技术无关放在首位。Kata Containers 可以说集二者之大成。

与传统的容器相比,Kata Container 做到了虚拟机的隔离,集虚拟机的安全性和容器的性能于一身。

总结

与普通容器相比,沙盒容器提供了更强的隔离性,这种强隔离提供了更高的安全性。同时这类容器技术支持 OCI 和 CRI 规范,可以与现有的容器工具以及 Kubernetes 很好的集成。

文章统一发布在公众号云原生指北


云原生指北
25 声望7 粉丝