在kubernetes上运行WASM负载

WASM一般用在前端业务中,但目前有扩展到后端服务的趋势。本文使用Krustlet 将WASM服务部署到kubernetes。

简介

Krustlet 是一个可以在kubernetes本地运行WebAssembly负载的工具。Krustlet作为kubernetes集群中的节点。当用户使用特定node tolerations来调度Pod时,kubernetes API会将该负载调度到一个Krustlet节点,Krustlet会拉取并运行模块。

为了在Krustlet 节点上运行一个应用,首先必须将该应用编译为WebAssembly 格式,并推送到镜像仓库中。

准备

首先使用kind安装一个kubernetes集群(minikube要求使用virtualBox驱动)。

安装Krustlet

安装二进制文件

首先从官网下载并安装Krustlet,拷贝到一个系统可识别的路径即可(如/usr/local/bin)

生成bootstrap文件

Krustlet和kubelet的初始化流程类似,执行如下命令生成Krustlet的bootstrap.conf文件,默认路径为/root/.krustlet/config。

$ bash <(curl https://raw.githubusercontent.com/deislabs/krustlet/master/docs/howto/assets/bootstrap.sh)

运行Krustlet

找到kind使用的默认网关地址:

# docker network ls
NETWORK ID NAME DRIVER SCOPE
...
b48010373347 kind bridge local # docker network inspect b48010373347|grep "Gateway"
"Gateway": "172.18.0.1"

运行Krustlet:

$ export KUBECONFIG=~/.krustlet/config/kubeconfig
$ krustlet-wasi --node-ip 172.18.0.1 --bootstrap-file=/root/.krustlet/config/bootstrap.conf

运行界面如下,提示需要审批CSR:

# krustlet-wasi --node-ip 172.18.0.1 --bootstrap-file=~/.krustlet/config/bootstrap.conf
BOOTSTRAP: TLS certificate requires manual approval. Run kubectl certificate approve ubuntu-tls

审批CSR

$ kubectl certificate approve <hostname>-tls

校验

运行kubectl get nodes -o wide,可以看到新增了一个节点ubuntu,在该节点上可以运行WebAssembly负载:

# kubectl get node -owide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP
kind-control-plane Ready master 16m v1.19.1 172.18.0.2 <none>
ubuntu Ready <none> 8m37s 0.7.0 172.18.0.1 <none>

部署应用

下面安装官方的一个例子/demos/wasi/simpleserver/。运行如下命令即可:

# kubectl apply -f simpleserver.yaml

该pod会启动一个伪服务,代码如下:

use std::thread::sleep;
use std::time::Duration; fn main() {
loop {
println!("Hello, World!");
sleep(Duration::from_secs(5));
}
}

需要注意的是,在k8s.yaml中镜像字段为webassembly.azurecr.io/simpleserver:v1.0.0,但它并不是一个标准的容器镜像,而是WASM的module,默认会放到/root/.krustlet/.oci/modules目录下。在/root/.krustlet/.oci/modules/webassembly.azurecr.io/simpleserver/v1.0.0目录下查看拉取到的module

# ll
-rw-r--r-- 1 root root 71 May 6 22:34 digest.txt
-rw-r--r-- 1 root root 1998989 May 6 22:34 module.wasm

可以看到module.wasm的大小只有约2M,是一个支持跨平台运行的二进制文件,由此可以看出WASM和容器的区别:容器是需要基础镜像的,而WASM则不需要,它是一个可以跨平台运行的二进制文件,且需要特定的runtime工具运行。

# file module.wasm
module.wasm: WebAssembly (wasm) binary module version 0x1 (MVP)

可以使用wasmtime运行.wasm文件,wasmtime的下载方式如下:

curl https://wasmtime.dev/install.sh -sSf | bash

运行如下:

# wasmtime module.wasm
Hello, World!
Hello, World!
Hello, World!
...

WASM POD分析

查看该Pod,可以看到它就是一个正常运行的pod

# kubectl get pod
NAME READY STATUS RESTARTS AGE
simpleserver 1/1 Running 0 7m59s

运行kubectl describe pod simpleserver查看该pod信息

apiVersion: v1
kind: Pod
metadata:
name: simpleserver
labels:
app: simpleserver
spec:
containers:
- image: webassembly.azurecr.io/simpleserver:v1.0.0
imagePullPolicy: Always
name: simpleserver
tolerations:
- key: "node.kubernetes.io/network-unavailable"
operator: "Exists"
effect: "NoSchedule"
- key: "kubernetes.io/arch"
operator: "Equal"
value: "wasm32-wasi"
effect: "NoExecute"
- key: "kubernetes.io/arch"
operator: "Equal"
value: "wasm32-wasi"
effect: "NoSchedule"

源代码编译运行

编译

由于上例的代码是rust编写的,因此需要安装rust套件:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

在rust工具链中添加wasm:

$ rustup target add wasm32-wasi

生成可执行文件:

$ cargo build --target wasm32-wasi --release

推送module

由于生成的二进制并不是标准的镜像,因此无法直接推送到OCI仓库中,可以使用wasm-to-oci将module推送到OCI 仓库。

但需要注意的是,并不是所有的镜像仓库都支持推送WASM module,目前支持的镜像仓库为:

PS: 我使用了harbor镜像库,但无论使用http(报token无法解析)还是https(ca issuer无法识别),krustlet-wasi都无法成功拉取镜像。因此,建议有条件的话使用Azure或Google的镜像仓库

参考这篇文章搭建harbor镜像仓库(使用https方式)。搭建成功后,登录仓库,并执行如下命令,将WASM module推送到仓库中:

# wasm-to-oci push simpleserver.wasm registry.harbor.com/library/wasm-hello-world:v1 --use-http

在harbor仓库中可以看到刚上传的module。

运行自己的module

将k8s.yml中的image修改为自己的module地址:

image: registry.harbor.com/library/simpleserver:v1

总结

WASM本身支持多种语言,因此可以方便地将市面上已有的服务转换为WASM格式。后续WebAssemble有可能成为一种新的容器类型,类似Linux容器或Windows容器。

WASM由WASM虚拟机实现隔离性,但目前的隔离程度有限(如CPU、mem、network、共享存储等),且WASM虚拟机实现各异。这里给出了一系列WebAssembly Runtimes。

可以参考一下这篇文章Using WebAssembly and Kubernetes in Combination,里面详细讲解了WASM的现状。WASM目前还处于早期,WASI标准后续也需要进行迭代更新。但由于其本身具有的轻量级以及可移植的优点,相信前途会一片光明。

PS:对服务端的WASM支持最多最好的语言是RUST,是否是时候捡起来了?

在kubernetes上运行WASM负载的更多相关文章

  1. 「在 Kubernetes 上运行 Pgpool-Il」实现 PostgreSQL 查询(读)负载均衡和连接池

    介绍如何在 Kubernetes 上运行 Pgpool-II 实现 PostgreSQL 读查询负载均衡和连接池. 介绍 因为 PostgreSQL 是一个有状态的应用程序,并且管理 PostgreS ...

  2. 在Kubernetes上运行SAP UI5应用(下): 一个例子体会Kubernetes内容器的高可用性和弹性伸缩

    上一篇文章 在Kubernetes上运行SAP UI5应用(上),我介绍了如何在Docker里运行一个简单的SAP UI5应用,并且已经成功地将一个包含了这个UI5应用的docker镜像上传到Dock ...

  3. 在Docker和Kubernetes上运行MongoDB微服务

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟.容器是完全使用沙箱机制,相互之间不会有任何接 ...

  4. 在Kubernetes上运行SAP UI5应用(上)

    2018年只剩最后30天了.Jerry在2017年的最后一天,曾经立下一个目标:这个微信公众号在2018年保证至少每周发布一篇SAP原创技术文章. 从Jerry在后台统计的2018全年文章数量来看,这 ...

  5. 在 Kubernetes 上运行高可用的 Kafka 集群

    转载自:https://www.qikqiak.com/post/deploy-kafka-ha-on-k8s/ Apache Kafka 是目前最流行的分布式消息发布订阅系统,虽然 Kafka 非常 ...

  6. 在Kubernetes上运行有状态应用:从StatefulSet到Operator

    一开始Kubernetes只是被设计用来运行无状态应用,直到在1.5版本中才添加了StatefulSet控制器用于支持有状态应用,但它直到1.9版本才正式可用.本文将介绍有状态和无状态应用,一个通过K ...

  7. 实例演示:如何在Kubernetes上大规模运行CI/CD

    本周四晚上8:30,第二期k3s在线培训如约开播!本期课程将介绍k3s的核心架构,如高可用架构以及containerd.一起来进阶探索k3s吧! 报名及观看链接:http://z-mz.cn/PmwZ ...

  8. 试试将.NET7编译为WASM并在Docker上运行

    之前有听到说Docker支持Wasmtime了,刚好.NET7也支持WASM,就带大家来了解一下这个东西,顺便试试它怎么样. 因为WASM(WebAssembly) 一开始是一个给浏览器的技术,比起J ...

  9. 高射炮打蚊子,杀鸡用绝世好剑:在SAP Kyma上运行UI5应用

    国人在表述"大材小用"这个场景时,总喜欢用一些实物来类比,比如:高射炮打蚊子. 英国QF 3.7英寸(94mm)高射炮,战斗全重超过9.3吨,全长近5米,最大射程约18公里,最大射 ...

随机推荐

  1. python学习总结篇(2)——函数

    如其他语言一样,除了基本知识外,另外一个重要的板块就是函数了,python中也有函数. 在python中,函数的定义方式为: def   函数名( ): 下面通过几个简单的例子,看看python中的函 ...

  2. SVN同步方式举例 ​​​​ FreeBSD

    FreeBSD base  默认安装了svnlite 不需要单独安装SVN 软件 svnlite co svn.freebsd.org/ports/head/ /usr/local/ports -r5 ...

  3. centos命令上传

    首先安装 lrzsz # yum -y install lrzsz 运行 rz 命令: 在弹出的窗口选择需要上传的文件,文件会被上传至对应的目录下 运行 sz file.name 在弹出的窗口选择保存 ...

  4. 自己整理的acm模板

    第一次上传: 链接:点我下载 大部分常用的模板都弄了,剩下的坑以后再补... 第二次上传: 链接:点我下载 更新内容:新增ST表.分块 第三次上传: 链接:点我下载 更新内容:新增AC自动机,修改权值 ...

  5. Codeforces 976C Nested Segments

    题面: 传送门 C. Nested Segments Input file: standard input Output file: standard output Time limit: 2 secon ...

  6. WM_CLOSE WM_QUIT WM_DESTROY 三者的区别

    一 个窗口或者应用程序应该被关闭时发出WM_CLOSE消息,当接收到WM_CLOSE消息时,如果你愿意,向用户提出是否真的退出.你知道让用户作确认或 有错误出现或有什么应该注意的事情发生的时候,往往弹 ...

  7. 使用 Velero 跨云平台迁移集群资源到 TKE

    概述 Velero 是一个非常强大的开源工具,可以安全地备份和还原,执行灾难恢复以及迁移Kubernetes群集资源和持久卷,可以在 TKE 平台上使用 Velero 备份.还原和迁移集群资源,关于如 ...

  8. 什么是事务?事务的四个特性(ACID)?并发事务带来哪些问题?事务隔离级别都有哪些?事务的传播特性

    什么是事务? 事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消.也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做. 事物的四个 ...

  9. K8S单集群桌面安装笔记【k8s-for-docker-desktop】

    一.K8S集群基本的拓扑结构 二.下载 k8s-for-docker-desktop k8s桌面单集群安装,基本上选择 k8s-for-docker-desktop或者minikube两类,本文采用前 ...

  10. 第一次OOP作业-Blog总结

    前言 第一次作业一共八道题,此次作业也是这三次作业中最接近面向过程程序设计的题目集,整体难度偏低,总耗时1.5h,主要的知识点在熟悉Java的语法上,整体题目的逻辑非常清晰简单,但最后一个判断三角形类 ...