什么是runwasi

查理谈科技 2024-05-08 00:27:25

WebAssembly 正在为下一波云计算提供动力,不过这得感谢 runwasi,有了runwasis, 才使得WebAssembly超越单纯的浏览器插件, 走到 Kubernetes为主导的云原生时代!

那么什么是runwasi呢? 简单来说,runwasi 是官方 CNCF containerd 项目的一部分,致力于将 Wasm 运行时与 containerd 集成。

在这里将揭开了 runwasi 的神秘面纱,并解释了它如何将 WebAssembly 引入到 Kubernetes。

Kubernetes 不仅仅是容器

首先大家都明白,Kubernetes 主要工作是编排容器。 但是,实际的情况可能超乎多数人的预料……Kubernetes 不关心容器的细节,甚至不知道如何启动和停止它们。 Kubernetes之所以能做容器的编排工作,主要依赖于一种称为容器运行时(container runtime)的技术来完成所有容器工作。

这就提出了一个问题——如果 Kubernetes 不关心容器并且需要容器运行时来将容器部署到 Kubernetes……我们可以借助Wasm 运行时,把 WebAssembly 部署到 Kubernetes 吗?

答案是肯定的。

containerd 入门

现代 Kubernetes 集群上最流行的容器运行时(runtime)是 containerd(发音为“container dee”)。 尽管 Containerd 是低级管道技术,但对于 Kubernetes 来说却是一件大事!

containerd 可作为 Linux 和 Windows 的守护进程使用。 它管理其主机系统的完整容器生命周期,从图像传输和存储到容器执行和监督,再到低级存储到网络附件等等。

containerd 就是我们说的高级运行时。 这意味着它坐在舒适的办公室里发号施令,而低级运行时则完成实际工作。

举个简单的例子,containerd 默认使用 runc 作为其低级运行时。 在当前设计下,containerd 提取镜像(image),但 runc 创建并启动容器(container instance)。

containerd架构如下所示。 请注意单个 containerd 实例如何为多个容器发号施令,而每个容器都有自己的 runc 和 shim 进程。

可能有些人对于Kubernetes的底层机制并不是很了解,尤其是shim接口, 这里对于containerd的shim接口多讲解一点。

Containerd Shim 介绍

shim的中文意思是“垫片”, 维基百科中是这样介绍shim的:

垫片是一种薄且通常呈锥形或楔形的材料,用于填充物体之间的小间隙或空间。 垫片通常用于支撑、调整以获得更好的贴合或提供水平表面。 垫片也可用作垫片,以填充磨损部件之间的间隙。

金属垫片,metal shim

这里有一个可能是违反我们常识的是,我们一般见到的垫片是圆形的, 而在维基百科中的垫片,通常是锥形或者契形,这点很有意思。

话说回来,前面说到,守护进程containerd并不直接启动容器。 相反,它充当协调容器和内容活动的高级管理器或中心,称为“运行时”的较低级程序实际上实现启动、停止和管理容器,无论是单个容器还是容器组, 例如 Kubernetes Pod。

最常用的运行时引擎(runtime engine)是 runc,它实现了 OCI 运行时规范。 由于这是一个运行时引擎,因此它不会被containerd直接调用; 相反,它由填充程序(shim)调用,该填充程序侦听套接字并调用运行时引擎,这就是containerd的shim+引擎架构

containerd的shim是这样工作的,每一个 Containerd 或 Docker 容器都有一个相应的 "shim" 守护进程,这个守护进程会提供一个 API,Containerd 使用该 API 来管理容器基本的生命周期(启动/停止),在容器中执行新的进程、调整 TTY 的大小以及与特定平台相关的其他操作。

Kubernetes 和容器

以下工作流程说明了在 Kubernetes 上启动容器时 containerd 和 runc 的角色。

节点上的 kubelet 监视 API 服务器是否有新任务kubelet 被分配任务任务是运行一个容器containerd 拉取所需的容器镜像containerd 指示 runc 创建容器runc 创建所需的命名空间和 cgroup 等。runc 在所需的命名空间中启动容器的主进程runc 退出shim 成为容器的父进程

Shims 可以做很多事情,例如保持容器处于活动状态并向 Containerd 报告退出代码,向 Containerd 报告容器的退出状态,在容器退出状态被 Containerd 收集之前,shim 会一直存在。这一点和僵尸进程很像,僵尸进程在被父进程回收之前会一直存在,只不过僵尸进程不会占用资源,而 shim 会占用资源。

Shims 还抽象了低级运行时的机制。shim 将 Containerd 进程从容器的生命周期中分离出来,具体的做法是 runc 在创建和运行容器之后退出,并将 shim 作为容器的父进程,即使 Containerd 进程挂掉或者重启,也不会对容器造成任何影响。这样做的好处很明显,你可以高枕无忧地升级或者重启 Containerd,不会对运行中的容器产生任何影响。Docker 的 --live-restore特征也实现了类似的功能。

关于containerd的shim api,更详细的可以参阅https://github.com/containerd/containerd/blob/main/runtime/v2/README.md#architecture

这与 v2 containerd shim API 相结合,应该允许我们将低级容器运行时替换为 Wasm 运行时。

好了,关于kubernetes,containerd,shim的介绍就先介绍到这里,现在回到最开始,WebAssembly的runwasi,看看runwasi是如何工作的。

通过 runwasi 将 Wasm 引入 Kubernetes

runwasi 是官方 CNCF containerd 项目的一部分,致力于将 Wasm 运行时与 containerd 集成。

从架构上来说,runwasi 作为一个 Containerd shim运行——位于 Containerd 和 Wasm 运行时之间。 高层架构如下所示,图中containerd以下的所有内容对于Kubernetes来说都是不透明的。

runwasi这种 Containerd shim 方法通过利用 Containerd 的庞大安装基础,提供了一种将 Wasm 工作负载引入 Kubernetes 的简单途径。

“简单”是一个相对术语,因为 runwasi 仍有很多工作要做。 然而已经有了IT巨头已经开始埋头工作…

Azure AKS 正在预览使用 runwasi 的 Wasm 节点池。 这些支持基于 wasmtime 运行时的应用程序框架,例如 Fermyon 的 Spin 和 Deislabs 的 Slight。Docker Desktop 还使用 runwasi 来支持 Wasm 工作负载。

两者对于 runwasi 的开发和采用都具有重要意义

WebAssembly 位于容器中

在容器内运行 Wasm 工作负载可能看起来有悖常理——为什么要采用比容器更小、更快、更便携的东西,并在看起来很像容器(命名空间和 cgroup)的东西中运行它?!

至少一个答案是平台和工具——您无需构建新平台和学习新工具即可获得 Wasm 的一些优点。 如果您在 Kubernetes 和 OCI 注册表等方面投入了大量资金,那么这是一件大事。

无论如何,容器是具有 cgroup 和其他分层安全技术的命名空间的集合。 Wasm 是一个基于堆栈的虚拟机,它实现了一个默认安全的沙盒,将应用程序与内核隔离,并且仅拥有应用程序所需的功能。

所以……在类似容器的结构中运行 Wasm 应用程序可以让您获得 Wasm 沙箱、命名空间和 cgroup 的安全优势。

runwasi的优点和缺点

runwasi 方法有优点也有缺点。

优点包括通往 Kubernetes 的简单路径,可与 Pod、Deployments、RuntimeClasses 等现有 K8s 原语配合使用。它允许 Wasm 驾驭 Kubernetes 浪潮,并使 Kubernetes 能够大胆地去往容器无法到达的地方 – 资源受限的边缘环境...

缺点包括现有平台和工具不是为 Wasm 设计的,可能会限制获得的好处。 此外,Wasm 和组件的开发人员体验远远落后于容器。

0 阅读:0

查理谈科技

简介:感谢大家的关注