云原生的下一步,或从WebAssembly在边缘取代Docker开始
作者 蔡芳芳
过去几年,云计算的边界不断向边缘侧延伸。作为云原生技术事实标准的Kubernetes+容器组合,自然也被很多人考虑部署到边缘侧,以提高边缘应用部署的效率和便利性,降低边缘应用与硬件之间的耦合度。不过Kubernetes+容器组合并非万用良药,对于边缘计算场景来说,它们还是太重了。
边缘设备通常硬件资源有限,没有足够的资源部署运行完整的Kubernetes。其他问题还有:很多边缘设备基于ARM架构,但大部分Kubernetes发行版不支持ARM架构;边缘设备所处环境复杂,无法保证稳定可靠的网络连接,而Kubernetes不支持离线运行,等等。为了解决包含但不限于以上Kubernetes在边缘计算场景下的挑战,更好地将Kubernetes从云端延伸到边缘,业内已经诞生了多个基于原生Kubernetes优化的开源项目,比如华为开源的KubeEdge、阿里开源的OpenYurt、腾讯开源的SuperEdge、Rancher开源的K3s等,并且这四个项目都已经被云原生计算基金会(下文简称CNCF)接收。
而传统容器方案比如Docker,问题与Kubernetes类似,它还是一个相对重的容器运行时,镜像大小很容易就达到一两百MB以上,对于资源不足的硬件——边缘场景有不少内存和磁盘空间小于1GB的微型设备,Docker也不是一个理想的选择。
边缘计算不仅需要更轻量的Kubernetes,也需要更轻量、更快的容器方案,WebAssembly就是近几年出现的一个新选择。
2021年,云原生社区对WebAssembly的兴趣愈发浓厚,WebAssembly在云原生方向也十分活跃。到目前为止,CNCF已经正式接收了至少三个WebAssembly项目,包括:WasmEdge Runtime,一个云原生WebAssembly runtime;wasmCloud,一个WebAssembly应用程序框架;Krustlet,一个在Kubernetes pods中运行WebAssembly程序的工具。其中,WasmEdge和Kruslet通过两种不同的方式,做到了让Kubernetes集群中的WebAssembly工作负载可以与传统容器(例如containerd、Docker和CRI-O)并列运行,用户可以使用与管理Docker应用程序完全相同的工具来管理WebAssembly应用程序。
而说到WebAssembly最初与Docker、云原生产生关联,就不得不提Docker联合创始人Solomon Hykes在2019年3月份发布的一条推文。他在推文中表示:如果WASM(WebAssembly)和WASI(WebAssembly System Interface, WASM系统接口)在2008年就已经存在,那就没有必要创建Docker了。
这条推文在社区里引起了很大的反响,有赞同者,但更多的是质疑:WebAssembly这个发源于浏览器的东西,怎么突然就能在服务端取代Docker了呢?随后Solomon又发布了一条推文解释道:WebAssembly不会取代Docker,但是可以想象未来WebAssembly应用容器将与Linux容器、Windows容器在Docker中并列运行。如今,Solomon说的未来已经成为现实,只不过他原话中的Docker替换成Kubernetes更准确。
Crun是Kubernetes社区里最流行的容器运行与管理工具,由红帽软件发起,一开始只支持基于Linux的应用容器。但最近crun项目已经正式支持WasmEdge,能同时运行与管理WasmEdge容器镜像与Linux容器镜像。通过crun的底层支持,目前WebAssembly已经融入到了整个Kubernetes生态中,开发者可以使用Kubernetes、Containerd、CRIO 、Docker Hub来管理WebAssembly镜像。
那么,WebAssembly是如何从前端走向后端的?WasmEdge在其中扮演什么样的角色?未来在庞大的云原生生态中,WebAssembly又会占据什么样的位置?InfoQ近日有幸专访了WasmEdge项目创始人Michael Yuan,请他跟我们聊聊他对于WebAssembly的思考,以及WasmEdge的发展历程和定位。
WebAssembly从浏览器走向云原生
Michael有一个虽然可能引发争论但很有意思的理论,他认为,后端的技术每隔十年左右总要重新发明一次轮子。1999-2000年Java给后端带来了革命性的变化,十年后主角换成了JavaScript,原本JavaScript一直是前端语言,但自Node.js诞生后越来越多人也在后端使用JavaScript了。这背后的逻辑在于,开发者需要一个轻量级且容易理解的技术,但后端类软件每发展到一定阶段之后都会变得相当复杂,这个时候就会有开发者想重造一个复杂度没那么高的新轮子出来,每十年左右就会有一个这样的周期。2019年正好是一个新十年周期的开始,而WebAssembly就是Michael认为的这一个十年周期的新轮子,在他看来,WebAssembly也会从前端转移到后端然后把后端革命掉。
WebAssembly发源于浏览器端,最初主要设计来改善JavaScript的Native性能和代码执行效率。2019年12月5日,WebAssembly经过万维网联盟(W3C)推荐,与HTML、CSS和JavaScript一起,成为了Web的第四种语言。
关于WebAssembly技术演变过程,可查阅笔者早前策划的文章:
《WebAssembly如何演进成为“浏览器第二编程语言”?》
2021年7月,计算机协会编程语言特别兴趣小组将其享有盛誉的编程语言软件奖(Programming Language Software Award)颁给了WebAssembly,高度肯定了WebAssembly作为“自JavaScript以来第一种在Web浏览器中广泛采用的新语言”的成就。
不过Michael认为WebAssembly更大的市场在后端。虽然WebAssembly在浏览器里确实发挥了重要作用,但没有达到“必要”的程度,“有了最好,但没有也能用”。WebAssembly在前端完成的最重要也最有意义的一件事情,是在Google、Apple、Mozilla、微软这样的大厂和W3C这样的组织联合推动下,实现了很好的标准化,这是后来的技术很难去跟WebAssembly竞争的地方。也正因为已经通过浏览器端做好了标准化,WebAssembly才有可能从前端走向后端,才可能在后端做更多的事情。
Michael认为现在WebAssembly想要解决的问题,跟它刚诞生时想要解决的问题是一致的。这个核心问题就是要在一个大型应用程序里,给开发者提供一个可以写扩展的机会。一开始是在浏览器里面可以写应用,这就是对浏览器的一种扩展,只是原来只能用JavaScript写,现在有了一个新方法,可以用C++写、可以用Rust写,然后编译成WebAssembly去运行。
而今天的WebAssembly应用依然延续着这个想法。比如在边缘计算场景,或者在SaaS应用场景,都是有一个操作系统或应用程序,以前这个系统外部开发者是进不去的,如果要安全地运行外部开发者提交的代码,一个方法就是把代码装在Docker里运行。但是Docker又太重了,有了WebAssembly就可以打开一个口子,把任何一个软件都变成平台。这也是目前流行的一个大趋势,即“软件平台化”。
所以WebAssembly除了是一种编程语言,也被视作一个轻量级、快速、安全和多语言的函数“容器”,和Docker属于不同抽象层次。如何理解?
Michael表示容器相关技术可以分为三个抽象层次,其中虚拟机是在计算机层面的抽象;应用容器如Docker是在操作系统层面的抽象;WebAssembly则是在操作系统进程层面的抽象,它与JVM、V8都属于高级语言虚拟机,抽象程度最高。
在一般操作系统上面能干的事情在Docker里面都能干,但WebAssembly不是,它展现出来的是一个执行环境,只能执行编译好的字节码应用,不起操作系统的作用。所以它需要的工具链最复杂,但相应地也能带来性能的巨大提升。根据WasmEdge团队的测试结果,在冷启动上WebAssembly能做到比Docker快100倍;在执行时间上,WebAssembly比Docker快10%-50%。在Docker只作为执行环境的场景,即把程序写好了放到Docker里执行,执行完之后就关闭Docker,没有用户互动的情况,就是WebAssembly能够完全取代Docker的一个应用场景。而边缘计算里有大量这样的场景,这也是WasmEdge这个开源项目瞄定的目标场景。
借助WebAssembly这样的方案,就能在边缘场景跨平台地、轻量级地、快速地用云原生理念和云原生工具去部署应用程序。Michael表示,Kubernetes+Docker这套方法在边缘侧推进遇到了很大阻力,而WebAssembly是在正确时间出现的一个正确的解决方案。
WasmEdge的生态定位
最初决定要做一个WebAssembly方向的开源项目时,Michael和团队成员就想好了要做WebAssembly Runtime。当时市场上已有的WebAssembly Runtime都有两个问题。一个问题是都聚焦在浏览器场景,其中一个非常突出的例子是谷歌的V8。V8堪称工程奇迹,它是一个非常复杂、工程化程度非常高的软件,内置一个WebAssembly Runtime。但V8是专为谷歌浏览器优化的,它永远不可能把里面的WebAssembly单拆出来,而是必须要和JavaScript整套绑在一起,导致体积增加了几十倍。但浏览器需要JavaScript,后端不需要,后端需要的只是WebAssembly这块,但V8又不会把它单独拿出来。因此这类Runtime并不能很好地满足后端的使用需求。另一个问题是,其他的WebAssembly Runtime都是标准驱动的,跟随WebAssembly标准,在扩展方面做的不太好。
由于一开始团队还不能确定未来具体的应用场景,因此只是想做一个比较轻量级、易扩展、能够针对各种应用场景优化的开源WebAssembly Runtime。最初在给项目取名字这件事上也比较随意,直接沿用了创业公司的名字Second State,将开源项目命名为Second State VM,即SSVM。直到今年项目被CNCF纳入托管之前,由于CNCF要求开源项目的名字里不能有公司的商标,团队才开始考虑给项目换个名字。这时候团队对于这个项目的定位已经有了更清晰的规划,就是要将它用在应该使用Docker而Docker用不起来的地方,即把云原生这套理念和工具应用到边缘计算场景,这也是WasmEdge这个名字的由来。
如今业界已经围绕WebAssembly构建起了一个非常庞大的生态,Runtime可以说是整个生态中最底层的基础设施(下图是以WasmEdge为例描绘的WebAssembly生态图)。其中最有代表性的项目包括WasmEdge、V8、Wasmtime、WAMR等,不同Runtime各有各的应用场景和优化点。
Runtime提供了一个运行代码的地方,但如果每行代码都要从头写的话,对于开发者来说太麻烦了,所以开发者一般会使用框架。在Runtime之上还会有运行这些框架的应用服务器,这样的应用服务器在Java非常常见,比如WildFly(Jboss)、ColdFusion、Apache Tomcat、Apache TomEES等等,JavaScript也有Node.js与Deno两个应用服务器。WebAssembly现在已经有了wasmCloud与Suborbital两家创业公司,未来势必将涌现出更多应用服务器。
Runtime之下则是各种各样的操作系统和硬件架构,每一个WebAssembly Runtime都会支持一些自己认为比较重要的硬件和操作系统的组合。Runtime的东西向则是编译器和工具链,因为WebAssembly是字节码,就需要上游生态的支持,比如要将Rust编译成WebAssembly,就需要Rust编译器的支持。由于标准化做得好,目前很多编译器项目和编程语言的编译器针对WebAssembly的编译工具链都已经有了很好的支持。
对于当前的WebAssembly生态,还有一个很多人会好奇的问题:我们需要这么多Runtime吗?
Michael表示,现在还是需要的,因为还处在一个百花齐放的阶段,最后哪个Runtime能赢还不一定。他认为,从长期来看,最终Runtime应该会收敛为2-3个,从分布式集群的运维角度考虑,对于很多应用场景,特别是像区块链这样的场景,还是需要有多个Runtime的。
“其实现在市场已经收敛得差不多了,能够数得上号的Runtime基本也就四个:WasmEdge、Wasmtime、Wasmer和WAMR(WebAssembly Micro Runtime)。我觉得肯定还会继续淘汰,直到剩下最后的2-3个。”
当然还有一个可能性,就是未来所有Runtime都把功能做的差不多,大家都趋于标准化了。不过Michael表示,虽然有很多标准化的扩展,但不是每个Runtime都会选择去做,因为大家有不同的侧重点。还是以V8为例,现在很多在后端做的扩展,V8就不想做,因为这些在浏览器场景没有意义,做了这些除了增加潜在Bug以外,没有什么其他好处。
WasmEdge目前的重点是推动WebAssembly更快地整合到后端生态里面,进而往云原生和边缘计算方向走得更远、更快。前不久,团队与FutureWei合作为seL4和WasmEdge构建了一个WebAssembly管理代理,使WebAssembly字节码应用程序能在seL4 RTOS上简单地被部署和执行,这样一来在如自动驾驶汽车、无人机这样的边缘设备上也可以方便地运行应用程序容器。
此外,如本文开头所述,crun目前已经合并了WasmEdge的贡献,在读取容器镜像时能够自动检测它到底是用于WasmEdge还是containerd/Docker,然后启动和管理相应的runtime/容器,这样一来WebAssembly就能够无缝融入现有的K8s生态。而且开发者对此是无感知的,开发者用WebAssembly编写的应用程序编译后推到Docker Hub里面,就能用K8s生态中的工具直接管理了。
这是WasmEdge向边缘云原生走出的第一步,接下来团队会在边缘场景寻找更多用户案例,在得到充分验证之后,再考虑把WebAssembly移到数据中心来取代现有的基础设施的可能性。
取代Docker的可能性
两年前,WebAssembly以超乎预料的发展速度闯入大家的视线,一度被视为Web新技术浪潮的主角,当时很多人认为2020年会是一个WebAssembly应用百花齐放的年份。但2020年一场突如其来的疫情,让WebAssembly在很多方面的发展都放慢了脚步,不过社区并没有停下对新方向的探索和尝试。2021年,WebAssembly迎来了Web浏览器之外的爆炸性增长,尤其是在服务器端和云原生环境。
Michael认为,当前WebAssembly正处在一个类似Java在2001-2002年的阶段。后端应用刚刚开始,虽然很多人还是会觉得这个东西可以放到后端有些奇怪,但认真研究之后也能认可这个思路是make sense的。大家对于WebAssembly的兴趣也非常浓厚,即使不一定有需求,也有很强烈的想法要试试看有什么办法可以把WebAssembly用起来。Michael觉得这是一个非常有意思的阶段,“生态早期就是这样,Rust语言一开始也是一样。就是有事没事,以前用C++写的,现在用Rust重写。社区对这个东西有兴趣,然后大家都在找这个东西能有什么用。”
在他看来,这是一个行业发展的前奏。早期开发者可能不知道自己的应用场景是什么,但他就是要用这个技术。如果行业没有这个过程的话,就不会有人去推动技术向前走,技术其实是起不来的。这也是他看好WebAssembly发展的原因之一,但他同时也坦言,WebAssembly要真正做到应用的爆发、甚至能够挣到钱,还需要一段时间。“就像在2001-2002年之后又过了几年,才开始有围绕Java的项目赚到钱。”
据Michael介绍,自从加入CNCF之后,WasmEdge项目的社区活跃度有了很明显的提升。相较于在GitHub上有多少颗Star,团队更看重有多少外部开发者在参与开源项目的贡献和讨论。目前WasmEdge社区中已经有上百个Second State公司以外的开发者给项目提交Issue,贡献代码的开发者也有数十人。这其中既有来自华为、红帽、微软、蚂蚁集团等大厂的开发者,也有来自如YOMO这样的创业公司的开发者。
此外,在社区层面的合作上,现在也已经有很多基于Kubernetes的产品与WasmEdge展开合作,比如Linkerd、KubeEdge、SuperEdge、OpenYurt等。同样是以将云原生从数据中心延伸到边缘端为目标,KubeEdge、SuperEdge、OpenYurt与WasmEdge之间其实能形成很好的互补,如果说KubeEdge+Docker是轻量级+重量级的解决方案,那么KubeEdge+WasmEdge就是轻量级+轻量级的解决方案。
在技术演进上,WasmEdge不是一个标准驱动的项目,这跟同为WebAssembly Runtime类型的Wasmtime有很大的不同。WasmEdge更多是一个由应用场景驱动的项目,即需求来自于社区伙伴在使用过程中遇到的问题,由社区来指导项目的技术研发方向,因此对于社区交流和互动也会更加看重。
对于WebAssembly在新一年的发展,Michael做了一个相对乐观的预测。在他看来,WebAssembly将会在边缘端得到广泛应用,今天在边缘很多想用Docker但又用不了的场景,会被WebAssembly给吃掉,尤其是在KubeEdge这样的框架的加持下。“在边缘端取得成功之后,它就会像农村包围城市,重新进到数据中心里面去。”
对于WasmEdge,Michael非常希望它能够使最后成功的2个Runtime中的一个。“说实话,我觉得很大概率最后会是Wasmtime和我们。两个项目各自聚焦不同的方向,Wastime聚焦于Fastly那套和标准化,我们聚焦于满足边缘计算和边缘设备的需求。”他补充表示,WasmEdge现在是CNCF的项目,而不是Second State的项目,Second State只是为项目提供了一些开发者。他希望,更多对WebAssembly感兴趣的人能够聚合到WasmEdge项目里来,大家一起把这个项目建设好,最终推动WebAssembly生态更好的发展,这也是团队决定将项目捐赠给CNCF的初衷和期望。“我们第一是希望WebAssembly社区能做好,社区好了之后,才能够把WasmEdge做大,WasmEdge做大,我们才能够有前途,这家公司才会有前途。”
采访嘉宾介绍:
Michael Yuan,毕业于德克萨斯大学奥斯汀分校,获得博士学位,在开发和商业化开源软件方面拥有丰富的经验。Michael是JBoss的早期员工,被Red Hat收购之后,作为产品经理见证了世界上第一个成功的开源商业模式。Michael著有5本国际知名出版社出版的技术书籍。2019年Michael发起了WasmEdge项目,提供下一代云原生和边缘计算的执行环境。
WasmEdge项目地址:https://github.com/WasmEdge/WasmEdge