沙盒化容器:是容器还是虚拟机
随着 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 功能、特权权限),都可能导致容器逃逸。 而虚拟机依靠硬件级的虚拟化,实现的硬件隔离比命名空间隔离提供了更强大的安全边界。与容器相比,虚拟机提供了更高程度的隔离,只因其有自己的内核。 由此可见,容器并不是真正的“沙盒”,也并不是轻量化的虚拟机。有没有可能为容器增加一个更安全的边界,尽可能的与主机操作系统隔离,做到类似虚拟机的强隔离,使其成为真正的“沙盒”?