容器与虚拟化的结合浅谈安全容器技术发展趋势

40次阅读

共计 6190 个字符,预计需要花费 16 分钟才能阅读完成。

【摘要】无论公有云还是私有云厂商,都认识到了将虚拟化的隔离性和容器的高效运维特性相结合,是云原生平台发展的必然趋势。

容器是如何解决隔离问题的

众所周知,容器技术的出现有两个关键原因:

1. 软件运行过程中的资源和环境的隔离。

2. 软件因为运行环境多样带来的打包和配置的复杂性。

而对于软件运行环境的隔离需求,从计算机出现之初就已经开始了,多任务分时操作系统和虚拟地址的引入,都是为了解决多个任务在同一主机上运行,并且让任务本身认为自己独占机器。当然这样的隔离是远远不够的,当今软件,根据不同的层级,可以将隔离技术分为以下三类:

1. 进程级别的隔离

2. 操作系统级别的隔离

3. 虚拟化级别的隔离

操作系统以进程作为程序运行过程的抽象,进程拥有独立的地址空间,进程的执行依靠操作系统的调度。但是进程共享了文件系统,函数库等资源,程序之间出现互相干扰的可能性很大。这个层级的隔离适合在相同主机上运行单个用户的不同程序,由用户自己保证程序之间的资源分配。

上世纪 70 年代出现了 chroot,进行文件系统的隔离,21 世纪初开始,随着计算硬件的性能提升,软件隔离的需求更加强烈,这时候开始出现如 jail,cgroup,namespace 等各种不同资源的隔离技术。我们将这些技术统一划分到操作系统的隔离技术,这类隔离技术可以实现软件在诸如硬件资源、文件系统、网络、进程号等方面的隔离,但是不同的应用依然是运行在相同的操作系统内核上,对于恶意的利用漏洞攻击的场景,这种隔离技术依然会捉襟见肘。但是这种级别的隔离带来的额外资源消耗较小,适合相同的组织内不同用户的应用在相同主机上运行。

虚拟化技术的出现,让相同的物理机上也能运行多个不同的操作系统。操作系统对硬件的接口,由虚拟机管理程序 (VMM) 负责模拟。运行在不同系统中的程序,内核也是隔离的。硬件资源则通过各种硬件辅助手段进行划分,虚拟机上的程序很难突破虚拟化层加上的资源限制。并且因为内核的隔离,资源的可见性也做到了很强的隔离性。即使是恶意的用户,也很难突破这层虚拟化的限制,已达到攻击物理机,或者相同主机上其他虚拟机的目的。

以上三种隔离是按照层级一步一步加强的,同时带来的理论损耗也是逐步递进的。虚拟化由于需要模拟各种设备,带来的资源损耗比其他两种隔离方式要大很多。

什么是“安全容器”

容器概念出来的时候,最初大家做隔离的思路,几乎都是操作系统级的隔离,也就是基于内核提供的 namespace、cgroup、seccomp 等机制,实现容器内的资源、文件、系统调用等限制和隔离。这种隔离方式更加高效,损耗更小。但是随着容器的大规模使用,尤其是各种容器编排系统,如 k8s 的深入使用,人们逐渐发现这样的隔离级别往往不能满足要求。在公有云场景下,相同主机如果需要运行不同租户的应用,因为这种隔离级别依然采用了共内核的机制,存在这广泛的攻击面,容器的隔离级别完全不能满足要求。所以最初的公有云上的容器服务,都是配合虚拟机的使用来完成的,首先是用户需要创建一批虚拟机作为运行容器的节点,形成一个私有的集群,然后才能在其上创建容器应用。虚拟化级别的隔离已经被各种公有云的实践证明,是一种安全的隔离技术。

自从云计算的概念提出开始,虚拟机一直是云平台的基础,无论是平台本身服务还是用户的使用,都是从 IaaS 平台创建通用虚拟机开始的。一般都是创建相应的规格的虚拟机,使用一个完成操作系统镜像启动一个完整的操作系统,随后在其安装,配置,运行软件和服务。包括我们上节提到的公有云容器服务的提供形式也是如此。

虚拟化本身带来的隔离能力是受到普遍认可的,不过 IaaS 层希望提供的是一个和应用完全无关的基础设施层,它几乎完全不感知应用的任何信息。于是从基础设施到应用运维,中间巨大的鸿沟则是由 PaaS 和用户自己来填平,这中间依然需要耗费无数的人力和成本。通用的虚拟机服务诚然有它的好处,比如完整的操作系统很适合程序调试,或者作为工作办公环境等等。但是对于多数运行于云平台的软件,它需要的是它独有的运行环境,它的运行环境由它的镜像已经完全定义好了。如果在此之外,又启动一个完整的操作系统,既浪费资源,也增加了运维的成本。为什么不能直接将虚拟化级别的隔离引入到容器技术中呢?结合虚拟化的安全性和容器在软件生命周期管理方面的优势,是不是可以给软件开发运维带来巨大的便利呢?

也就是在这个时间,docker 和 coreos 等一起成立了 OCI 组织,其目的是将容器的运行时和镜像管理等流程标准化。OCI 标准定义了一套容器运行时的命令行接口和文件规范,docker 将其 RunC 捐给 OCI 作为运行时标准的一个参考实现。2015 年 Hyper.sh 开源了 RunV,则是一种基于虚拟化的容器运行时接口的实现,它很好地结合了虚拟化的安全性和容器的便利性。后来 RunV 和 ClearContainer 合并成立了 kata 项目,kata 提供了更加完整的基于虚拟化的容器实现。我们把这种基于虚拟化的容器实现称作安全容器。

除 kata 之外,还相继出现了多个安全容器的实现方式,比如 google 的 gVisor、AWS 的 firecracker-containerd、IBM 的 Nabla、VMware 的 CRX 等等,其原理不尽相同,但共同反应了一个趋势,就是将容器的便利和虚拟化的安全隔离结合起来,让虚拟化直接和应用运维结合,成为云原生技术的大势所趋。下面对这些“安全容器”的实现技术进行简要的介绍和对比。

Google gVisor

相比于其他几种实现,gVisor 的显著不同之处在于,它通过拦截容器中应用的系统调用,模拟了一个操作系统内核,因此 gVisor 实际上没有虚拟化,而是在用户态实现了一个操作系统。这种方式可以降低因为虚拟化带来的模拟设备内存损耗。gVisor 提供的 runsc 符合 OCI 标准,可以直接对接 docker、containerd 等容器平台,同时它也完全兼容 docker 的镜像格式。但是由于不是一个标准 linux 内核,因为应用的兼容性有较大问题。另外拦截系统调用带来的巨大的性能损耗也是阻止其广泛使用的一个阻碍。

图片来自 https://gvisor.dev/docs/

IBM nabla

nabla 是继承于 unikernel 的隔离方式,应用采用 rumprun 打包成一个 unikernel 镜像,直接运行在一个专为运行 unikernel 定制虚拟机 (ukvm) 中。应用直接打包首先可以降低很多内核态和用户态转换的开销,另外通过 ukvm 暴露非常有限的主机上的 syscall(只剩 7 个),可以大大缩小主机的攻击面。它是这些安全容器实现中,最安全的。不过由于它要求应用打包成 unikernel 镜像,因此和当前 docker 的镜像标准是不兼容的。另外,unikernel 应用在诸如支持创建子进程等一些常规操作上都有很难解决的问题。

图片来自 https://unit42.paloaltonetworks.com/making-containers-more-isolated-an-overview-of-sandboxed-container-technologies/

AWS Firecracker

最初 firecracker 是为 AWS 的 Lambda 打造的高密度轻量级虚拟化组件。由于它是从头开始构建虚拟化,带着轻量化的目的,因此他抛掉了 qemu 这种通用虚拟化组件的大部分功能,只留下运行容器和 Function 必要的一些模拟设备。因此它的内存开销非常小(小于 5M),启动速度非常快(小于 125ms),一秒钟可以在一个节点上运行 150 个轻量级虚拟机。

为了让 firecracker-microvm 更好的运行容器,AWS 启动了 firecracker-containerd 项目,firecracker-containerd 是 containerd-shim-v2 的一个实现,不符合 OCI 标准,但是可以直接对接 containerd 启动容器,也就很容易通过 containerd 对接 k8s 的 CRI 接口。containerd-shim-v2 是 containerd 定义的新的 runtime 接口,它是对最初 shim-v1 的一个简化,可以大大精简 runtime 的组件和内存使用。containerd 是一个全插件化的代码框架,扩展性非常好。firecracker-containerd 在该框架下,实现了一个 snapshotter 作为镜像插件,负责块设备镜像的生成;实现了一个 shim-v2 的 runtime,负责容器的生命周期管理。另外还有个 fc-control-plugin 作为虚拟机的管理插件,提供 grpc 接口供 runtime 调用。在轻量级虚拟机内部,有一个 agent 负责监听 runtime 传进来的 vsock,接收 runtime 的指令进行虚机内部真正的容器生命周期管理操作,它是直接调用 runc 来管理容器的。

图片来自 https://github.com/firecracker-microvm/firecracker-containerd/blob/master/docs/architecture.md

VMware CRX

VMware 发布的 vSphere 7 与 kubernetes 进行了融合,它利用 k8s 的 CRD 将其集群的虚拟机、容器、函数等运行实体管理的所有功能都集成到了 k8s 中。VMware 是一个做虚拟化起家的公司,因此虚拟化作为它的老本行,这块的积累是很深厚的。它将虚拟化融合到它的容器 runtime CRX 中,因此和 firecracker-containerd 和 kata 类似,也是一个基于轻量级虚拟化的容器 runtime 的实现。通过对其虚拟化组件和 guest 内核的精简,CRX 容器同样做到了很低的内存损耗 (20MB)、快速(100ms) 的启动以及高密度部署(单个节点大于 1000 个 pod)。

图片来自 https://cormachogan.com/2019/11/22/project-pacific-vmworld-2019-deep-dive-updates/

vSphere 对 node 上的 kubelet 组件改造比较大,节点上的 Spherelet 部分功能和 kubelet 重合,负责 pod 的生命周期管理(他们称之为 Native Pod),运行在虚拟机中的 SphereletAgent 则集成了符合 OCI 接口规范的 libcontainer,实现容器的生命周期管理,以及容器的监控日志采集、容器的 shell 登录(kubectl exec)。Spherelet 和虚机中的 SphereletAgent 交互实现类似于 kubelet 使用 CRI 接口管理 pod 的效果。

kata containers

相比于以上几种,kata containers 最大的特点是它专注于实现一个开放的符合 OCI 标准的安全容器 runtime 实现,对于对接什么样的虚拟化方案,它抽象了一套 hypervisor 接口,如今已经对接了多种虚拟化实现,比如 qemu、nemu、firecracker、cloud-hypervisor 等等。

图片来自 https://katacontainers.io/

通过 containerd-shim-v2 和 vsock 技术,kata 精简了大量的组件,配合轻量级 hypervisor 和精简内核,kata 可以做到将额外内存消耗降低到 10MB 以下。容器启动时间降低到 100ms 以下。后续还会通过 rust 语言重写等方式,提供更低内存额外消耗。

图片来自 https://github.com/kata-containers/documentation/blob/master/design/architecture.md

现有安全容器技术对比

安全容器技术发展趋势

随着 Serverless 等技术的兴起,应用部署和运维工作已经下沉到云平台上,人们需要一个更加高效的云原生技术平台。从这几年涌现的安全容器实现技术可以观察到,无论公有云还是私有云厂商,都认识到了将虚拟化的隔离性和容器的高效运维特性相结合,是云原生平台发展的必然趋势。结合当前安全容器实现中遇到的一些问题,我们可以预见到,未来这项技术发展的几个走向:

  1. 需要一个为安全容器而生的轻量级 hypervisor,当前 qemu+kvm 是主流的虚拟化技术,但因为 qemu 是为通用的虚拟机而设计的,其体量过于庞大,而 对于安全容器而言,一个模块化可定制的虚拟化实现尤为重要。如果结合 gVisor 和 nabla 的实现来看,内核的可定制性也是安全容器场景的必然要求。rust-vmm 即是这样一种模块化的虚拟化组件库。linux 内核本身的模块化特性可以部分满足容器场景下的内核定制需求,不过也许像 gVisor 那样实现一个专为容器而生的内核也许是未来的趋势。
  2. 容器的启动时间是衡量一个云原生平台效率的重要指标 ,尤其是在 Serverless 场景下,程序运行时间本身可能很短,这时候启动时间可能占用了其绝大部分,那么这种低效就显得尤为明显。 安全容器通过极致的轻量化,可以将容器启动时间降低到 100ms 以下,但是容器镜像拉取时间过长仍是当前容器部署过程中的一个短板。由于当前容器镜像格式和镜像挂载方式等方面的限制,需要在启动容器之前将容器镜像拉取到本地以后,才能启动容器。而容器启动本身需要的数据只占镜像的 6% 左右。因此我们亟需一个高效的镜像挂载方式,当前已经有一些免下载和懒加载(Lazy-Loading)的技术原型,后续需要尽快推出一个可商用的镜像下载加速方案。

3. 当前公有云的网络普遍采用原 IaaS 的网络管理模式,在地址分配,网络配置效率等方面完全赶不上容器快速启停的需求,docker 容器采用的 veth 方式在性能等方面也很难满足高效转发的要求。因此 需要一个专为云原生设计的网络管理方案

4. 我们看到云平台对应用的管理逐步深入,从只管理基础设施的 IaaS 层,发展到管理应用整体部署和运维的 PaaS,再到如今服务网格(Service Mesh)技术将平台管理能力深入到应用内部的微服务级别。同时我们也看到,以 K8s 容器、Istio 服务网格为代表的云原生技术已经和下层的计算 / 网络虚拟化等技术逐步整合到了一起,比如安全容器即是容器与计算虚拟化的结合,而 Istio 服务网格也会与虚拟化网络进行深度整合以提供更高的性能与更精细的 QoS 控制

5. 当前硬件加速技术在 AI 和大数据等领域大行其道,安全容器需要与各种计算加速硬件技术进行结合 使得 AI、大数据、科学计算等批量计算领域的用户可以利用云平台直接投递其海量的计算任务 ,可大大降低他们在底层技术上的心智负担。通过硬件加速也是提升云平台本身效率、降低云平台运行成本的有效手段。比如 华为云擎天架构在硬件加速方面拥有的技术优势在“安全容器”领域已得到充分的证明,CCE Turbo 裸金属容器已经实现了安全容器的部分硬件卸载能力

总结

未来必然是云原生技术大行其道的时代,我们已经看到很多传统行业也逐渐认识到云原生技术可以给传统企业的 IT 软件,工业自动化,线上运维和数据管理等带来明显的效率提升。我们将看到通过对底层硬件和上层服务的全栈整合,打造出一个高效智能的云计算技术平台,而这中间,容器将是串联整个技术栈的关键所在。

点击关注,第一时间了解华为云新鲜技术~

正文完
 0